Home > Enterprise >  not iterate until condition is met
not iterate until condition is met

Time:09-23

My mind is about to break trying to figure out this.

I'm trying to automate adding some machines to a list from the google chrome console, since the website is not mine and i do not have access to the code.

enter image description here

I have a big list of machine that i need to add to the right column, i can't import it so that's why i'm trying to automate the process.

This is my code:

// input box
var search = document.getElementById(
  "CustomControl_ml_ms_m_si_m_tic_pc_xAssignedResources_m_computerSelector_WrappedSelector_ml_ms_m_si_m_tic_pc_xAssignedResources_m_computerSelector_WrappedSelector_mainGrid_ctl00_SearchBox"
);
// add to list btn
const addToList = document.querySelector(".scbMiddleCell input:nth-child(2)");
// first item on the left column
const primeraCelda = document.querySelector(".scgc");

// change the value of the input box
search.value = "XXX-MXXXX";

// create a keyup event
var ev = document.createEvent("Event");
ev.initEvent("keyup");
ev.which = ev.keyCode = 13;
// run the event, this way the ajax function kicks in and i'm left with only one item in the left column
search.dispatchEvent(ev);

setTimeout(() => {
// simulate the left item row selection
  primeraCelda.click();
}, 1000);
setTimeout(() => {
// click on the button to add the item to the right column
  addToList.click();
}, 1500);

Now this works only when i'm using a single value, if i create and array with values, and a foreach loop, it directly iterates through all the items in the array and only the last item gets added to the right column.

I can't figure out how to NOT iterate until the item is added to the right column.

CodePudding user response:

It took me a whole lot of searching, but i was finally able to find a solution using promises, promisfiying setTimeout.

I found the solution on this thread: JavaScript ES6 promise for loop

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));


for (let i = 0, p = Promise.resolve(); i < myArray.length; i  ) {
  const element = myArray[i];
  const celdaClick = () => primeraCelda.click();
  const addtoListClick = () => addToList.click();

  p = p
    .then(() => delay(1000, (search.value = element)))
    .then(() => delay(1000, search.dispatchEvent(ev)))
    .then(() => console.log(i))
    .then(() => delay(1500, celdaClick()))
    .then(() => delay(1500, addtoListClick()));
}

CodePudding user response:

I am late to your post, why do you need async function? They look all like sync functions. Is there any reason behind this?

Why not just do like below?

for (const element of myArray) {
  search.value = element;
  search.dispatchEvent(ev);
  primeraCelda.click();
  addToList.click();
}

If you really need async, I guess the dispatchEvent is the part you need to wait, you can do like below:

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

(async function asyncRun() {
  for (const element of myArray) {
    search.value = element;
    search.dispatchEvent(ev);
    await delay(2000);
    primeraCelda.click();
    addToList.click();
  }
})();

However, it is not the best approach because after you dispatch the event and it may not return the data after 2000ms, it would be better to have some waitForSpecificItem function to handle it instead.

As you are looking for some automation process, you may have a look of puppeteer

  • Related