How to count the number of options into a select?

Hello, I have to get the number of options elements into a select, and then clic on any option.

So I tried to count the number of options into a select on a webpage with ui.vision, but it returns 0.
i would like it returns the real number of options, here there is 4 options.

There is my html :

<select id="dog">
<option value="1">--select--</option>
<option value="2">Rottweiler</option>
<option value="3">Doberman</option>
<option value="4"> Poodle</option>
</select>

I don’t know in advance what value will be display into the options, it can change because it depending on other conditions.

I tried this Json sourcecode among others :

{
  "Command": "sourceSearch",
  "Target": "dog $*</option>",
  "Value": "nbLabelOption"
}

Does anyone have a solution or any idea please ?

Thanks in advanced,
Best regards

Post url please your question doesn’t explain well the problem you need to see the page to find a solution.

I can’t post url because it is private, sorry. I have made an example with a select element in my post.
I just would like to get the values into the options of the select, and get the number of those options.

This is the solution, simple and working

Simple use partial text with * and you solve the problem

Macro code

{
  "Name": "Select_Partial_Name",
  "CreationDate": "2020-8-26",
  "Commands": [
    {
      "Command": "bringBrowserToForeground",
      "Target": "",
      "Value": ""
    },
    {
      "Command": "open",
      "Target": "https://html.com/tags/select/",
      "Value": ""
    },
    {
      "Command": "waitForPageToLoad",
      "Target": "10000",
      "Value": ""
    },
    {
      "Command": "select",
      "Target": "xpath=//*[@id=\"post-289\"]/div/div[4]/select",
      "Value": "label=Lesser*"
    }
  ]
}

Thanks for your response,

For the id it is ok, the id of the select field is always fixed. But it is not the case for the option label, and I have to get all values of all option label to select them after that.

I’ve tried the * character in the label, but I have another problem to solve : if I write “Value”: “label=*” on the select command, the value selected is the first “–select–”, even if there is no selection.

I would like to make a loop to be able to select each value (except the first). That’s why I’ve thought to get the option label values before use them like something like this (example without loop) :

{
    "Command": "storeText"
    "Target": "//*[@id=\"dog\"]/div/div[4]/select"
    "Value": "myLabel"
}
{
    "Command": "Select",
    "Target": "id=dog",
    "Value": "label=${MYLABEL}"
}

Why you merge a part of xpath of my macro code with your code? What is the sense ?

You must detect a correct and good xpath in your page otherwise never working your macro.

Every page have custom xpath you can not use xpath of other macro code.

Check a good xpath for your select, after you can think next step.

Without seen yout page I can not find a xpath.

Without seeing the page it is likely that you will not solve your problem, it is very important when you have to automate being able to see the page to make test to find good xpath.

This is an example. I have no problem to get the xpath, it is not the question. I would to select randomly the select option after get all the element options.

In other words, I just try to get the labels of my select options in order to select one of the options randomly (except the first).

I have made this ui.vision code for the moment :

         {
          "Command": "executeScript",
          "Target": "document.getElementById(\"typeDocumentClient\").selectedIndex = Math.floor(Math.random() * (document.getElementById(\"typeDocumentClient\").options.lenght-1))+1;",
          "Value": ""
        }

But it doesn’t work, I have an error :

Error in executeScript code: Refused to evaluate a string as javaScript because 'unsafe-eval' is not an allowed source of script in the foloowing Content Security Policy directive: "script-src 'self' 'unsafe-inline'".

The code used for the moment is working but I can’t select a random select option for now.

Do anyone have another solution to select it randomly please ?

{
“Command”: “select”,
“Target”: “id=typeDocumentClient”,
“Value”: “label=00*”,
“Targets”: [
“id=typeDocumentClient”,
“name=typeDocumentClient.id”,
“xpath=//*[@id="typeDocumentClient"]”,
“xpath=//select[@id=‘typeDocumentClient’]”,
“xpath=//div[2]/select”,
“css=#typeDocumentClient”
]
}

The select option source :

-- Select -- 001 - Not informed 002 - Bird 003 - Butterfly 006 - Tiger 007 - Dog 008 - Cow

A very simple and working solution is use select with locaton index=n

n = number

And you randomize n with a random number is very fast way and working.

I think you can try with id=n too

Option locators provide different ways of specifying a select element (e.g., label=, value=, id=, index=). If no option locator prefix is provided, a match on the label will be attempted. If you use label= you can also use asterisk * to match only parts of the string. For example instead of label=RPA software you can use label=PA softwar

Read here

https://ui.vision/rpa/docs/selenium-ide/select

How I can do to use regex to count the option ? I tried but I can’t do this… It’s blocking now.
I can just get one by one the value inside each option but it is all.

{
“Command”: “sourceExtract”,
“Target”: “regex=<option.>(.)@3,1”,
“Value”: “myvar”
}

I don’t know how to use sourceSearch and regex to count some options.
And / or how to use the “n” random with select.

I am not a developper so… :slight_smile:

Hi

