How can I avoid inconsistent behavior with Selenium StaleElementReferenceException (Python)? - python

I'm working on a bit of automation that basically opens YouTube, plays a particular video, then opens the "Stats for Nerds" dialog and grabs the info from it. This was working yesterday. Today, I added lines to set the video to 1080p, then go into full screen, and now it fails to work.
The following line works:
driver.find_element_by_id("movie_player").click()
While this set fails, throwing a StaleElementReferenceException:
element = driver.find_element_by_id("movie_player")
actions.move_to_element(element)
actions.context_click(element)
actions.perform()
Nothing I have done can avoid this. I've tried putting it in a try block, with and without some waits thrown in. Somehow the element is going stale in the very short time between finding and setting the element, and performing the context_click action.
Is there any way of getting around this?
Edit: I'll keep checking back in to see if someone knows a better way to do this, but for now, in the interest of expediency, I've just kludged it by using pymouse to actually take control of the mouse and right click.

I suspect the DOM changes if you mouse over the button. To workaround it, "refind" the element:
element = driver.find_element_by_id("movie_player")
actions.move_to_element(element).perform()
element = driver.find_element_by_id("movie_player")
actions.context_click(element).perform()

Related

Python Selenium drag_and_drop promlem

I'm trying to perform DND action, and I'm facing a problem that drives me crazy!
For some reason Selenium keeps using my cursor instead of browsers own cursor. Doesn't matter what method I use (I tried drag_and_drop and also combination of click_and_hold() + release() methods, but without any luck), the element is always dropped where my real mouse cursor is. I've seen this problem raised before (here is similar one on Java, also an issue on gitHub, another one), but unfortunately I found no solution. I've spent many hours trying to make it work and I hope someone actually has an experience of solving this problem.
def test_dnd():
driver = webdriver.Chrome()
driver.get("https://www.w3schools.com/html/html5_draganddrop.asp")
driver.find_element(By.CSS_SELECTOR, "#accept-choices").click()
src = driver.find_element(By.CSS_SELECTOR, "#drag1")
target = driver.find_element(By.CSS_SELECTOR, "#div2")
ActionChains(driver).drag_and_drop(src, target).release().perform()

Selenium Python not finding the element

I'm trying to click on some element but it's not working:
driver.find_element_by_xpath("//span[text()='ENG']")
When I add:
driver.maximize_window()
before click action, it works, other codes are not working again.
I had similar problem
When I was looking for an element, it was not yet available in the code.
Fixed by adding
driver.implicitly_wait(30) ## 30 is the time he will wait
before searching for the element.
This line makes the code wait until the entire page is loaded before looking for an element.
I'm trying to click on some element via driver.find_element_by_xpath("//span[text()='ENG']"), but it's not working,
You need to post logs or be more specific. Are you getting an error on the call to find_element_by_xpath(), or when you call click as you mention below?
when I add driver.maximize_window() before click action, it works,
other codes are not working again, please advise which can be the
reason
The relevant code needs to be provided. I believe you're saying that when you call maximize_window() before you locate the element, it works, but if you don't call maximize window, it fails. This could be for a variety of reasons, but it sounds Javascript related. A similar question like this this could help. If maximize window doesn't actually help the issue, I would look into implicit waits or WebDriverWaits.

**Python Selenium Behave** Alert box automatically closes after going to next step

I am in a project in which I am making a modular behavior driven framework for the company I am working right now. In making a modular approach of the step "user accepts alert", when I test it and came an expected alert box, it automatically closes itself and therefore shows this "NoAlertPresentException: Message: No alert is present" exception.
I have done this codes so far:
def acceptalert():
alert = driver.switch_to.alert
alert.accept()
driver.switch_to.parent_frame()
This code snippet works as I have those modules in which I incorporated the closing of alert box. The only problem is just when I try to make this one a standalone module in my framework. I have done research with this one but I really never got my problem answered. I hope there will be one in here who can help me. Thank you very much.
Found the answer. Thank you. I implemented the step "user clicks '' button" where is the value of the button being matched with a series of xpath and if the xpath returns zero match, then it fetches the available iframes and loops inside each one. When the xpath still returned zero matches, then it switches back to the main frame with this peace of code:
driver.switch_to.parent_frame()
The side effect with this one is it will dismiss the alert boxes. My problem is solved. Thanks everyone.

