From 06c3d28b490910c6b137dfb184aea8ca40845c53 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 08:49:30 +0000 Subject: [PATCH 1/5] Update selenium requirement from <4.5.0,>=4.1.0 to >=4.1.0,<4.16.0 Updates the requirements on [selenium](https://github.com/SeleniumHQ/Selenium) to permit the latest version. - [Release notes](https://github.com/SeleniumHQ/Selenium/releases) - [Commits](https://github.com/SeleniumHQ/Selenium/compare/selenium-4.1.0...selenium-4.15.0) --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 992a6a00e..bafc210d2 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,7 @@ def get_version_data() -> dict: "zope.testbrowser": ["zope.testbrowser>=6.0", "lxml>=4.2.4", "cssselect"], "django": ["Django>=2.0.6", "lxml>=4.2.4", "cssselect"], "flask": ["Flask>=2.3.2", "lxml>=4.2.4", "cssselect"], - "selenium": ["selenium>=4.1.0,<4.5.0"], + "selenium": ["selenium>=4.1.0,<4.16.0"], }, tests_require=["coverage", "flask"], ) From f8eb4eecf25b7a28a9bca6ae6c348a382577b715 Mon Sep 17 00:00:00 2001 From: francisco souza <108725+fsouza@users.noreply.github.com> Date: Thu, 9 Nov 2023 22:47:11 -0500 Subject: [PATCH 2/5] tests/test_webdriver: remove assertion on exception message Asserting on the message that we don't control is prone to break every time we upgrade selenium, just like I'm doing now. --- tests/test_webdriver.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/test_webdriver.py b/tests/test_webdriver.py index b6aeae580..b8e026f1b 100644 --- a/tests/test_webdriver.py +++ b/tests/test_webdriver.py @@ -21,11 +21,9 @@ def test_webdriver_local_driver_not_present(browser_name): else: service = FirefoxService(executable_path="failpath") - with pytest.raises(WebDriverException) as e: + with pytest.raises(WebDriverException): Browser(browser_name, service=service) - assert "Message: 'failpath' executable needs to be in PATH." in str(e.value) - @pytest.mark.parametrize("browser_name", supported_browsers) def test_attach_file(request, browser_name): From 2ca601855074d8c86cb0af772fcc48485b8aed13 Mon Sep 17 00:00:00 2001 From: francisco souza <108725+fsouza@users.noreply.github.com> Date: Thu, 9 Nov 2023 23:25:36 -0500 Subject: [PATCH 3/5] tests: 4x the `wait_time` in tests Hoping that this will help with the flakiness. Note: I'm 4x'ing with a maximum value of 30. --- tests/is_element_present.py | 29 ++++++++++++++++------------- tests/is_text_present.py | 4 ++-- tests/test_async_finder.py | 10 +++++----- tests/test_element_is_visible.py | 4 ++-- tests/test_mouse_interaction.py | 6 +++--- tests/test_webdriver_firefox.py | 2 +- 6 files changed, 29 insertions(+), 26 deletions(-) diff --git a/tests/is_element_present.py b/tests/is_element_present.py index 2ff897f66..f352095ec 100644 --- a/tests/is_element_present.py +++ b/tests/is_element_present.py @@ -13,7 +13,7 @@ def test_is_element_present_by_css_using_a_custom_wait_time(self): "should is element present by css verify if element is present using a custom wait time" self.browser.find_by_css(".add-async-element").click() self.assertTrue( - self.browser.is_element_present_by_css(".async-element2", wait_time=3), + self.browser.is_element_present_by_css(".async-element2", wait_time=12), ) def test_is_element_present_by_css_returns_false_if_element_is_not_present(self): @@ -31,7 +31,7 @@ def test_is_element_not_present_by_css_returns_false_if_element_is_present(self) def test_is_element_not_present_by_css_using_a_custom_wait_time(self): "should is element not present by css verify if element is not present using a custom wait time" self.assertTrue( - self.browser.is_element_not_present_by_css(".async-element", wait_time=3), + self.browser.is_element_not_present_by_css(".async-element", wait_time=12), ) def test_is_element_present_by_xpath(self): @@ -42,7 +42,7 @@ def test_is_element_present_by_xpath(self): def test_is_element_present_by_xpath_using_a_custom_wait_time(self): "should is element present by xpath verify if element is present using a custom wait time" self.browser.find_by_css(".add-async-element").click() - self.assertTrue(self.browser.is_element_present_by_xpath("//h5", wait_time=3)) + self.assertTrue(self.browser.is_element_present_by_xpath("//h5", wait_time=12)) def test_is_element_present_by_xpath_returns_false_if_element_is_not_present(self): "should is element present by xpath returns false if element is not present" @@ -57,7 +57,7 @@ def test_is_element_not_present_by_xpath_returns_false_if_element_is_present(sel def test_is_element_not_present_by_xpath_using_a_custom_wait_time(self): "should is element not present by xpath verify if element is not present using a custom wait time" self.assertTrue( - self.browser.is_element_not_present_by_xpath("//h4", wait_time=3), + self.browser.is_element_not_present_by_xpath("//h4", wait_time=12), ) def test_is_element_present_by_tag(self): @@ -68,7 +68,7 @@ def test_is_element_present_by_tag(self): def test_is_element_present_by_tag_using_a_custom_wait_time(self): "should is element present by tag verify if element is present using a custom wait time" self.browser.find_by_css(".add-async-element").click() - self.assertTrue(self.browser.is_element_present_by_tag("h4", wait_time=3)) + self.assertTrue(self.browser.is_element_present_by_tag("h4", wait_time=12)) def test_is_element_present_by_tag_returns_false_if_element_is_not_present(self): "should is element present by tag returns false if element is not present" @@ -80,7 +80,7 @@ def test_is_element_not_present_by_tag(self): def test_is_element_not_present_by_tag_using_a_custom_wait_time(self): "should is element not present by tag verify if element is not present using a custom wait time" - self.assertTrue(self.browser.is_element_not_present_by_tag("h4", wait_time=3)) + self.assertTrue(self.browser.is_element_not_present_by_tag("h4", wait_time=12)) def test_is_element_not_present_by_tag_returns_false_if_element_is_present(self): """should is_element_not_present_by_tag returns False if element is present""" @@ -113,7 +113,10 @@ def test_is_element_present_by_value_using_a_custom_wait_time(self): "should is element present by value verify if element is present using a custom wait time" self.browser.find_by_css(".add-async-element").click() self.assertTrue( - self.browser.is_element_present_by_value("async-header-value", wait_time=3), + self.browser.is_element_present_by_value( + "async-header-value", + wait_time=12, + ), ) def test_is_element_present_by_value_returns_false_if_element_is_not_present(self): @@ -131,7 +134,7 @@ def test_is_element_not_present_by_value_using_a_custom_wait_time(self): self.assertTrue( self.browser.is_element_not_present_by_value( "async-header-value", - wait_time=3, + wait_time=12, ), ) @@ -142,14 +145,14 @@ def test_is_element_not_present_by_value_returns_false_if_element_is_present(sel def test_is_element_present_by_id(self): "should is element present by id verify if element is present" self.browser.find_by_css(".add-async-element").click() - result = self.browser.is_element_present_by_id("async-header", wait_time=5) + result = self.browser.is_element_present_by_id("async-header", wait_time=20) assert result def test_is_element_present_by_id_using_a_custom_wait_time(self): "should is element present by id verify if element is present using a custom wait time" self.browser.find_by_css(".add-async-element").click() self.assertTrue( - self.browser.is_element_present_by_id("async-header", wait_time=3), + self.browser.is_element_present_by_id("async-header", wait_time=12), ) def test_is_element_present_by_id_returns_false_if_element_is_not_present(self): @@ -163,7 +166,7 @@ def test_is_element_not_present_by_id(self): def test_is_element_not_present_by_id_using_a_custom_wait_time(self): "should is element not present by id verify if element is not present using a custom wait time" self.assertTrue( - self.browser.is_element_not_present_by_id("async-header", wait_time=3), + self.browser.is_element_not_present_by_id("async-header", wait_time=12), ) def test_is_element_not_present_by_id_returns_false_if_element_is_present(self): @@ -181,7 +184,7 @@ def test_is_element_present_by_name_using_a_custom_wait_time(self): "should is element present by name verify if element is present using a custom wait time" self.browser.find_by_css(".add-async-element").click() self.assertTrue( - self.browser.is_element_present_by_name("async-input", wait_time=3), + self.browser.is_element_present_by_name("async-input", wait_time=12), ) def test_is_element_present_by_name_returns_false_if_element_is_not_present(self): @@ -195,7 +198,7 @@ def test_is_element_not_present_by_name(self): def test_is_element_not_present_by_name_using_a_custom_wait_time(self): "should is element not present by name verify if element is not present using a custom wait time" self.assertTrue( - self.browser.is_element_not_present_by_name("async-input", wait_time=3), + self.browser.is_element_not_present_by_name("async-input", wait_time=12), ) def test_is_element_not_present_by_name_returns_false_if_element_is_present(self): diff --git a/tests/is_text_present.py b/tests/is_text_present.py index c12de3e11..6042f9356 100644 --- a/tests/is_text_present.py +++ b/tests/is_text_present.py @@ -16,7 +16,7 @@ def test_is_text_present_and_should_return_false(self): def test_is_text_present_and_should_wait_time(self): "should verify if text is present and wait for five seconds" self.browser.links.find_by_text("FOO").click() - self.assertTrue(self.browser.is_text_present("BAR!", wait_time=5)) + self.assertTrue(self.browser.is_text_present("BAR!", wait_time=20)) def test_is_text_not_present(self): "should verify if text is not present" @@ -29,7 +29,7 @@ def test_is_text_not_present_and_should_return_false(self): def test_is_text_not_present_and_should_wait_time(self): "should verify if text is not present and wait for five seconds" self.browser.links.find_by_text("FOO").click() - self.assertTrue(self.browser.is_text_not_present("another text", wait_time=5)) + self.assertTrue(self.browser.is_text_not_present("another text", wait_time=20)) def test_is_text_present_no_body(self): "should work properly (return false) even if there's no body" diff --git a/tests/test_async_finder.py b/tests/test_async_finder.py index 215584a46..5ac7a9c75 100644 --- a/tests/test_async_finder.py +++ b/tests/test_async_finder.py @@ -13,7 +13,7 @@ def test_find_by_css_should_found_an_async_element(get_new_browser, browser_name browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() - elements = browser.find_by_css(".async-element", wait_time=10) + elements = browser.find_by_css(".async-element", wait_time=30) assert 1 == len(elements) @@ -24,7 +24,7 @@ def test_find_by_xpath_should_found_an_async_element(get_new_browser, browser_na browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() - elements = browser.find_by_xpath("//h4", wait_time=10) + elements = browser.find_by_xpath("//h4", wait_time=30) assert 1 == len(elements) @@ -35,7 +35,7 @@ def test_find_by_tag_should_found_an_async_element(get_new_browser, browser_name browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() - elements = browser.find_by_tag("h4", wait_time=10) + elements = browser.find_by_tag("h4", wait_time=30) assert 1 == len(elements) @@ -46,7 +46,7 @@ def test_find_by_id_should_found_an_async_element(get_new_browser, browser_name) browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() - elements = browser.find_by_id("async-header", wait_time=10) + elements = browser.find_by_id("async-header", wait_time=30) assert 1 == len(elements) @@ -68,6 +68,6 @@ def test_find_by_value_should_found_an_async_element(get_new_browser, browser_na browser.visit(EXAMPLE_APP) browser.find_by_css(".add-async-element").click() - elements = browser.find_by_value("async-header-value", wait_time=10) + elements = browser.find_by_value("async-header-value", wait_time=30) assert 1 == len(elements) diff --git a/tests/test_element_is_visible.py b/tests/test_element_is_visible.py index 1f82dbdd1..7d72c0494 100644 --- a/tests/test_element_is_visible.py +++ b/tests/test_element_is_visible.py @@ -24,7 +24,7 @@ def test_element_is_visible_custom_wait_time(browser_name, get_new_browser): browser.visit(EXAMPLE_APP) browser.find_by_css(".show-invisible-element").click() - assert browser.find_by_css("#invisible").is_visible(wait_time=3) + assert browser.find_by_css("#invisible").is_visible(wait_time=12) @pytest.mark.parametrize("browser_name", supported_browsers) @@ -61,4 +61,4 @@ def test_element_is_not_visible_custom_wait_time(browser_name, get_new_browser): browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) - assert browser.find_by_css("#invisible").is_not_visible(wait_time=3) + assert browser.find_by_css("#invisible").is_not_visible(wait_time=12) diff --git a/tests/test_mouse_interaction.py b/tests/test_mouse_interaction.py index 82ec206e2..ccbc85b48 100644 --- a/tests/test_mouse_interaction.py +++ b/tests/test_mouse_interaction.py @@ -18,7 +18,7 @@ def test_mouse_over(browser_name, get_new_browser): element = browser.find_by_css(".add-element-mouseover") element.mouse_over() - assert browser.is_element_present_by_id("what-is-your-name", wait_time=5) + assert browser.is_element_present_by_id("what-is-your-name", wait_time=20) element = browser.find_by_css(".add-element-mouseover") element.mouse_out() @@ -65,7 +65,7 @@ def test_double_click(browser_name, get_new_browser): button.double_click() assert browser.find_by_css(".should-be-visible-after-double-click").is_visible( - wait_time=5, + wait_time=20, ) assert browser.is_element_not_present_by_id("what-is-your-name") @@ -80,7 +80,7 @@ def test_right_click(browser_name, get_new_browser): element.right_click() time.sleep(2) - result_1 = browser.find_by_text("right clicked", wait_time=5).text + result_1 = browser.find_by_text("right clicked", wait_time=20).text result_2 = browser.find_by_css(".right-clicable").text assert result_1 == result_2 == "right clicked" diff --git a/tests/test_webdriver_firefox.py b/tests/test_webdriver_firefox.py index 440fdefd8..47ec59449 100644 --- a/tests/test_webdriver_firefox.py +++ b/tests/test_webdriver_firefox.py @@ -52,7 +52,7 @@ def test_firefox_create_instance_with_extension(request): browser.visit(EXAMPLE_APP) elem = browser.find_by_css("body") - elem.is_visible(wait_time=5) + elem.is_visible(wait_time=20) style = elem._element.get_attribute("style") assert "border: 5px solid red;" == style From c815ec628ec29a66c7a60da7de309cd47d203766 Mon Sep 17 00:00:00 2001 From: francisco souza <108725+fsouza@users.noreply.github.com> Date: Thu, 9 Nov 2023 23:39:47 -0500 Subject: [PATCH 4/5] tests: tune time around mouse operations --- tests/test_mouse_interaction.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/tests/test_mouse_interaction.py b/tests/test_mouse_interaction.py index ccbc85b48..ee8956e84 100644 --- a/tests/test_mouse_interaction.py +++ b/tests/test_mouse_interaction.py @@ -18,11 +18,14 @@ def test_mouse_over(browser_name, get_new_browser): element = browser.find_by_css(".add-element-mouseover") element.mouse_over() - assert browser.is_element_present_by_id("what-is-your-name", wait_time=20) + time.sleep(5) + assert browser.is_element_present_by_id("what-is-your-name", wait_time=10) element = browser.find_by_css(".add-element-mouseover") element.mouse_out() + assert browser.is_element_not_present_by_id("what-is-your-name", wait_time=10) + @pytest.mark.parametrize("browser_name", supported_browsers) def test_mouse_out(browser_name, get_new_browser): @@ -33,7 +36,8 @@ def test_mouse_out(browser_name, get_new_browser): element = browser.find_by_css(".add-element-mouseover") element.mouse_over() element.mouse_out() - assert browser.is_element_not_present_by_id("what-is-your-name") + + assert browser.is_element_not_present_by_id("what-is-your-name", wait_time=10) @pytest.mark.parametrize("browser_name", supported_browsers) @@ -48,7 +52,7 @@ def test_mouse_out_top_left(browser_name, get_new_browser): element.mouse_over() element.mouse_out() - assert browser.is_element_not_present_by_id("what-is-your-name") + assert browser.is_element_not_present_by_id("what-is-your-name", wait_time=10) @pytest.mark.parametrize("browser_name", supported_browsers) @@ -61,13 +65,16 @@ def test_double_click(browser_name, get_new_browser): browser = get_new_browser(browser_name) browser.visit(EXAMPLE_APP) - button = browser.find_by_css(".db-button") + button = browser.find_by_css(".db-button", wait_time=10) button.double_click() - assert browser.find_by_css(".should-be-visible-after-double-click").is_visible( - wait_time=20, + assert browser.find_by_css( + ".should-be-visible-after-double-click", + wait_time=10, + ).is_visible( + wait_time=10, ) - assert browser.is_element_not_present_by_id("what-is-your-name") + assert browser.is_element_not_present_by_id("what-is-your-name", wait_time=20) @pytest.mark.parametrize("browser_name", supported_browsers) @@ -79,9 +86,9 @@ def test_right_click(browser_name, get_new_browser): element = browser.find_by_css(".right-clicable") element.right_click() - time.sleep(2) + time.sleep(5) result_1 = browser.find_by_text("right clicked", wait_time=20).text - result_2 = browser.find_by_css(".right-clicable").text + result_2 = browser.find_by_css(".right-clicable", wait_time=20).text assert result_1 == result_2 == "right clicked" @@ -98,4 +105,5 @@ def test_drag_and_drop(browser_name, get_new_browser): draggable = browser.find_by_css(".draggable") draggable.drag_and_drop(droppable) + time.sleep(5) assert "yes" == browser.find_by_css(".dragged").text From c63ee45158fa9492043e3ff4dc0d30a3f42bc2ec Mon Sep 17 00:00:00 2001 From: francisco souza <108725+fsouza@users.noreply.github.com> Date: Fri, 10 Nov 2023 22:15:26 -0500 Subject: [PATCH 5/5] tests: use `pytest.mark.flaky` to manage flaky tests We want to run those, but we don't trust them, so we ignore their results. Also mark all tests for mouse operations as flaky. --- requirements/test.txt | 1 + requirements/test_windows.txt | 1 + tests/test_mouse_interaction.py | 6 ++++++ tox.ini | 6 +++--- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/requirements/test.txt b/requirements/test.txt index 2cbb5a773..d338a50af 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -4,4 +4,5 @@ argparse Django>=2.0.6 pytest==7.4.3 pytest-xdist==3.3.1 +pytest-ignore-flaky==2.1.0 zope.testbrowser==6.0 diff --git a/requirements/test_windows.txt b/requirements/test_windows.txt index bbdbf5330..8053813cd 100644 --- a/requirements/test_windows.txt +++ b/requirements/test_windows.txt @@ -2,4 +2,5 @@ Flask==3.0.0 coverage==7.3.2 argparse pytest==7.4.3 +pytest-ignore-flaky==2.1.0 pytest-xdist==3.3.1 diff --git a/tests/test_mouse_interaction.py b/tests/test_mouse_interaction.py index ee8956e84..d82c101c0 100644 --- a/tests/test_mouse_interaction.py +++ b/tests/test_mouse_interaction.py @@ -9,6 +9,7 @@ from .fake_webapp import EXAMPLE_APP +@pytest.mark.flaky @pytest.mark.parametrize("browser_name", supported_browsers) def test_mouse_over(browser_name, get_new_browser): "Should be able to perform a mouse over on an element" @@ -27,6 +28,7 @@ def test_mouse_over(browser_name, get_new_browser): assert browser.is_element_not_present_by_id("what-is-your-name", wait_time=10) +@pytest.mark.flaky @pytest.mark.parametrize("browser_name", supported_browsers) def test_mouse_out(browser_name, get_new_browser): "Should be able to perform a mouse out on an element" @@ -40,6 +42,7 @@ def test_mouse_out(browser_name, get_new_browser): assert browser.is_element_not_present_by_id("what-is-your-name", wait_time=10) +@pytest.mark.flaky @pytest.mark.parametrize("browser_name", supported_browsers) def test_mouse_out_top_left(browser_name, get_new_browser): """Should be able to perform a mouse out on an element, @@ -55,6 +58,7 @@ def test_mouse_out_top_left(browser_name, get_new_browser): assert browser.is_element_not_present_by_id("what-is-your-name", wait_time=10) +@pytest.mark.flaky @pytest.mark.parametrize("browser_name", supported_browsers) def test_double_click(browser_name, get_new_browser): """Test: WebDriverElement.double_click() @@ -77,6 +81,7 @@ def test_double_click(browser_name, get_new_browser): assert browser.is_element_not_present_by_id("what-is-your-name", wait_time=20) +@pytest.mark.flaky @pytest.mark.parametrize("browser_name", supported_browsers) def test_right_click(browser_name, get_new_browser): "should be able to perform a right click on an element" @@ -93,6 +98,7 @@ def test_right_click(browser_name, get_new_browser): assert result_1 == result_2 == "right clicked" +@pytest.mark.flaky @pytest.mark.parametrize("browser_name", supported_browsers) def test_drag_and_drop(browser_name, get_new_browser): """ diff --git a/tox.ini b/tox.ini index 475f0869b..73668aeee 100644 --- a/tox.ini +++ b/tox.ini @@ -2,7 +2,7 @@ extras = zope.testbrowser, django, flask deps = -rrequirements/test.txt commands= - pytest -v {posargs} + pytest --ignore-flaky -v {posargs} [testenv:tests_selenium] @@ -10,7 +10,7 @@ extras = selenium deps = -rrequirements/test.txt commands= - pytest -v {posargs} + pytest --ignore-flaky -v {posargs} [testenv:tests_windows_selenium] @@ -20,4 +20,4 @@ deps = passenv = EDGEWEBDRIVER commands= - pytest -v {posargs} + pytest --ignore-flaky -v {posargs}