I do not use regex but I can create this command with a simple loop with select index=n and statusok

When statusok fails the option do not exist and you can know the number of option selected with success.

Resume:
Select index=1
Check statusok if true continue

Select index=2
Check statusok if true continue

Select index=3
Check statusok if false you stop loop

You know in your select there are 2 option (index=1 and index=2)

For every work exist multiple way, i search always simple and fast way.

Hello,

Thank you for your answer.

For the moment, I have made this code in ui.vision to init the index with “i” variable. Then I do a loop where I increment the “i” variable, and where I would to get an array of the options values.

This is the actual code (with executeScript command) :

{
“Name”: “test3”,
“CreationDate”: “2020-9-2”,
“Commands”: [
{
“Command”: “executeScript”,
“Target”: “i = 1; return i;”,
“Value”: “i”
},
{
“Command”: “echo”,
“Target”: “My first value is ${i}”,
“Value”: “”
},
{
“Command”: “while_v2”,
“Target”: “${i} < 10”,
“Value”: “”
},
{
“Command”: “executeScript”,
“Target”: “return (${i}) + 1”,
“Value”: “i”
},
{
“Command”: “echo”,
“Target”: “My new value is ${i}”,
“Value”: “”
},
{
“Command”: “end”,
“Target”: “”,
“Value”: “”
},
{
“Command”: “echo”,
“Target”: “The end”,
“Value”: “”
}
]
}

And then I would re-use the array with the option values to select randomly one of these values with select command.

The actual script is functional, but I have a problem on my own website : if I launch this script on it, there is an error for the executeScript command, because there is a security implemented for javascript commands and I cannot do anything to change this. The executeScript cannot be used because if it was, it would be possible to inject some code through it…

If I launch the code with executeScript command like written, I have this error :

Error in executeScript code: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'". ui.vision

So, I think I have to use another command than executeScript.

And so I have made this code with store command :

{
“Name”: “test3”,
“CreationDate”: “2020-9-2”,
“Commands”: [
{
“Command”: “store”,
“Target”: “1”,
“Value”: “i”
},
{
“Command”: “echo”,
“Target”: “My first value is ${i}”,
“Value”: “”
},
{
“Command”: “while_v2”,
“Target”: “${i} < 10”,
“Value”: “”
},
{
“Command”: “executeScript”,
“Target”: “return (${i}) + 1”,
“Value”: “i”
},
{
“Command”: “echo”,
“Target”: “My new value is ${i}”,
“Value”: “”
},
{
“Command”: “end”,
“Target”: “”,
“Value”: “”
},
{
“Command”: “echo”,
“Target”: “The end”,
“Value”: “”
}
]
}

This code is launched successfully but the valeur is a text, not an integer… So it is not incremented like I would… And I don’t know how to parse my string variable to an integer.

For the moment, the ${i] is incremented like that so : i=1, Loop 1 : i=11...

The ParseInt(${i}) doesn’t work or I don’t know how to use it correctly. Is it possible ?

Thanks in advanced

Solution found : I use executeScript_Sandbox command and it works ! Now I’m trying to get values then select randomly one of the array values and I’ll come back here :slight_smile: :crazy_face:

Other thing :
It is just too bad I cannot get the number of the option elements in a select… But I have an idea :
If I write a while with i < 30 for example, and if there is only 9 option elements into the select, the ui.vision macro return an error “cannot find option with ‘index=9’”.
So I could save the $i value like this. (I tried to use the Do ... repeatIf command instead of the While loop, but this method stop to the second option value and I don’t know why).
But if there is an error during playing macro, the macro is stopped and I neither can’t get the $i value outside the loop nor continue my test… :roll_eyes:

Hello again !

So, I can get the options values now and store them into an array, like this :

{
“Name”: “test3”,
“CreationDate”: “2020-9-2”,
“Commands”: [
{
“Command”: “executeScript_Sandbox”,
“Target”: “i=0; return i;”,
“Value”: “i”
},
{
“Command”: “echo”,
“Target”: “My first value is ${i}”,
“Value”: “”
},
{
“Command”: “executeScript_Sandbox”,
“Target”: “var myArrayOptions = ; return myArrayOptions”,
“Value”: “myArrayOptions”
},
{
“Command”: “echo”,
“Target”: “This is an array ${myArrayOptions}”,
“Value”: “”
},
{
“Command”: “while_v2”,
“Target”: “${i} < 9”,
“Value”: “”
},
{
“Command”: “click”,
“Target”: “id=titi”,
“Value”: “”,
“Targets”: [
“id=titi”,
“name=typeDocument”,
“xpath=//*[@id="titi"]”,
“xpath=//select[@id=‘titi’]”,
“xpath=//div[2]/div[4]/div/titi”,
“css=#titi”
]
},
{
“Command”: “select”,
“Target”: “id=titi”,
“Value”: “index=${i}”
},
{
“Command”: “storeValue”,
“Target”: “id=titi”,
“Value”: “currentOption”
},
{
“Command”: “echo”,
“Target”: “My current option selected is ${currentOption}”,
“Value”: “”
},
{
“Command”: “executeScript_Sandbox”,
“Target”: “myArrayOptions[${i}] = ${currentOption}; return myArrayOptions”,
“Value”: “myArrayOptions”
},
{
“Command”: “echo”,
“Target”: “My array has new values : ${myArrayOptions}”,
“Value”: “”
},
{
“Command”: “executeScript_Sandbox”,
“Target”: “return (${i}) + 1”,
“Value”: “i”
},
{
“Command”: “echo”,
“Target”: “Ma nouvelle valeur est ${i}”,
“Value”: “”
},
{
“Command”: “end”,
“Target”: “”,
“Value”: “”
},
{
“Command”: “echo”,
“Target”: “The end value is ${i}”,
“Value”: “”
}
]
}