Selenium PhantomJS throws EelementNotVisible while Firefox is completely fine during combo box selection

So I have a website which has a combo that I need to select an item from, now the problem is it's a bit untraditional and doesn't have option's as elements but instead it has divs.
So I need my program to click combo box then wait (the best way to do this I found is via implicitly_wait(3)# 3 seconds) and then click the box element I need. Firefox is doing a great job with it but PhantomJS seem to throw:
Selenium.common.exceptions.ElementNotVisibleException:
Message: 'Error Message => \'Element is not currently visible and may not be manipulated\'
I'm not sure what's the cause of it, but I suspect that PhantomJS fails to correctly wait via implicitly_wait for some reason and tries to select non-visible element.
Any idea how to approach this without forced thread sleep?
Yup, your issue sounds exactly something I've just fixed in a UI test that was starting to anoy me. Quite a complex one, that passed on all browsers, except my favorite PhantomJs (which is the fastest).
It was quite anoying, when in the debugger I could clearly see that even the parent element was set to visible. Only the prime faces component I needed to click for whatever reason (not CSS or active Styles) was not visible.
After looking at Phantom JS screenshot, I realized the window was quite tiny, and indeed the UI element was not visually visible.
You see now where I am geting at?
Phantom JS is a headless browser, it does not render you the window, but it does use a window, and the window does have a size.
The exception is quite unexpected, because the engine behind is the same as the one used for chrome and safari ... things should just work.
Well, and they did in the end.
Try to tune your driver factory like this:
WebDriver driver = new PhantomJSDriver();
driver.manage().window().setSize(new Dimension(800, 600));
return driver;
Good luck.

Python Selenium WebDriverWait and Click inconsistently giving StaleElementReferenceException()

Ok, here goes my attempt to explain this problem that I haven't even figured out for myself yet. I'm using Selenium with the python-bindings and seem to have an issue with a page element randomly not being found when when using WebDriverWait followed by a click() event. Here is my code:
yearOption = WebDriverWait(self.br, 40).until(lambda d: d.find_element_by_xpath("//select[#name='ctl00$holdSection$rptCommissionYears']/option[#value='%s']" % year), self.br)
print yearOption.text
yearOption.click()
This command set is in a for loop and will randomly fail on the .click() event producing the error: StaleElementReferenceException() after the yearOption.text is printed. This is completely odd to me since the WebDriverWait line obviously found the element, and I haven't reloaded or changed the browser state before clicking the element...
Any ideas why I would be getting this error? Remember, it doesn't happen consistently, infact--sometimes, my entire script will execute successfully with no errors.
I have run into a similar issue before, and I am 99% sure that your problem is the same.
If you check your loop is:
Look for this element
Click
Look for same element
CLick
Normaly after a Click, some page reload or changes occur. This may affect to the element that you are searching for. And if you don't take care, you may end up looking for the element before is reloaded, and when you click it, the element ID already changed, therefore giving you a Stale exception.
Lets go one by one:
Page loads and you element has ID=1
You find it.
You click it and reload/changes start to happen
You enter another loop and find the element. Notice that this even
can happen really fast as there is no wait after click, and thus
find can exit giving you ID=1 element again. You try to click the
element ID=1, but since it was reloaded, it does not exist anymore.
You can fix this in different ways:
If speed is not an issue, you can add an explicit wait after click
of a few seconds, giving enough time to javascript to finish.
You can save the ID of the element, and every time you look for it,
you check that is different, and if it is not, you wait and retry.
Giving this, if that is not your problem, you can always share more of your code and your testing target and I would be happy to help.

Categories