While_v2 loop if value exists?

2 questions:

  1. is it possible to do a While Loop inside another While Loop with UI.Vision?
  2. I’m trying to implement a while loop to scrape a list of variable size. I.e. “keep on scraping this until {element} does not exist”, and I can’t get my script to run (I’m guessing it’s a syntax issue) - what am I doing wrong?
{
  "Name": "seek.com.au pagination",
  "CreationDate": "2022-8-15",
  "Commands": [
    {
      "Command": "store",
      "Target": "1",
      "Value": "i",
      "Description": ""
    },
    {
      "Command": "store",
      "Target": "//*[@id=\"app\"]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[2]/div[i]/article/div[2]/a",
      "Value": "myDescription",
      "Description": ""
    },
    {
      "Command": "while_v2",
      "Target": "${myDescription} == true",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "echo",
      "Target": "i=${i}",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "executeScript_Sandbox",
      "Target": "return Number (${i}) + 1;",
      "Value": "i",
      "Description": ""
    },
    {
      "Command": "end",
      "Target": "",
      "Value": "",
      "Description": ""
    }
  ]
}

In this case, @id=\"app\"]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[2]/div[i]/article/div[2]/a is the xpath, and “div[i]” supposed to increase by 1 for i each time.

Yes! Nested loops are supported.

I guess the issue is here, this looks wrong. Check a description if it is trueß

“Target”: “${myDescription} == true”,

I’m unsure what to change it to though - how do I do a conditional statement for if a value exists or not?

I tried !statusok but since there’s 2 nested while statements (going to the next page + going down the list) it didn’t work.

Thanks!

Remove the “==true” bit, ${myDescription} will be coerced into true in a Boolean context, and that’s one way you can check if a variable exists. That said, I don’t think storing the xpath as myDescription is doing what you’d like it to here, I think you’re literally storing “@id=“app”]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[2]/div[i]/article/div[2]/a” as the value of the myDescription variable, and not actually doing anything webpage related.

I’d use a verifyelementpresent with the xpath immediately before the while command and again at the end of the while loop (right before the end command), and make the while loop condition ${!statusOK}. You may need to set !errorignore to true before the verifyelement part, I can’t remember if verify commands stop the macro when the element doesn’t exist

I’m not exactly sure what you mean. I used verifyelementpresent, but because there’s two nested while statements, the inner verifyelementpresent affects the other verifyelementpresent. I tried adding another verifyelement in between them, but it doesn’t seem to work:

{
  "Name": "pagination test",
  "CreationDate": "2022-8-18",
  "Commands": [
    {
      "Command": "store",
      "Target": "4",
      "Value": "q",
      "Description": ""
    },
    {
      "Command": "while_v2",
      "Target": "${!statusOK} == true",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "XClick",
      "Target": "//*[@id=\"app\"]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[3]/div[3]/nav/ul/li[${q}]",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "executeScript_Sandbox",
      "Target": "return Number (${q}) + 1",
      "Value": "q",
      "Description": ""
    },
    {
      "Command": "comment",
      "Target": "START LIST (not page) LOOP",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "store",
      "Target": "1",
      "Value": "i",
      "Description": ""
    },
    {
      "Command": "while_v2",
      "Target": "${!statusok} == true",
      "Value": "",
      "Description": "list of company names"
    },
    {
      "Command": "storeText",
      "Target": "//*[@id=\"app\"]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[2]/div[${i}]/article/div[3]/div[1]/div/div[1]/div/div[1]/div/div/div[2]/span/a",
      "Value": "!csvline",
      "Description": ""
    },
    {
      "Command": "executeScript_Sandbox",
      "Target": "return Number (${i}) + 1",
      "Value": "i",
      "Description": ""
    },
    {
      "Command": "if_v2",
      "Target": "${!statusok} == true",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "csvSave",
      "Target": "aaa_companynames3",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "end",
      "Target": "",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "end",
      "Target": "",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "comment",
      "Target": "END LIST (not page) LOOP",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "verifyElementPresent",
      "Target": "//*[@id=\"app\"]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[3]/div[3]/nav/ul/li[${q}]",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "comment",
      "Target": "above to make status ok for big page loop",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "end",
      "Target": "",
      "Value": "",
      "Description": ""
    }
  ]
}```

You need to set !statusOK to true after the inner while loop since the outer while loop uses the same condition and !statusOK doesn’t reset itself, once it’s false it’ll remain that way until you change it. In general, I’d recommend setting !statusOK to true before every verify/assert/waitfor command so that it’s never accidentally executed with !statusOK as false to begin with.

Try this (note that I didn’t put a verifyelement in the inner loop because storetext will serve the same purpose there, otherwise you’d need one):

{
  "Name": "TEMPORARY-4",
  "CreationDate": "2022-8-19",
  "Commands": [
    {
      "Command": "store",
      "Target": "true",
      "Value": "!errorignore",
      "Description": ""
    },
    {
      "Command": "store",
      "Target": "4",
      "Value": "q",
      "Description": ""
    },
    {
      "Command": "store",
      "Target": "true",
      "Value": "!statusOK",
      "Description": ""
    },
    {
      "Command": "verifyElementPresent",
      "Target": "//*[@id=\"app\"]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[3]/div[3]/nav/ul/li[${q}]",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "while_v2",
      "Target": "${!statusOK}",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "XClick",
      "Target": "//*[@id=\"app\"]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[3]/div[3]/nav/ul/li[${q}]",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "executeScript_Sandbox",
      "Target": "return Number (${q}) + 1",
      "Value": "q",
      "Description": ""
    },
    {
      "Command": "comment",
      "Target": "START LIST (not page) LOOP",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "store",
      "Target": "1",
      "Value": "i",
      "Description": ""
    },
    {
      "Command": "store",
      "Target": "true",
      "Value": "!statusOK",
      "Description": ""
    },
    {
      "Command": "verifyElementPresent",
      "Target": "//*[@id=\"app\"]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[2]/div[${i}]/article/div[3]/div[1]/div/div[1]/div/div[1]/div/div/div[2]/span/a",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "while_v2",
      "Target": "${!statusOK}",
      "Value": "",
      "Description": "list of company names"
    },
    {
      "Command": "storeText",
      "Target": "//*[@id=\"app\"]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[2]/div[${i}]/article/div[3]/div[1]/div/div[1]/div/div[1]/div/div/div[2]/span/a",
      "Value": "!csvline",
      "Description": ""
    },
    {
      "Command": "if_v2",
      "Target": "${!statusOK}",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "csvSave",
      "Target": "aaa_companynames3",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "executeScript_Sandbox",
      "Target": "return Number (${i}) + 1",
      "Value": "i",
      "Description": ""
    },
    {
      "Command": "end",
      "Target": "",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "end",
      "Target": "",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "comment",
      "Target": "END LIST (not page) LOOP",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "store",
      "Target": "true",
      "Value": "!statusOK",
      "Description": ""
    },
    {
      "Command": "verifyElementPresent",
      "Target": "//*[@id=\"app\"]/div/div[4]/div/section/div[2]/div/div[2]/div[1]/div/div/div[3]/div[3]/nav/ul/li[${q}]",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "comment",
      "Target": "above to make status ok for big page loop",
      "Value": "",
      "Description": ""
    },
    {
      "Command": "end",
      "Target": "",
      "Value": "",
      "Description": ""
    }
  ]
}
1 Like

That works - thank you!!!