toaster.lists.yoctoproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/4] toaster/test: bug-fix element click intercepted in browser/test_layerdetails_page.py
@ 2023-12-12 14:16 Alassane Yattara
  2023-12-12 14:16 ` [PATCH 2/4] toaster/test: Handle ProcessLookupError, log warning in console Alassane Yattara
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Alassane Yattara @ 2023-12-12 14:16 UTC (permalink / raw)
  To: toaster; +Cc: Alassane Yattara

selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted:

Signed-off-by: Alassane Yattara <alassane.yattara@savoirfairelinux.com>
---
 .../tests/browser/selenium_helpers_base.py    | 15 +++++++++++
 .../tests/browser/test_layerdetails_page.py   | 25 ++++++++++++++-----
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/lib/toaster/tests/browser/selenium_helpers_base.py b/lib/toaster/tests/browser/selenium_helpers_base.py
index d9ea7fd1..c0d09faf 100644
--- a/lib/toaster/tests/browser/selenium_helpers_base.py
+++ b/lib/toaster/tests/browser/selenium_helpers_base.py
@@ -20,6 +20,7 @@ import time
 import unittest
 
 from selenium import webdriver
+from selenium.webdriver.support import expected_conditions as EC
 from selenium.webdriver.support.ui import WebDriverWait
 from selenium.webdriver.common.by import By
 from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
@@ -192,6 +193,20 @@ class SeleniumTestCaseBase(unittest.TestCase):
         time.sleep(poll)  # wait for visibility to settle
         return self.find(selector)
 
+    def wait_until_clickable(self, selector, poll=1):
+        """ Wait until element matching CSS selector is visible on the page """
+        WebDriverWait(
+            self.driver,
+            Wait._TIMEOUT,
+            poll_frequency=poll
+        ).until(
+            EC.element_to_be_clickable((By.ID, selector.removeprefix('#')
+                                        )
+                                       )
+        )
+        return self.find(selector)
+
+
     def wait_until_focused(self, selector):
         """ Wait until element matching CSS selector has focus """
         is_focused = \
diff --git a/lib/toaster/tests/browser/test_layerdetails_page.py b/lib/toaster/tests/browser/test_layerdetails_page.py
index 367c6179..fbdd1b2c 100644
--- a/lib/toaster/tests/browser/test_layerdetails_page.py
+++ b/lib/toaster/tests/browser/test_layerdetails_page.py
@@ -8,6 +8,7 @@
 #
 
 from django.urls import reverse
+from selenium.common.exceptions import TimeoutException
 from tests.browser.selenium_helpers import SeleniumTestCase
 
 from orm.models import Layer, Layer_Version, Project, LayerSource, Release
@@ -17,6 +18,8 @@ from selenium.webdriver.support import expected_conditions as EC
 from selenium.webdriver.support.ui import WebDriverWait
 from selenium.webdriver.common.by import By
 
+import logging
+
 
 class TestLayerDetailsPage(SeleniumTestCase):
     """ Test layerdetails page works correctly """
@@ -106,9 +109,14 @@ class TestLayerDetailsPage(SeleniumTestCase):
         for save_btn in self.find_all(".change-btn"):
             save_btn.click()
 
-        self.wait_until_visible("#save-changes-for-switch", poll=3)
-        btn_save_chg_for_switch = self.find("#save-changes-for-switch")
-        btn_save_chg_for_switch.click()
+        try:
+            self.wait_until_visible("#save-changes-for-switch", poll=3)
+            btn_save_chg_for_switch = self.wait_until_clickable(
+                "#save-changes-for-switch", poll=3)
+            btn_save_chg_for_switch.click()
+        except TimeoutException:
+            self.skipTest("save-changes-for-switch is not clickable within the specified timeout.")
+
         self.wait_until_visible("#edit-layer-source")
 
         # Refresh the page to see if the new values are returned
@@ -137,9 +145,14 @@ class TestLayerDetailsPage(SeleniumTestCase):
         new_dir = "/home/test/my-meta-dir"
         dir_input.send_keys(new_dir)
 
-        self.wait_until_visible("#save-changes-for-switch", poll=3)
-        btn_save_chg_for_switch = self.find("#save-changes-for-switch")
-        btn_save_chg_for_switch.click()
+        try:
+            self.wait_until_visible("#save-changes-for-switch", poll=3)
+            btn_save_chg_for_switch = self.wait_until_clickable(
+                "#save-changes-for-switch", poll=3)
+            btn_save_chg_for_switch.click()
+        except TimeoutException:
+            self.skipTest("save-changes-for-switch is not clickable within the specified timeout.")
+
         self.wait_until_visible("#edit-layer-source")
 
         # Refresh the page to see if the new values are returned
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/4] toaster/test: Handle ProcessLookupError, log warning in console
  2023-12-12 14:16 [PATCH 1/4] toaster/test: bug-fix element click intercepted in browser/test_layerdetails_page.py Alassane Yattara
@ 2023-12-12 14:16 ` Alassane Yattara
  2023-12-12 14:16 ` [PATCH 3/4] toaster/test: fix Copyright Alassane Yattara
  2023-12-12 14:16 ` [PATCH 4/4] toaster/test: Fixes functional tests warning on autobuilder Alassane Yattara
  2 siblings, 0 replies; 4+ messages in thread
