Selenium ElementNotFoundException when the element in a loop - selenium-webdriver

Am writing the selenium code for an element. It gives the error as ElementNotFoundException
I know the reason that the element was hidden or its style is none.
I Googled and I found the following solution:
((JavascriptExecutor) this.webdriver).executeScript("arguments[0].click();", elementToClick);
…but my element in a loop. For the first iteration it is successful but in the further iterations it is throwing the same exception.
Can anyone explain the arguments[0]?

Yes, in your example, "arguments[0]" = elementToClick . Also, I only use a JavascriptExecutor when I have no other options to click something, and that almost never happens. For example, I use JavascriptExecutor to do page-downs because Selenium doesn't have a feature that does that properly.
So, if the element you are seeking really does have a 'display=none' set on it, what you should do instead is use an ExpectedConditions.visibilityOfElementLocated condition with a WebDriverWait (or a FluentWait).
For all other cases of elements which are visible or not visible at times, use ExpectedConditions.presenceOfElementLocated.
Using the Wait classes with ExpectedConditions, you can use a while loop to ignore certain exceptions and do re-tries until the condition is satisfied.

Related

How to iterate over elements in selenium

Actually i want to read emails one by one in junk folder of "outlook:live" and mark emails "Not spam".
emails = WebDriverWait(driver, 5).until(EC.element_to_be_clickable((By.XPATH,"//div[#class = 'xoCOIP8PzdTVy0T6q_uG6']")))
This xpath matches 400 instances. I want to make a loop to select one email at a time like select first email, click on the div and perform action and then 2nd email and so on. I'm trying this
emails = WebDriverWait(driver,
5).until(EC.element_to_be_clickable((By.XPATH,"//div[#class =
'xoCOIP8PzdTVy0T6q_uG6']")))
for count in range(0,len(emails)):
(emails)[count+1].click()
Please help me know where im doing wrong. Thanks in advance
It appears that the function you're using to return the clickable elements is only returning a single element, so you'll have to use a different function, make a change in your logic, etc.
For instance, you could use Selenium's find_elements_by_xpath("//div[#class = 'xoCOIP8PzdTVy0T6q_uG6']") which will return a list of WebElement object(s) if the element(s) are found, or an empty list if the element(s) is not found. This will, of course, not take into consideration the possibility of the elements not being completely loaded on the page. In my experience, just slapping a time.sleep(10) after you open the page is "'good enough".
I recommend making sure your elements can be discovered and interacted with first to make sure this isn't all in vain, if you haven't already.
Another option is to add another function, something like a elements_to_be_clickable() function, to the Expected Conditions source code.
From the Expected Condition documentation, I've done some research and it looks like the element_to_be_clickable() function only returns a single element. Moreover, from the source code, said function mainly makes use of the visibility_of_element_located() function. I believe you could follow similar logic to the element_to_be_clickable() function, but instead use the visibility_of_all_elements_located() function, in order to return multiple WebElements (since visibiilty_of_all_elements_located() returns a list of WebElements).

isEnable() is not working in selenium webdriver for find the button is enabled or disabled?

i am trying the bellow code,but always return true value.
if(updatebuton_status=="true"){
Thread.sleep(timmer*3);
//click on the update button
//ieDriver.findElement(By.xpath("html/body/div[1]/div/div/div/div[3]/div/div[1]/div/div/table/tbody/tr/td/table/tbody/tr/td[3]/div/div/div[2]/div[3]/div/div/div/div[2]/div/div[2]/div[2]/div/div/div[3]/div[2]/div/div/div/div[3]/div/div/div/div/div/div[2]/div[1]/div/div/div/div/table[1]/tbody/tr/td/table/tbody/tr/td[3]/span/table/tbody/tr[2]/td[2]")).click();
ieDriver.findElement(By.xpath("/html/body/div[1]/div/div/div/div[3]/div/div[1]/div/div/table/tbody/tr/td/table/tbody/tr/td[3]/div/div/div[2]/div[3]/div/div/div/div[2]/div/div[2]/div[2]/div/div/div[3]/div[2]/div/div/div/div[3]/div/div/div/div/div/div[2]/div[1]/div/div/div/div/table[1]/tbody/tr/td/table/tbody/tr/td[1]/span/table/tbody/tr[2]/td[2]")).click();
}else{
Thread.sleep(timmer*3);
//click on the Add button
ieDriver.findElement(By.xpath("/html/body/div[1]/div/div/div/div[3]/div/div[1]/div/div/table/tbody/tr/td/table/tbody/tr/td[3]/div/div/div[2]/div[3]/div/div/div/div[2]/div/div[2]/div[2]/div/div/div[3]/div[2]/div/div/div/div[3]/div/div/div/div/div/div[2]/div[1]/div/div/div/div/table[1]/tbody/tr/td/table/tbody/tr/td[1]/span/table/tbody/tr[2]/td[2]")).click();
}
I think somewhere you are doing wrong as your xpath is too long recommended to use relative xpath. and if your element having id then use it directly
I don't know how you are checking that element is displayed
use following method to do same -
boolean check= driver.findElement(By.id("tVLQur-btn")).isEnabled();
if(check) // if `check` returns true then go in if condition
{
driver.findElement(By.id("tVLQur-btn")).click();
}
else
{
// DO SOME OTHER FUNCTIONALITY
}
Edited
If your button id is dynamic then use following xpath to find the element
//td[contains(.,'Update')]/../preceding-sibling::tr//button
like
boolean check= driver.findElement(By.xpath("//td[contains(.,'Update')]/../preceding-sibling::tr//button")).isEnabled();
It will find your update button and check weather it is enable or not
I believe at the very least if you break the line into two statements, one to located the element, and the next to check its enabled status, at least you'll know that the problem (most likely) lies in the element location, as it would return a nul to the web element and isEnabled would return a null pointer exception. There are always ways to use relatively short xpaths if no consistent ID is available. Check your browser for add-ins that include the word xpath, and you'll see there are a variety of xpath helpers out there. The inspect element option is the safest, at least in theory, but it's not always the best.

Breakable loop in Scratch?

How do you make a breakable loop in Scratch? I'm using Scratch 2.0 and can't find any good way to make a loop breakable, from inside of the loop itself.
Disclaimer:
There is no perfect way to do it. If you can possibly stand this true fact then feel free to continue.
There are a few different ways you could do it.
With repeat until
The first and most simple one follows this:
But this isn't technically part of the script - it's just repeating until some value returns true.
With a custom block (stop this script)
In order to do it inside of the script, you'll need to use a sneaky little trick with custom blocks.
Create a custom block called whatever you want - but probably along the lines of "breakable loop". Inside of it, create this script:
By using stop script we are breaking out of the script that is currently running - which, according to Scratch, is the custom block.
See the result! (as scratchblocks)
With broadcast and wait
You could also use a broadcast-and-wait method, very similar to above:
Though I highly suggest you don't use this method, as if any other sprites have breakable loops you'll need to rename each one, which can be tedious after using a lot of loops in a lot of sprites!
(Note this bug has been fixed in version 442 of the editor and such the following no longer applies.)
Help! My project is lagging a bunch now!
As #foi has noticed, if your code must be run inside of a frame you probably checked run without screen refresh. Unfortunately, due to a bug in the Scratch player, this causes the program to essentially break after the stop this script block has been activated. How can you handle this?
It follows the same principle you use when you use a run without screen refresh custom block inside of a forever loop - the loop doesn't use screen refresh while the inside does, allowing for instant animations whether or not one is using turbo mode.
Here's an example - the image is really too long to be embedded, so see it here instead.
You can make a variable inside or outside of the repeat and make your script like this:
repeat until [[my variable] = [e.g: 1]]
your code
your code
your code
your code
end of repeat until
For a "repeat until" block the simplest way would be to "or" your normal until condition with the break condition in the until.
By adding an incremeting loop counter variable in the loop you can use a "repeat until" to replicate the function of a "repeat n times" block
By using a "repeat until" block with only your break condition you get the equivalent of a "forever" block
If you need another script/ sprite to trigger the break then a public variable will let you break the loop from anywhere and let a single condition break loops for different sprites.
I'd post an image of the blocks but this is my first reply and the site won't let me!
good luck
You can use these few ways to do it...
conditional loop
stop this script
if then else, in the else section, put nothing
I would prefer to use the first method, as it requires less blocks and for the first method, you can still add in code that will be executed after the loop has stopped executing.
You can make it repeat x times or make it have a certain point where it stops, such as another variable changing.
Otherwise, I don't think there is a wat to do that.
Use the repeat until block. Then put in an equals block or whatever into the boolean part. Then inside that repeat until block, put a stop this script block.
Hope this helps :D

Selenium CSS selector by id AND multiple classes

Using selenium for the first time here, I was wondering why:
final WebElement justAnId = findElement(By.cssSelector("#someId"));
final WebElement whatIWant = justAnId.findElement(
By.cssSelector(".aClass.andAnother input[type=text]")
);
works, but not:
final WebElement whatIWant = findElement(By.cssSelector(
"div#someId.aClass.andAnother input[type=text]"
));
Although they seem equivalent to me I get:
org.openqa.selenium.NoSuchElementException: Unable to locate element:
{"method":"css selector","selector":"div#someId.aClass.andAnother input[type=text]"}
Is this intended behaviour or a bug in Selenium? I had a quick look in the bug tracker in Selenium but I didn't see anything about that. I wanted to ask here before raising an issue that doesn't need to be. Also as far as I understand it doesn't work in IE6 but who cares. I was using firefox for this run.
Actually the two are quite different selectors.
Here is your cssSelector:
div#someId.aClass.andAnother input[type=text]
But what you really wanted to write was:
div#someId .aClass.andAnother input[type=text]
notice the space between ID and class. you need that.
findElement() finds an element in the current context, which means your first snippet of code is really finding an element that matches .aClass.andAnother input[type=text], which is contained within #someId. The element with that ID may or may not contain the two classes; WebDriver doesn't assume you're referring to the same element; it just finds the input as long as its ancestors are #someId and .aClass.andAnother.
This is completely different from div#someId.aClass.andAnother input[type=text], which finds any input[type=text] within div#someId.aClass.andAnother only (i.e. it's a div that contains both the ID and the classes).

changing variables in loop in Jmeter

I have web request like this
Loop Controller(3)
moreSamples=true
startIndex=0
While Controller(${__javaScript(${moreSamples}==true)})
SOAP/XML-RPC Request(index=${startIndex})
Regular Expression Extractor(startIndex=newIndex,moreSamples=samples)
Now problem is I am not able to initialize moreSamples and startIndex in loop.
I tried two options:
Make moreSamples and startIndex as user defined variables. Now I am able to change their values using Regular Expression Extractor but not able to reinitialize them in outer loop using BeanShell PostProcessor like this:
vars.put("moreSamples","false")
vars.put("startIndex","0")
Make moreSamples and startIndex as User Parameters in preprocessor of of while loop but then I am not able to assign them values using Regular Expression Extractor.
Please suggest the mistakes or some new construct which can fit in.
Screenshot:
#bpsingh,
Can you do following things:
Add UserDefinedVariables on top of your Test Plan with two defined variables:
moreSamples, startIndex (like #ant suggested already)
Under the Download - PersistentSyncScope Sampler, you have two regular expression extractors in which I assume you want to extract some values and place it in these two variables from the above. Add BeanShellPostProcessor under the Download - PersistentSyncScope Sampler.
In BeanShellPostProcessor add following code:
vars.put("moreSamples","${REGEX_EXTRACT1}");
vars.put("startIndex","${REGEX_EXTRACT2}");
These two (moreSamples, startIndex) are global variables and changes on them should be visible outside of the loop.
Do you have to initialize them from the loop? How about adding those to User Defined Variables?
Or you can do it from your loop as well, the reason why it doesn't work for you is either the fact that you forgot to put the semi-colon ; after your expression(s) :
vars.put("moreSamples","false"); // ; <- was missing
vars.put("startIndex","0"); // ; <- was missing
I used BSF Sampler and it worked for me (don't forget to choose the language -> beanshell if you use this one). Here is my debug sampler (relevant part) :
START.HMS=101818
START.MS=1341821898080
START.YMD=20120709
TESTSTART.MS=1341822195274
moreSamples=false
startIndex=0
Update:
You need not to use both BSF Sampler and user defined variables. You can use either, and I see you have more user defined variables, no need for that. Have one of those at the start of your test. I'm still not clear what your problem is and what you're trying to achieve.
Actually problem here is I am using 2 loops and all answers don't take this properly into account.
Since pre/post processors are applied only to samplers not to loops there is no way to reinitialize the variables before while loop. Thus if I add initialize statements in preprocessor, loop run infinitely and if in postprocessor, it never executes. Only way to initialize is adding BSF sampler before while loop but that will spoil the reports as this sampler will also be recorded by listeners.
So only solution I found is run Download - PersistentSyncScope Sampler once and add BSF preprocessor with following scripts
vars.put("moreSamples","false");
vars.put("startIndex","0");
Now add while loop and add Download - PersistentSyncScope Sampler as its child.
That is the only solution till now. Thanks everyone to help me understand the problem.

Resources