But, I don’t understand why the array return ALL the options values at the first loop iteration, how is it possible ?! If I know that I should get them not in a loop I presume, and it will be awsome. And so resolve this discussion maybe (and then I “just” have to select one of the options randomly)…

Hello I do not understand your macro code how it works, I use another simple solution to know how many options are present in a select.

I prefer in a few lines of code to have a command that works well always and quickly.

I’m sorry but I can’t help you because I don’t understand your long and confusing macro code what it should do.

Hi,

Okay no matter, I will try to resolve things one by one here.

My actual problem is I can’t add some values into an array if I am in a while loop.

I declare the array like this :

{
“Command”: “executeScript_Sandbox”,
“Target”: “var myArrayOptions = ; return myArrayOptions;”,
“Value”: “myArrayOptions”
}

Then I have verified if it was possible to add some values in the array just after declaration, it is ok :

{
“Command”: “executeScript_Sandbox”,
“Target”: “var myArrayOptions = ; myArrayOptions[0] = ‘test’ ; return myArrayOptions;”,
“Value”: “myArrayOptions”
}

But if I do the exactly same thing into a loop, it doesn’t work, the array is empty…
My code ui.vision :

{
“Command”: “executeScript_Sandbox”,
“Target”: “var myArrayOptions = ; return myArrayOptions;”,
“Value”: “myArrayOptions”
},
{
“Command”: “while_v2”,
“Target”: “${i} < 9”,
“Value”: “”
},
{
“Command”: “executeScript_Sandbox”,
“Target”: " myArrayOptions[${i}] = ‘test’ ; return myArrayOptions;",
“Value”: “”
},
{
“Command”: “end”,
“Target”: “”,
“Value”: “”
}

→ the array is always empty or undefined, I have tried so many syntaxes… Do you know if there is some issues or other with using arrays in loop ?

Change the title of your post because I posted a working solution to count option in select but you want use your executeScript_Sandbox and your way

My solution count option in select well and working.

You want executeScript_Sandbox custom code change title please.

Hi
I agree to change title but I don’t know how to do…

I have find a working solution to select randomly a select option, here the final code :
A latest question : do you know how I can do to select randomly one of the values of my array except the first, or except one with some characters, for example if I don’t want to select the value “my little value” ?

{
  "Command": "storeText",
  "Target": "id=titi",
  "Value": "mySel"
},
{
  "Command": "executeScript_Sandbox",
  "Target": "return ${mySel}.replace(/(\\n|\\r)/gm,'###');",
  "Value": "set"
},
{
  "Command": "executeScript_Sandbox",
  "Target": "var myArr = []; myArr = ${set}.split('###'); return myArr;",
  "Value": "myArr"
},

{
“Command”: “executeScript_Sandbox”,
“Target”: “var randomElement = ${myArr}[Math.floor(Math.random()${myArr}.length)]; return randomElement;",
“Value”: “randomElement”
},
{
“Command”: “click”,
“Target”: “id=titi”,
“Value”: “”,
“Targets”: [
“id=titi”,
“name=titi.id”,
"xpath=//
[@id="titi"]”,
“xpath=//select[@id=‘titi’]”,
“xpath=//div[2]/select”,
“css=#titi”
]
},
{
“Command”: “select”,
“Target”: “id=titi”,
“Value”: “label=${randomElement}”,
“Targets”: [
“id=titi”,
“name=titi.id”,
“xpath=//*[@id="titi"]”,
“xpath=//select[@id=‘titi’]”,
“xpath=//div[2]/select”,
“css=#titi”
]
}

Thank you very much for your help.

Have a nice day !

The easy solution to skip some value in random value is an if command

If ${randomElement} == “BADWORD”

Repeat command to select a random value

BADWORD is the value you want to skip

Yes, I have found the solution in the meantime and I use :

{
“Command”: “do”,
“Target”: “”,
“Value”: “”
},
{
“Command”: “executeScript_Sandbox”,
“Target”: “var test = ${myArr}[Math.floor(Math.random()*${myArr}.length)]; return test;”,
“Value”: “randomElement”
},
{
“Command”: “repeatIf”,
“Target”: “${randomElement}==‘badvalue’”,
“Value”: “”
}

Thank you very much

1 Like