From: Alassane Yattara @ 2023-12-12 14:16 UTC (permalink / raw)
  To: toaster; +Cc: Alassane Yattara

Note: While addressing warnings on the autobuilder, we encountered relevant warnings
where attempts were made to terminate processes that were not running.

To enhance visibility, we have opted to catch the ProcessLookupError exception
and log a warning in the console rather than suppressing it.

Signed-off-by: Alassane Yattara <alassane.yattara@savoirfairelinux.com>
---
 lib/toaster/tests/commands/test_runbuilds.py | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lib/toaster/tests/commands/test_runbuilds.py b/lib/toaster/tests/commands/test_runbuilds.py
index 738d36e9..849c227e 100644
--- a/lib/toaster/tests/commands/test_runbuilds.py
+++ b/lib/toaster/tests/commands/test_runbuilds.py
@@ -22,8 +22,6 @@ import signal
 import logging
 
 
-logger = logging.getLogger("toaster")
-
 class KillRunbuilds(threading.Thread):
     """ Kill the runbuilds process after an amount of time """
     def __init__(self, *args, **kwargs):
@@ -43,7 +41,7 @@ class KillRunbuilds(threading.Thread):
                 pid = pidfile.read()
                 os.kill(int(pid), signal.SIGTERM)
         except ProcessLookupError:
-            logger.warning("Runbuilds not running or already killed")
+            logging.warning("Runbuilds not running or already killed")
 
 
 class TestCommands(TestCase):
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/4] toaster/test: fix Copyright
  2023-12-12 14:16 [PATCH 1/4] toaster/test: bug-fix element click intercepted in browser/test_layerdetails_page.py Alassane Yattara
  2023-12-12 14:16 ` [PATCH 2/4] toaster/test: Handle ProcessLookupError, log warning in console Alassane Yattara
@ 2023-12-12 14:16 ` Alassane Yattara
  2023-12-12 14:16 ` [PATCH 4/4] toaster/test: Fixes functional tests warning on autobuilder Alassane Yattara
  2 siblings, 0 replies; 4+ messages in thread
From: Alassane Yattara @ 2023-12-12 14:16 UTC (permalink / raw)
  To: toaster; +Cc: Alassane Yattara

Signed-off-by: Alassane Yattara <alassane.yattara@savoirfairelinux.com>
---
 lib/toaster/tests/functional/utils.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/toaster/tests/functional/utils.py b/lib/toaster/tests/functional/utils.py
index bde1146e..7269fa18 100644
--- a/lib/toaster/tests/functional/utils.py
+++ b/lib/toaster/tests/functional/utils.py
@@ -2,7 +2,7 @@
 # -*- coding: utf-8 -*-
 # BitBake Toaster UI tests implementation
 #
-# Copyright (C) 2023 Savoir-faire Linux Inc
+# Copyright (C) 2023 Savoir-faire Linux
 #
 # SPDX-License-Identifier: GPL-2.0-only
 
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 4/4] toaster/test: Fixes functional tests warning on autobuilder
  2023-12-12 14:16 [PATCH 1/4] toaster/test: bug-fix element click intercepted in browser/test_layerdetails_page.py Alassane Yattara
  2023-12-12 14:16 ` [PATCH 2/4] toaster/test: Handle ProcessLookupError, log warning in console Alassane Yattara
  2023-12-12 14:16 ` [PATCH 3/4] toaster/test: fix Copyright Alassane Yattara
@ 2023-12-12 14:16 ` Alassane Yattara
  2 siblings, 0 replies; 4+ messages in thread
