Home > Mobile >  Selenium python random Jenkins pipeline fails
Selenium python random Jenkins pipeline fails

Time:09-30

I have a problem I cannot figure out how to solve as it occurs randomly.

I have a webpage on which I want to check always if everything is working, such as buttons, videos etc.

So I start using selenium and everything works just fine when I run it locally.

S I decided to automate those test by creating a Jenkins pipeline, and here is the weird thing, out of 16 pipelines, I have always random 2 pipeline that fails and times out always at the same point.

Let me give a bit more details:

one step that all the pipelines have in common is this:

Play video
(wait for the video to finish)
Press Next button

This bit of code is as follow:

# Play Button
time.sleep(5)
wait.until(EC.presence_of_element_located((By.XPATH, "//div[contains(text(),'Play')]"))).click()
time.sleep(120)

# After Video Ends, click Next button
wait.until(EC.presence_of_element_located((By.XPATH, "//button[contains(text(),'Next')]"))).click(

I am not an expert with Selenium, so this is the solution that I could think of. The video plays just fine, always..but randomly it fails because it cannot find the Next button.

On step to debug this, is to take a screenshot and see what is happening. In the screenshot I could see the button, which mean the page was fully loaded. So I decided to increase the web driver wait time to 150sec and yet the same error occurs randomly.

So I was wondering what else I can do to prevent those False Positive from happening?

I hope I made my point clear enough and please if I missed something or need more infos, just ask me.

UPDATE: Thank you Tony for your help. Just to make sure I understood the logic. This is the updated code.

driver.set_window_size(1920,994)
short_timeout = 100
long_timeout = 150

play = None

try:
    next = WebDriverWait(driver, short_timeout).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(text(),'Play')]")))
except TimeoutException:
    try:
        driver.get(driver.current_url)
        next = WebDriverWait(driver, long_timeout).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(text(),'Play')]")))
    except TimeoutException:
        pass

if next is not None:
    driver.execute_script("arguments[0].scrollIntoView();", play)
    driver.execute_script("arguments[0].click();", play) 

# After Video Ends, click Next button

next = None

try:
    next = WebDriverWait(driver, short_timeout).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Next')]")))
except TimeoutException:
    try:
        driver.get(driver.current_url) # reload the current page
        next = WebDriverWait(driver, long_timeout).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Next')]")))
    except TimeoutException:
        pass

if next is not None:
    driver.execute_script("arguments[0].scrollIntoView();", next)
    driver.execute_script("arguments[0].click();", next) 

the Try and except must be applied to every action I want to perform on that page, and if it timeout, it reload the page and try again.

There is only one thing that I am not sure I understood. The if statement for the scroll and click. I have to declare it for each try?

CodePudding user response:

It's difficult to say without having a minimal example to test with.

You shouldn't need your time.sleep() calls and instead use the ExpectedConditions fully. You're already using presence_of_element_located but as the docs state, this check doesn't ensure that the element is visible; and thus clickable.

An expectation for checking that an element is present on the DOM of a page. This does not necessarily mean that the element is visible.

Try using element_to_be_clickable which should check visibility and clickability:

An Expectation for checking an element is visible and enabled such that you can click it.

Also, be careful reusing your WebDriverWait object as they chain.

CodePudding user response:

I would suggest the following:

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By

next = None
try:
    next = WebDriverWait(driver, short_timeout).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Next')]")))                            
except TimeoutException:
    try:
        driver.get(driver.current_url) # reload the current page
        next = WebDriverWait(driver, long_timeout).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Next')]")))
    except TimeoutException:
        pass

if next is not None:
    driver.execute_script("arguments[0].scrollIntoView();", next)
    driver.execute_script("arguments[0].click();", next) 

Other option is to use next.click() as you did but I learned that this sometimes doesn't work while executing a click via JavaScript always work.

  • Related