encore2097
encore2097

Reputation: 503

Javascript pause / wait ; synchronous execution

Goal: Automate data backup from a third party site.

Scenario:

The data is available on a web page as a series of elements. ex:

[Data A]

[Data B]

[Data ...]
  1. Click on a Data element.
  1. After a short delay, elements will be populated under the data element and a [Save] button will appear. ex:
+ [Data A]
   [ ] item 1
   [ ] item 2
   ...
   [ ] item N
   
   [Save]
  1. Select all items
  1. Click [Save] to download.

Repeat steps 1-4 to save each Data element for a complete backup.

In synchronous psuedo code this would be:

alerts [array]

for i in alerts
  click alerts[i].load
  check if data ready; ready when save button appears
  click select_all
  click save

How can this be done in Javascript?

Upvotes: 0

Views: 1209

Answers (2)

encore2097
encore2097

Reputation: 503

Got it done with a macro and Firefox console.

Solution that works:

  1. What is the JavaScript version of sleep()?
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}
    
async function backup() {
   var alerts = $('.alerts'); 
   var imax = alerts.length; 
    
   for (let i = 0; i < imax; i++) {
       alerts[i].click();
       await sleep(2000);

       $('.ui-select-all').click();
       await sleep(200);

       $('#save');
       await sleep(500);
   }
}

backup();

Solution that may work:

  1. javascript synchronous execution

JavaScript pausing execution of function to wait for user input

A recursive, callback version

If there's a succinct event based approach I'd prefer and accept that as the answer


Update: optimal solution: Event delegation allows an event listener to be attached to a dynamically created element, even if that element does not yet exist. The event listener can call an anonymous function after the sub element is created.

https://davidwalsh.name/event-delegate

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events

https://learn.jquery.com/events/event-delegation/

Attach event to dynamic elements in javascript

Upvotes: 0

mwilson
mwilson

Reputation: 12900

It's a little unclear on the flow of your steps and what you are wanting the output to be. However, I think what you're ultimately after is how to listen to an event, wait some time, then do another event.

Below is an example of using Promises to create a wait method.

  1. Click Alerts button
  2. Save button appears
  3. 5 second wait time is triggered
  4. After 5 seconds, you will see a console.log message

const btn = document.getElementById('alerts');
btn.addEventListener( 'click', async () => {
  createSaveElement();
  console.log('waiting 5 seconds');
  await wait(5);
  console.log('finished waiting 5 seconds');

});

function createSaveElement() {
  const container = document.getElementById('container');
  const saveBtn = document.createElement('button');
  saveBtn.innerText = 'Save';
  container.append(saveBtn);
}

async function wait(seconds) {
  return new Promise( (resolve, reject) => {
    setTimeout( () => {
      resolve();
    }, seconds * 1000);
  });
}
<button id="alerts">Alerts</button>
<div id="container"></div>

Upvotes: 1

Related Questions