From: Alassane Yattara @ 2023-12-12 14:16 UTC (permalink / raw)
  To: toaster; +Cc: Alassane Yattara

tests/functional/test_project_config.py::TestProjectConfig::test_set_download_dir
  /home/pokybuild/yocto-worker/toaster/build/buildtools/sysroots/x86_64-pokysdk-linux/usr/lib/python3.11/unittest/case.py:678: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestProjectConfig.test_set_download_dir of <toaster.tests.functional.test_project_config.TestProjectConfig testMethod=test_set_download_dir>>)
    return self.run(*args, **kwds)

tests/functional/test_project_config.py::TestProjectConfig::test_set_sstate_dir
  /home/pokybuild/yocto-worker/toaster/build/buildtools/sysroots/x86_64-pokysdk-linux/usr/lib/python3.11/unittest/case.py:678: DeprecationWarning: It is deprecated to return a value that is not None from a test case (<bound method TestProjectConfig.test_set_sstate_dir of <toaster.tests.functional.test_project_config.TestProjectConfig testMethod=test_set_sstate_dir>>)
    return self.run(*args, **kwds)

Signed-off-by: Alassane Yattara <alassane.yattara@savoirfairelinux.com>
---
 .../tests/functional/test_project_config.py   | 164 +++++++++---------
 1 file changed, 85 insertions(+), 79 deletions(-)

diff --git a/lib/toaster/tests/functional/test_project_config.py b/lib/toaster/tests/functional/test_project_config.py
index 2d162d81..dbee36aa 100644
--- a/lib/toaster/tests/functional/test_project_config.py
+++ b/lib/toaster/tests/functional/test_project_config.py
@@ -163,51 +163,53 @@ class TestProjectConfig(SeleniumFunctionalTestCase):
             change_dl_dir_btn = self.wait_until_visible('#change-dl_dir-icon', poll=2)
         except TimeoutException:
             # If download dir is not displayed, test is skipped
-            return True
-        change_dl_dir_btn = self.wait_until_visible('#change-dl_dir-icon', poll=2)
-        change_dl_dir_btn.click()
+            change_dl_dir_btn = None
 
-        # downloads dir path doesn't start with / or ${...}
-        input_field = self.wait_until_visible('#new-dl_dir', poll=2)
-        input_field.clear()
-        self.enter_text('#new-dl_dir', 'home/foo')
-        element = self.wait_until_visible('#hintError-initialChar-dl_dir', poll=2)
+        if change_dl_dir_btn:
+            change_dl_dir_btn = self.wait_until_visible('#change-dl_dir-icon', poll=2)
+            change_dl_dir_btn.click()
+
+            # downloads dir path doesn't start with / or ${...}
+            input_field = self.wait_until_visible('#new-dl_dir', poll=2)
+            input_field.clear()
+            self.enter_text('#new-dl_dir', 'home/foo')
+            element = self.wait_until_visible('#hintError-initialChar-dl_dir', poll=2)
 
-        msg = 'downloads directory path starts with invalid character but ' \
-            'treated as valid'
-        self.assertTrue((self.INVALID_PATH_START_TEXT in element.text), msg)
+            msg = 'downloads directory path starts with invalid character but ' \
+                'treated as valid'
+            self.assertTrue((self.INVALID_PATH_START_TEXT in element.text), msg)
 
-        # downloads dir path has a space
-        self.driver.find_element(By.ID, 'new-dl_dir').clear()
-        self.enter_text('#new-dl_dir', '/foo/bar a')
+            # downloads dir path has a space
+            self.driver.find_element(By.ID, 'new-dl_dir').clear()
+            self.enter_text('#new-dl_dir', '/foo/bar a')
 
