1

I'm trying to do the test to learn Allure, and to assure that the test is passed, the button has to be INVISIBLE. It first clicks 1st button to make 2nd button appear. Then click 2nd button - so same (2nd button disappears). Here it is: http://the-internet.herokuapp.com/add_remove_elements/

My code would look like this (below), it clicks the 1st button, 2nd button - and after it should check that button DELETE is not visible anymore. Instead it interrupts whole code and throws error that element was not found/located. How do you make it so it will not interrput/cancel whole codeblock when it doesn't find this button?

class TestPage:

    def test_button(self):
        s=Service('C:\Program Files\chromedriver.exe')
        browser = webdriver.Chrome(service=s)
        browser.get("http://the-internet.herokuapp.com/")
        browser.maximize_window()
        time.sleep(1)
        add = browser.find_element(By.XPATH, "/html/body/div[2]/div/ul/li[2]/a")
        add.click()
        time.sleep(1)
        button = browser.find_element(By.XPATH, "/html/body/div[2]/div/div/button")
        button.click()
        time.sleep(1)
        deleteButton = browser.find_element(By.XPATH, "/html/body/div[2]/div/div/div/button")
        deleteButton.click()
        deleteCheck = browser.find_element(By.XPATH, "/html/body/div[2]/div/div/div/button").is_displayed()
        if deleteCheck == False:
            assert True
        else:
            assert False
        time.sleep(1)
        browser.close()

Here's edited code (with last step trying to go to main page):

def test_button(self):
        s=Service('C:\Program Files\chromedriver.exe')
        browser = webdriver.Chrome(service=s)
        browser.get("http://the-internet.herokuapp.com/")
        browser.maximize_window()
        wait = WebDriverWait(browser, 3)
        time.sleep(1)
        add = browser.find_element(By.XPATH, "/html/body/div[2]/div/ul/li[2]/a")
        add.click()
        time.sleep(1)
        button = browser.find_element(By.XPATH, "/html/body/div[2]/div/div/button")
        button.click()
        time.sleep(1)
        browser.save_screenshot('buttons.png')
        time.sleep(1)
        delete = browser.find_element(By.XPATH, "/html/body/div[2]/div/div/div/button")
        delete.click()
        time.sleep(1)
        wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[onclick*='delete']"))).click()
        time.sleep(0.5)
        if not browser.find_elements(By.CSS_SELECTOR, "button[onclick*='delete']"):
            assert True
        else:
            assert False
        time.sleep(0.5)
        browser.get("http://the-internet.herokuapp.com/")
michalb93
  • 119
  • 9

3 Answers3

1

You can wrap the deleteCheck in a try block:

try:
    deleteCheck = browser.find_element(By.XPATH, "/html/body/div[2]/div/div/div/button")
    assert False
except NoSuchElementException:
    assert True
Bendik Knapstad
  • 1,409
  • 1
  • 9
  • 18
1

you can try this code to wait for that element in 15 second and if it does not appear then continue code

try:
    WebDriverWait(self.browser, 15).until(EC.visibility_of_all_elements_located((By.XPATH, "/html/body/div[2]/div/div/div/button")))
    ...
except:
    continue
1

After clicking the delete button it disappears. Not only becomes invisible but no more present on the page.
The clearest way to validate web element is not presented is to use find_elements method. This method return a list of elements found matching the passed locator. So, in case of match the list will be non-empty and in case of no match the list will be empty. Non-empty list is indicated by Python as Boolean True, while empty list is indicated as Boolean False. No exception will be thrown in any case.
Additionally, you need to improve your locators and use WebDriverWait expected_conditions explicit waits, not hardcoded sleeps.
The following code worked for me:

import time

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

options = Options()
options.add_argument("start-maximized")
options.add_argument('--disable-notifications')

webdriver_service = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(options=options, service=webdriver_service)
wait = WebDriverWait(driver, 10)

url = "http://the-internet.herokuapp.com/add_remove_elements/"
driver.get(url)


wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[onclick*='add']"))).click()
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[onclick*='delete']"))).click()
time.sleep(0.5)
if not driver.find_elements(By.CSS_SELECTOR, "button[onclick*='delete']"):
    print("Delete button not presented")
Prophet
  • 32,350
  • 22
  • 54
  • 79
  • I guess it works, but what if you'd want code to do something more after "if not"? I tried to attach browser.get() after this "if not..." but it just stops right on this 'if' and ignores next steps. Also, my terminal shows me that the test failed, while it should, I guess, PASS? I mean, button is not visible so it means a success/test pass, not fail. Should it be that way? – michalb93 Nov 23 '22 at 09:50
  • It gives me error: `Desktop/SELENIUM/test_single.py::TestPage::test_button - selenium.common.exceptions.TimeoutException: Message:` – michalb93 Nov 23 '22 at 09:52
  • 1
    This code worked for me. I run it several times. What line gives you that exception? – Prophet Nov 23 '22 at 09:53
  • 1
    Of course you can continue your test after the code I shared. Please show me what have you tried so it gave you a failure? Not as a comment, inside the question to make it readable. – Prophet Nov 23 '22 at 09:56
  • I attached it to my first post (as edit) – michalb93 Nov 23 '22 at 10:02
  • 1
    You leaved your previous code and added my. This will not work... You have 4 clicks there while only 2 clicks needed there – Prophet Nov 23 '22 at 10:06
  • I tried it again, but added `assert True` instead of `print("Delete button not presented")` and it worked fine... I dont understand, why my code was wrong, while both codes did almost same thing? – michalb93 Nov 23 '22 at 10:15
  • 1
    Looks like you clicked buttons more than 2 times as you intended to do – Prophet Nov 23 '22 at 10:17
  • 2
    @michalb93 the reason his code works and your does not is that he is using find_elements and you are using find_element, the difference is that find elements returns a list of all elements that match the selector, and returnes a empty list if there are no elements that match, find_element raises an error if it cant find any element that matches the selector. – Bendik Knapstad Nov 23 '22 at 10:34