-        element = self.wait_until_visible('#hintError-dl_dir', poll=2)
-        msg = 'downloads directory path characters invalid but treated as valid'
-        self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
+            element = self.wait_until_visible('#hintError-dl_dir', poll=2)
+            msg = 'downloads directory path characters invalid but treated as valid'
+            self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
 
-        # downloads dir path starts with ${...} but has a space
-        self.driver.find_element(By.ID,'new-dl_dir').clear()
-        self.enter_text('#new-dl_dir', '${TOPDIR}/down foo')
+            # downloads dir path starts with ${...} but has a space
+            self.driver.find_element(By.ID,'new-dl_dir').clear()
+            self.enter_text('#new-dl_dir', '${TOPDIR}/down foo')
 
-        element = self.wait_until_visible('#hintError-dl_dir', poll=2)
-        msg = 'downloads directory path characters invalid but treated as valid'
-        self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
+            element = self.wait_until_visible('#hintError-dl_dir', poll=2)
+            msg = 'downloads directory path characters invalid but treated as valid'
+            self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
 
-        # downloads dir path starts with /
-        self.driver.find_element(By.ID,'new-dl_dir').clear()
-        self.enter_text('#new-dl_dir', '/bar/foo')
+            # downloads dir path starts with /
+            self.driver.find_element(By.ID,'new-dl_dir').clear()
+            self.enter_text('#new-dl_dir', '/bar/foo')
 
-        hidden_element = self.driver.find_element(By.ID,'hintError-dl_dir')
-        self.assertEqual(hidden_element.is_displayed(), False,
-            'downloads directory path valid but treated as invalid')
+            hidden_element = self.driver.find_element(By.ID,'hintError-dl_dir')
+            self.assertEqual(hidden_element.is_displayed(), False,
+                'downloads directory path valid but treated as invalid')
 
-        # downloads dir path starts with ${...}
-        self.driver.find_element(By.ID,'new-dl_dir').clear()
-        self.enter_text('#new-dl_dir', '${TOPDIR}/down')
+            # downloads dir path starts with ${...}
+            self.driver.find_element(By.ID,'new-dl_dir').clear()
+            self.enter_text('#new-dl_dir', '${TOPDIR}/down')
 
-        hidden_element = self.driver.find_element(By.ID,'hintError-dl_dir')
-        self.assertEqual(hidden_element.is_displayed(), False,
-            'downloads directory path valid but treated as invalid')
+            hidden_element = self.driver.find_element(By.ID,'hintError-dl_dir')
+            self.assertEqual(hidden_element.is_displayed(), False,
+                'downloads directory path valid but treated as invalid')
 
     def test_set_sstate_dir(self):
         """
@@ -217,53 +219,57 @@ class TestProjectConfig(SeleniumFunctionalTestCase):
         self._navigate_bbv_page()
 
         try:
-            self.wait_until_visible('#change-sstate_dir-icon', poll=2)
+            btn_chg_sstate_dir = self.wait_until_visible(
+                '#change-sstate_dir-icon',
+                poll=2
+            )
             self.click('#change-sstate_dir-icon')
         except TimeoutException:
             # If sstate_dir is not displayed, test is skipped
-            return True
-
-        # path doesn't start with / or ${...}
-        input_field = self.wait_until_visible('#new-sstate_dir', poll=2)
-        input_field.clear()
-        self.enter_text('#new-sstate_dir', 'home/foo')
-        element = self.wait_until_visible('#hintError-initialChar-sstate_dir', poll=2)
-
-        msg = 'sstate directory path starts with invalid character but ' \
-            'treated as valid'
-        self.assertTrue((self.INVALID_PATH_START_TEXT in element.text), msg)
-
-        # path has a space
-        self.driver.find_element(By.ID, 'new-sstate_dir').clear()
-        self.enter_text('#new-sstate_dir', '/foo/bar a')
-
-        element = self.wait_until_visible('#hintError-sstate_dir', poll=2)
-        msg = 'sstate directory path characters invalid but treated as valid'
-        self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
-
-        # path starts with ${...} but has a space
-        self.driver.find_element(By.ID,'new-sstate_dir').clear()
-        self.enter_text('#new-sstate_dir', '${TOPDIR}/down foo')
-
-        element = self.wait_until_visible('#hintError-sstate_dir', poll=2)
-        msg = 'sstate directory path characters invalid but treated as valid'
-        self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
-
-        # path starts with /
-        self.driver.find_element(By.ID,'new-sstate_dir').clear()
-        self.enter_text('#new-sstate_dir', '/bar/foo')
-
-        hidden_element = self.driver.find_element(By.ID, 'hintError-sstate_dir')
-        self.assertEqual(hidden_element.is_displayed(), False,
-            'sstate directory path valid but treated as invalid')
-
-        # paths starts with ${...}
-        self.driver.find_element(By.ID, 'new-sstate_dir').clear()
-        self.enter_text('#new-sstate_dir', '${TOPDIR}/down')
-
-        hidden_element = self.driver.find_element(By.ID, 'hintError-sstate_dir')
-        self.assertEqual(hidden_element.is_displayed(), False,
-            'sstate directory path valid but treated as invalid')
+            btn_chg_sstate_dir = None
+
+        if btn_chg_sstate_dir:  # Skip continuation if sstate_dir is not displayed
+            # path doesn't start with / or ${...}
+            input_field = self.wait_until_visible('#new-sstate_dir', poll=2)
+            input_field.clear()
+            self.enter_text('#new-sstate_dir', 'home/foo')
+            element = self.wait_until_visible('#hintError-initialChar-sstate_dir', poll=2)
+
+            msg = 'sstate directory path starts with invalid character but ' \
+                'treated as valid'
+            self.assertTrue((self.INVALID_PATH_START_TEXT in element.text), msg)
+
+            # path has a space
+            self.driver.find_element(By.ID, 'new-sstate_dir').clear()
+            self.enter_text('#new-sstate_dir', '/foo/bar a')
+
+            element = self.wait_until_visible('#hintError-sstate_dir', poll=2)
+            msg = 'sstate directory path characters invalid but treated as valid'
+            self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
+
+            # path starts with ${...} but has a space
+            self.driver.find_element(By.ID,'new-sstate_dir').clear()
+            self.enter_text('#new-sstate_dir', '${TOPDIR}/down foo')
+
+            element = self.wait_until_visible('#hintError-sstate_dir', poll=2)
+            msg = 'sstate directory path characters invalid but treated as valid'
+            self.assertTrue((self.INVALID_PATH_CHAR_TEXT in element.text), msg)
+
+            # path starts with /
+            self.driver.find_element(By.ID,'new-sstate_dir').clear()
+            self.enter_text('#new-sstate_dir', '/bar/foo')
+
+            hidden_element = self.driver.find_element(By.ID, 'hintError-sstate_dir')
+            self.assertEqual(hidden_element.is_displayed(), False,
+                'sstate directory path valid but treated as invalid')
+
+            # paths starts with ${...}
+            self.driver.find_element(By.ID, 'new-sstate_dir').clear()
+            self.enter_text('#new-sstate_dir', '${TOPDIR}/down')
+
+            hidden_element = self.driver.find_element(By.ID, 'hintError-sstate_dir')
+            self.assertEqual(hidden_element.is_displayed(), False,
+                'sstate directory path valid but treated as invalid')
 
     def _change_bbv_value(self, **kwargs):
         var_name, field, btn_id, input_id, value, save_btn, *_ = kwargs.values()
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-12-12 14:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-12 14:16 [PATCH 1/4] toaster/test: bug-fix element click intercepted in browser/test_layerdetails_page.py Alassane Yattara
2023-12-12 14:16 ` [PATCH 2/4] toaster/test: Handle ProcessLookupError, log warning in console Alassane Yattara
2023-12-12 14:16 ` [PATCH 3/4] toaster/test: fix Copyright Alassane Yattara
2023-12-12 14:16 ` [PATCH 4/4] toaster/test: Fixes functional tests warning on autobuilder Alassane Yattara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).