From patchwork Tue Oct 3 17:26:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marlon Rodriguez Garcia X-Patchwork-Id: 31629 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id 53FA7E7542B for ; Tue, 3 Oct 2023 17:26:34 +0000 (UTC) Received: from mail.savoirfairelinux.com (mail.savoirfairelinux.com [208.88.110.44]) by mx.groups.io with SMTP id smtpd.web11.114301.1696353990819912465 for ; Tue, 03 Oct 2023 10:26:32 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@savoirfairelinux.com header.s=DFC430D2-D198-11EC-948E-34200CB392D2 header.b=fb2HreXa; spf=pass (domain: savoirfairelinux.com, ip: 208.88.110.44, mailfrom: marlon.rodriguez-garcia@savoirfairelinux.com) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 9A8849C28CB for ; Tue, 3 Oct 2023 13:26:29 -0400 (EDT) Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10032) with ESMTP id 8aeteCXOT6_w; Tue, 3 Oct 2023 13:26:26 -0400 (EDT) Received: from localhost (localhost [127.0.0.1]) by mail.savoirfairelinux.com (Postfix) with ESMTP id 7750E9C2980; Tue, 3 Oct 2023 13:26:26 -0400 (EDT) DKIM-Filter: OpenDKIM Filter v2.10.3 mail.savoirfairelinux.com 7750E9C2980 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=savoirfairelinux.com; s=DFC430D2-D198-11EC-948E-34200CB392D2; t=1696353986; bh=SqCm0HXg6toSdJeM72ee2fL+hZbfxUmRXFqjJJV45vQ=; h=From:To:Date:Message-Id:MIME-Version; b=fb2HreXaV/RD6wFQ8RZe5qvnZgRiWMIPUX47vRZUutdEUzarjjkb/M2s3pY4cCE8h KI+uWOpBlyq2GJxIEPrFuWru3KDGDP0VFI9xN83tlWXMZHeYGlBJaNO08F1qIiqlq+ /8N/aT3qnCjq7foZb/834NxVAH+Av5MmQuBDwgJlBIfCSZLXGAR9PM0u9nUINc8Wyd /z8tBZqMrQECqzqoivF3qvdzWiip02clskh6BylFAwu1B8M+vHG+sHnFAUO7BR6KnG DKfoCo5rKGmecTaOy5LnVZZTpQxWWR2eZ7mod+WTT45UpAKXjosEOUuV9f/CQs2WyL atpVKvFVBwqLg== X-Virus-Scanned: amavis at mail.savoirfairelinux.com Received: from mail.savoirfairelinux.com ([127.0.0.1]) by localhost (mail.savoirfairelinux.com [127.0.0.1]) (amavis, port 10026) with ESMTP id lBGdpGE8pjE2; Tue, 3 Oct 2023 13:26:26 -0400 (EDT) Received: from savoirfairelinux.hitronhub.home (unknown [192.168.51.254]) by mail.savoirfairelinux.com (Postfix) with ESMTPSA id 492AB9C28CB; Tue, 3 Oct 2023 13:26:26 -0400 (EDT) From: Marlon Rodriguez Garcia To: bitbake-devel@lists.openembedded.org Cc: Marlon Rodriguez Garcia Subject: [PATCH 1/1] toaster:update selenium version and code syntax Date: Tue, 3 Oct 2023 13:26:23 -0400 Message-Id: <20231003172623.72071-1-marlon.rodriguez-garcia@savoirfairelinux.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Tue, 03 Oct 2023 17:26:34 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/bitbake-devel/message/15177 Updated selenium version to latest 4.13.0, changed selenum specific version syntax elements to accomplish test success Signed-off-by: Marlon Rodriguez Garcia --- lib/toaster/orm/models.py | 2 +- .../tests/browser/selenium_helpers_base.py | 9 +- .../tests/browser/test_all_builds_page.py | 26 ++-- .../tests/browser/test_all_projects_page.py | 14 +- .../tests/browser/test_builddashboard_page.py | 10 +- .../browser/test_most_recent_builds_states.py | 12 +- .../browser/test_new_custom_image_page.py | 4 + .../tests/browser/test_new_project_page.py | 12 +- .../tests/browser/test_project_config_page.py | 29 +++-- .../tests/browser/test_toastertable_ui.py | 7 +- .../tests/builds/test_core_image_min.py | 1 + .../tests/functional/functional_helpers.py | 21 +-- .../tests/functional/test_functional_basic.py | 120 +++++++++--------- .../tests/toaster-tests-requirements.txt | 2 +- lib/toaster/tests/views/test_views.py | 4 + lib/toaster/toastergui/widgets.py | 1 + 16 files changed, 156 insertions(+), 118 deletions(-) diff --git a/lib/toaster/orm/models.py b/lib/toaster/orm/models.py index f9fcf9e4..0d503a51 100644 --- a/lib/toaster/orm/models.py +++ b/lib/toaster/orm/models.py @@ -1733,7 +1733,7 @@ class CustomImageRecipe(Recipe): packages_conf += "\"" base_recipe_path = self.get_base_recipe_file() - if base_recipe_path: + if base_recipe_path and os.path.isfile(base_recipe_path): base_recipe = open(base_recipe_path, 'r').read() else: # Pass back None to trigger error message to user diff --git a/lib/toaster/tests/browser/selenium_helpers_base.py b/lib/toaster/tests/browser/selenium_helpers_base.py index 644d45fe..9a4e27a3 100644 --- a/lib/toaster/tests/browser/selenium_helpers_base.py +++ b/lib/toaster/tests/browser/selenium_helpers_base.py @@ -21,6 +21,7 @@ import unittest from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.common.by import By from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.common.exceptions import NoSuchElementException, \ StaleElementReferenceException, TimeoutException @@ -32,9 +33,7 @@ def create_selenium_driver(cls,browser='chrome'): browser = env_browser if browser == 'chrome': - return webdriver.Chrome( - service_args=["--verbose", "--log-path=selenium.log"] - ) + return webdriver.Chrome() elif browser == 'firefox': return webdriver.Firefox() elif browser == 'marionette': @@ -153,11 +152,11 @@ class SeleniumTestCaseBase(unittest.TestCase): def find(self, selector): """ Find single element by CSS selector """ - return self.driver.find_element_by_css_selector(selector) + return self.driver.find_element(By.CSS_SELECTOR, selector) def find_all(self, selector): """ Find all elements matching CSS selector """ - return self.driver.find_elements_by_css_selector(selector) + return self.driver.find_elements(By.CSS_SELECTOR, selector) def element_exists(self, selector): """ diff --git a/lib/toaster/tests/browser/test_all_builds_page.py b/lib/toaster/tests/browser/test_all_builds_page.py index 8423d3da..d4312bb3 100644 --- a/lib/toaster/tests/browser/test_all_builds_page.py +++ b/lib/toaster/tests/browser/test_all_builds_page.py @@ -7,7 +7,7 @@ # SPDX-License-Identifier: GPL-2.0-only # -import re +import re, time from django.urls import reverse from django.utils import timezone @@ -15,6 +15,8 @@ from tests.browser.selenium_helpers import SeleniumTestCase from orm.models import BitbakeVersion, Release, Project, Build, Target +from selenium.webdriver.common.by import By + class TestAllBuildsPage(SeleniumTestCase): """ Tests for all builds page /builds/ """ @@ -91,7 +93,7 @@ class TestAllBuildsPage(SeleniumTestCase): found_row = None for row in rows: - outcome_links = row.find_elements_by_css_selector(selector) + outcome_links = row.find_elements(By.CSS_SELECTOR, selector) if len(outcome_links) == 1: found_row = row break @@ -131,17 +133,19 @@ class TestAllBuildsPage(SeleniumTestCase): url = reverse('all-builds') self.get(url) + # should see a rebuild button for non-command-line builds + selector = 'div[data-latest-build-result="%s"] .rebuild-btn' % build1.id + time.sleep(2) + run_again_button = self.find_all(selector) + self.assertEqual(len(run_again_button), 1, + 'should see a rebuild button for non-cli builds') + # shouldn't see a rebuild button for command-line builds selector = 'div[data-latest-build-result="%s"] .rebuild-btn' % default_build.id run_again_button = self.find_all(selector) self.assertEqual(len(run_again_button), 0, 'should not see a rebuild button for cli builds') - # should see a rebuild button for non-command-line builds - selector = 'div[data-latest-build-result="%s"] .rebuild-btn' % build1.id - run_again_button = self.find_all(selector) - self.assertEqual(len(run_again_button), 1, - 'should see a rebuild button for non-cli builds') def test_tooltips_on_project_name(self): """ @@ -198,24 +202,24 @@ class TestAllBuildsPage(SeleniumTestCase): # test recent builds area for successful build element = self._get_build_time_element(build1) - links = element.find_elements_by_css_selector('a') + links = element.find_elements(By.CSS_SELECTOR, 'a') msg = 'should be a link on the build time for a successful recent build' self.assertEquals(len(links), 1, msg) # test recent builds area for failed build element = self._get_build_time_element(build2) - links = element.find_elements_by_css_selector('a') + links = element.find_elements(By.CSS_SELECTOR, 'a') msg = 'should not be a link on the build time for a failed recent build' self.assertEquals(len(links), 0, msg) # test the time column for successful build build1_row = self._get_row_for_build(build1) - links = build1_row.find_elements_by_css_selector('td.time a') + links = build1_row.find_elements(By.CSS_SELECTOR, 'td.time a') msg = 'should be a link on the build time for a successful build' self.assertEquals(len(links), 1, msg) # test the time column for failed build build2_row = self._get_row_for_build(build2) - links = build2_row.find_elements_by_css_selector('td.time a') + links = build2_row.find_elements(By.CSS_SELECTOR, 'td.time a') msg = 'should not be a link on the build time for a failed build' self.assertEquals(len(links), 0, msg) diff --git a/lib/toaster/tests/browser/test_all_projects_page.py b/lib/toaster/tests/browser/test_all_projects_page.py index 15b03400..3389d323 100644 --- a/lib/toaster/tests/browser/test_all_projects_page.py +++ b/lib/toaster/tests/browser/test_all_projects_page.py @@ -16,6 +16,8 @@ from tests.browser.selenium_helpers import SeleniumTestCase from orm.models import BitbakeVersion, Release, Project, Build from orm.models import ProjectVariable +from selenium.webdriver.common.by import By + class TestAllProjectsPage(SeleniumTestCase): """ Browser tests for projects page /projects/ """ @@ -117,7 +119,7 @@ class TestAllProjectsPage(SeleniumTestCase): # check the release text for the default project selector = 'span[data-project-field="release"] span.text-muted' - element = default_project_row.find_element_by_css_selector(selector) + element = default_project_row.find_element(By.CSS_SELECTOR, selector) text = element.text.strip() self.assertEqual(text, 'Not applicable', 'release should be "not applicable" for default project') @@ -127,7 +129,7 @@ class TestAllProjectsPage(SeleniumTestCase): # check the link in the release cell for the other project selector = 'span[data-project-field="release"]' - element = other_project_row.find_element_by_css_selector(selector) + element = other_project_row.find_element(By.CSS_SELECTOR, selector) text = element.text.strip() self.assertEqual(text, self.release.name, 'release name should be shown for non-default project') @@ -152,7 +154,7 @@ class TestAllProjectsPage(SeleniumTestCase): # check the machine cell for the default project selector = 'span[data-project-field="machine"] span.text-muted' - element = default_project_row.find_element_by_css_selector(selector) + element = default_project_row.find_element(By.CSS_SELECTOR, selector) text = element.text.strip() self.assertEqual(text, 'Not applicable', 'machine should be not applicable for default project') @@ -162,7 +164,7 @@ class TestAllProjectsPage(SeleniumTestCase): # check the link in the machine cell for the other project selector = 'span[data-project-field="machine"]' - element = other_project_row.find_element_by_css_selector(selector) + element = other_project_row.find_element(By.CSS_SELECTOR, selector) text = element.text.strip() self.assertEqual(text, self.MACHINE_NAME, 'machine name should be shown for non-default project') @@ -187,7 +189,7 @@ class TestAllProjectsPage(SeleniumTestCase): # check the link on the name field selector = 'span[data-project-field="name"] a' - element = default_project_row.find_element_by_css_selector(selector) + element = default_project_row.find_element(By.CSS_SELECTOR, selector) link_url = element.get_attribute('href').strip() expected_url = reverse('projectbuilds', args=(self.default_project.id,)) msg = 'link on default project name should point to builds but was %s' % link_url @@ -198,7 +200,7 @@ class TestAllProjectsPage(SeleniumTestCase): # check the link for the other project selector = 'span[data-project-field="name"] a' - element = other_project_row.find_element_by_css_selector(selector) + element = other_project_row.find_element(By.CSS_SELECTOR, selector) link_url = element.get_attribute('href').strip() expected_url = reverse('project', args=(self.project.id,)) msg = 'link on project name should point to configuration but was %s' % link_url diff --git a/lib/toaster/tests/browser/test_builddashboard_page.py b/lib/toaster/tests/browser/test_builddashboard_page.py index efcd89b3..1afa4a4d 100644 --- a/lib/toaster/tests/browser/test_builddashboard_page.py +++ b/lib/toaster/tests/browser/test_builddashboard_page.py @@ -15,6 +15,8 @@ from tests.browser.selenium_helpers import SeleniumTestCase from orm.models import Project, Release, BitbakeVersion, Build, LogMessage from orm.models import Layer, Layer_Version, Recipe, CustomImageRecipe, Variable +from selenium.webdriver.common.by import By + class TestBuildDashboardPage(SeleniumTestCase): """ Tests for the build dashboard /build/X """ @@ -183,7 +185,7 @@ class TestBuildDashboardPage(SeleniumTestCase): found = False for element in message_elements: - log_message_text = element.find_element_by_tag_name('pre').text.strip() + log_message_text = element.find_element(By.TAG_NAME, 'pre').text.strip() text_matches = (log_message_text == expected_text) log_message_pk = element.get_attribute('data-log-message-id') @@ -213,7 +215,7 @@ class TestBuildDashboardPage(SeleniumTestCase): the WebElement modal match the list of text values in expected """ # labels containing the radio buttons we're testing for - labels = modal.find_elements_by_css_selector(".radio") + labels = modal.find_elements(By.CSS_SELECTOR,".radio") labels_text = [lab.text for lab in labels] self.assertEqual(len(labels_text), len(expected)) @@ -248,7 +250,7 @@ class TestBuildDashboardPage(SeleniumTestCase): selector = '[data-role="edit-custom-image-trigger"]' self.click(selector) - modal = self.driver.find_element_by_id('edit-custom-image-modal') + modal = self.driver.find_element(By.ID, 'edit-custom-image-modal') self.wait_until_visible("#edit-custom-image-modal") # recipes we expect to see in the edit custom image modal @@ -270,7 +272,7 @@ class TestBuildDashboardPage(SeleniumTestCase): selector = '[data-role="new-custom-image-trigger"]' self.click(selector) - modal = self.driver.find_element_by_id('new-custom-image-modal') + modal = self.driver.find_element(By.ID,'new-custom-image-modal') self.wait_until_visible("#new-custom-image-modal") # recipes we expect to see in the new custom image modal diff --git a/lib/toaster/tests/browser/test_most_recent_builds_states.py b/lib/toaster/tests/browser/test_most_recent_builds_states.py index 7844aaa3..a34a0928 100644 --- a/lib/toaster/tests/browser/test_most_recent_builds_states.py +++ b/lib/toaster/tests/browser/test_most_recent_builds_states.py @@ -6,7 +6,7 @@ # # Copyright (C) 2013-2016 Intel Corporation # - +import time from django.urls import reverse from django.utils import timezone from tests.browser.selenium_helpers import SeleniumTestCase @@ -14,6 +14,8 @@ from tests.browser.selenium_helpers_base import Wait from orm.models import Project, Build, Task, Recipe, Layer, Layer_Version from bldcontrol.models import BuildRequest +from selenium.webdriver.common.by import By + class TestMostRecentBuildsStates(SeleniumTestCase): """ Test states update correctly in most recent builds area """ @@ -62,7 +64,7 @@ class TestMostRecentBuildsStates(SeleniumTestCase): element = self.wait_until_visible(selector) bar_selector = '#recipes-parsed-percentage-bar-%s' % build.id - bar_element = element.find_element_by_css_selector(bar_selector) + bar_element = element.find_element(By.CSS_SELECTOR, bar_selector) self.assertEqual(bar_element.value_of_css_property('width'), '0px', 'recipe parse progress should be at 0') @@ -73,7 +75,7 @@ class TestMostRecentBuildsStates(SeleniumTestCase): self.get(url) element = self.wait_until_visible(selector) - bar_element = element.find_element_by_css_selector(bar_selector) + bar_element = element.find_element(By.CSS_SELECTOR, bar_selector) recipe_bar_updated = lambda driver: \ bar_element.get_attribute('style') == 'width: 50%;' msg = 'recipe parse progress bar should update to 50%' @@ -107,7 +109,7 @@ class TestMostRecentBuildsStates(SeleniumTestCase): element = self.wait_until_visible(selector) bar_selector = '#build-pc-done-bar-%s' % build.id - bar_element = element.find_element_by_css_selector(bar_selector) + bar_element = element.find_element(By.CSS_SELECTOR, bar_selector) task_bar_updated = lambda driver: \ bar_element.get_attribute('style') == 'width: 50%;' @@ -121,7 +123,7 @@ class TestMostRecentBuildsStates(SeleniumTestCase): self.get(url) element = self.wait_until_visible(selector) - bar_element = element.find_element_by_css_selector(bar_selector) + bar_element = element.find_element(By.CSS_SELECTOR, bar_selector) task_bar_updated = lambda driver: \ bar_element.get_attribute('style') == 'width: 100%;' msg = 'tasks progress bar should update to 100%' diff --git a/lib/toaster/tests/browser/test_new_custom_image_page.py b/lib/toaster/tests/browser/test_new_custom_image_page.py index 9906ae42..6361f403 100644 --- a/lib/toaster/tests/browser/test_new_custom_image_page.py +++ b/lib/toaster/tests/browser/test_new_custom_image_page.py @@ -6,6 +6,7 @@ # # SPDX-License-Identifier: GPL-2.0-only # +from bldcontrol.models import BuildEnvironment from django.urls import reverse from tests.browser.selenium_helpers import SeleniumTestCase @@ -18,6 +19,9 @@ class TestNewCustomImagePage(SeleniumTestCase): CUSTOM_IMAGE_NAME = 'roopa-doopa' def setUp(self): + BuildEnvironment.objects.get_or_create( + betype=BuildEnvironment.TYPE_LOCAL, + ) release = Release.objects.create( name='baz', bitbake_version=BitbakeVersion.objects.create(name='v1') diff --git a/lib/toaster/tests/browser/test_new_project_page.py b/lib/toaster/tests/browser/test_new_project_page.py index e20a1f68..f4b2708f 100644 --- a/lib/toaster/tests/browser/test_new_project_page.py +++ b/lib/toaster/tests/browser/test_new_project_page.py @@ -6,11 +6,13 @@ # # SPDX-License-Identifier: GPL-2.0-only # +import time from django.urls import reverse from tests.browser.selenium_helpers import SeleniumTestCase from selenium.webdriver.support.ui import Select from selenium.common.exceptions import InvalidElementStateException +from selenium.webdriver.common.by import By from orm.models import Project, Release, BitbakeVersion @@ -47,13 +49,14 @@ class TestNewProjectPage(SeleniumTestCase): url = reverse('newproject') self.get(url) - self.enter_text('#new-project-name', project_name) select = Select(self.find('#projectversion')) select.select_by_value(str(self.release.pk)) + time.sleep(1) self.click("#create-project-button") + time.sleep(2) # We should get redirected to the new project's page with the # notification at the top @@ -84,6 +87,12 @@ class TestNewProjectPage(SeleniumTestCase): select = Select(self.find('#projectversion')) select.select_by_value(str(self.release.pk)) + radio = self.driver.find_element(By.ID, 'type-new') + radio.click() + + self.click("#create-project-button") + time.sleep(2) + element = self.wait_until_visible('#hint-error-project-name') self.assertTrue(("Project names must be unique" in element.text), @@ -96,6 +105,7 @@ class TestNewProjectPage(SeleniumTestCase): except InvalidElementStateException: pass + time.sleep(2) self.assertTrue( (Project.objects.filter(name=project_name).count() == 1), "New project not found in database") diff --git a/lib/toaster/tests/browser/test_project_config_page.py b/lib/toaster/tests/browser/test_project_config_page.py index 944bcb26..7b21460e 100644 --- a/lib/toaster/tests/browser/test_project_config_page.py +++ b/lib/toaster/tests/browser/test_project_config_page.py @@ -11,6 +11,7 @@ from django.urls import reverse from tests.browser.selenium_helpers import SeleniumTestCase from orm.models import BitbakeVersion, Release, Project, ProjectVariable +from selenium.webdriver.common.by import By class TestProjectConfigsPage(SeleniumTestCase): """ Test data at /project/X/builds is displayed correctly """ @@ -66,7 +67,7 @@ class TestProjectConfigsPage(SeleniumTestCase): self.enter_text('#new-imagefs_types', imagefs_type) - checkboxes = self.driver.find_elements_by_xpath("//input[@class='fs-checkbox-fstypes']") + checkboxes = self.driver.find_elements(By.XPATH, "//input[@class='fs-checkbox-fstypes']") for checkbox in checkboxes: if checkbox.get_attribute("value") == "btrfs": @@ -95,7 +96,7 @@ class TestProjectConfigsPage(SeleniumTestCase): for checkbox in checkboxes: if checkbox.get_attribute("value") == "cpio": checkbox.click() - element = self.driver.find_element_by_id('new-imagefs_types') + element = self.driver.find_element(By.ID, 'new-imagefs_types') self.wait_until_visible('#new-imagefs_types') @@ -129,7 +130,7 @@ class TestProjectConfigsPage(SeleniumTestCase): 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.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') @@ -137,7 +138,7 @@ class TestProjectConfigsPage(SeleniumTestCase): 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.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') @@ -145,18 +146,18 @@ class TestProjectConfigsPage(SeleniumTestCase): 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.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') + 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.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') + 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') @@ -184,7 +185,7 @@ class TestProjectConfigsPage(SeleniumTestCase): 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.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') @@ -192,7 +193,7 @@ class TestProjectConfigsPage(SeleniumTestCase): 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.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') @@ -200,18 +201,18 @@ class TestProjectConfigsPage(SeleniumTestCase): 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.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') + 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.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') + 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') diff --git a/lib/toaster/tests/browser/test_toastertable_ui.py b/lib/toaster/tests/browser/test_toastertable_ui.py index e82d5ec6..e00c30a8 100644 --- a/lib/toaster/tests/browser/test_toastertable_ui.py +++ b/lib/toaster/tests/browser/test_toastertable_ui.py @@ -13,6 +13,7 @@ from django.urls import reverse from django.utils import timezone from tests.browser.selenium_helpers import SeleniumTestCase from orm.models import BitbakeVersion, Release, Project, Build +from selenium.webdriver.common.by import By class TestToasterTableUI(SeleniumTestCase): """ @@ -33,7 +34,7 @@ class TestToasterTableUI(SeleniumTestCase): table: WebElement for a ToasterTable """ selector = 'thead a.sorted' - heading = table.find_element_by_css_selector(selector) + heading = table.find_element(By.CSS_SELECTOR, selector) return heading.get_attribute('innerHTML').strip() def _get_datetime_from_cell(self, row, selector): @@ -45,7 +46,7 @@ class TestToasterTableUI(SeleniumTestCase): selector: CSS selector to use to find the cell containing the date time string """ - cell = row.find_element_by_css_selector(selector) + cell = row.find_element(By.CSS_SELECTOR, selector) cell_text = cell.get_attribute('innerHTML').strip() return datetime.strptime(cell_text, '%d/%m/%y %H:%M') @@ -105,7 +106,7 @@ class TestToasterTableUI(SeleniumTestCase): self.click('#checkbox-started_on') # sort by started_on column - links = table.find_elements_by_css_selector('th.started_on a') + links = table.find_elements(By.CSS_SELECTOR, 'th.started_on a') for link in links: if link.get_attribute('innerHTML').strip() == 'Started on': link.click() diff --git a/lib/toaster/tests/builds/test_core_image_min.py b/lib/toaster/tests/builds/test_core_image_min.py index 44b6cbec..9cdaa15f 100644 --- a/lib/toaster/tests/builds/test_core_image_min.py +++ b/lib/toaster/tests/builds/test_core_image_min.py @@ -26,6 +26,7 @@ class BuildCoreImageMinimal(BuildTest): def setUp(self): self.completed_build = self.build("core-image-minimal") + self.built = self.target_already_built("core-image-minimal") # Check if build name is unique - tc_id=795 def test_Build_Unique_Name(self): diff --git a/lib/toaster/tests/functional/functional_helpers.py b/lib/toaster/tests/functional/functional_helpers.py index 5c4ea717..c3191f66 100644 --- a/lib/toaster/tests/functional/functional_helpers.py +++ b/lib/toaster/tests/functional/functional_helpers.py @@ -16,6 +16,9 @@ import re from tests.browser.selenium_helpers_base import SeleniumTestCaseBase from tests.builds.buildtest import load_build_environment +from bldcontrol.models import BuildEnvironment +from selenium.webdriver.common.by import By +from selenium.common.exceptions import NoSuchElementException logger = logging.getLogger("toaster") @@ -30,6 +33,8 @@ class SeleniumFunctionalTestCase(SeleniumTestCaseBase): raise RuntimeError("Please initialise django with the tests settings: " \ "DJANGO_SETTINGS_MODULE='toastermain.settings_test'") + if BuildEnvironment.objects.count() == 0: + BuildEnvironment.objects.create(betype=BuildEnvironment.TYPE_LOCAL) load_build_environment() # start toaster @@ -74,8 +79,8 @@ class SeleniumFunctionalTestCase(SeleniumTestCaseBase): """ try: table_element = self.get_table_element(table_id) - element = table_element.find_element_by_link_text(link_text) - except self.NoSuchElementException: + element = table_element.find_element(By.LINK_TEXT, link_text) + except NoSuchElementException: print('no element found') raise return element @@ -85,8 +90,8 @@ class SeleniumFunctionalTestCase(SeleniumTestCaseBase): #return whole-table element element_xpath = "//*[@id='" + table_id + "']" try: - element = self.driver.find_element_by_xpath(element_xpath) - except self.NoSuchElementException: + element = self.driver.find_element(By.XPATH, element_xpath) + except NoSuchElementException: raise return element row = coordinate[0] @@ -95,8 +100,8 @@ class SeleniumFunctionalTestCase(SeleniumTestCaseBase): #return whole-row element element_xpath = "//*[@id='" + table_id + "']/tbody/tr[" + str(row) + "]" try: - element = self.driver.find_element_by_xpath(element_xpath) - except self.NoSuchElementException: + element = self.driver.find_element(By.XPATH, element_xpath) + except NoSuchElementException: return False return element #now we are looking for an element with specified X and Y @@ -104,7 +109,7 @@ class SeleniumFunctionalTestCase(SeleniumTestCaseBase): element_xpath = "//*[@id='" + table_id + "']/tbody/tr[" + str(row) + "]/td[" + str(column) + "]" try: - element = self.driver.find_element_by_xpath(element_xpath) - except self.NoSuchElementException: + element = self.driver.find_element(By.XPATH, element_xpath) + except NoSuchElementException: return False return element diff --git a/lib/toaster/tests/functional/test_functional_basic.py b/lib/toaster/tests/functional/test_functional_basic.py index 5683e387..067ad99a 100644 --- a/lib/toaster/tests/functional/test_functional_basic.py +++ b/lib/toaster/tests/functional/test_functional_basic.py @@ -10,6 +10,7 @@ import re from tests.functional.functional_helpers import SeleniumFunctionalTestCase from orm.models import Project +from selenium.webdriver.common.by import By class FuntionalTestBasic(SeleniumFunctionalTestCase): @@ -17,10 +18,10 @@ class FuntionalTestBasic(SeleniumFunctionalTestCase): def test_create_slenium_project(self): project_name = 'selenium-project' self.get('') - self.driver.find_element_by_link_text("To start building, create your first Toaster project").click() - self.driver.find_element_by_id("new-project-name").send_keys(project_name) - self.driver.find_element_by_id('projectversion').click() - self.driver.find_element_by_id("create-project-button").click() + self.driver.find_element(By.LINK_TEXT, "To start building, create your first Toaster project").click() + self.driver.find_element(By.ID, "new-project-name").send_keys(project_name) + self.driver.find_element(By.ID, 'projectversion').click() + self.driver.find_element(By.ID, "create-project-button").click() element = self.wait_until_visible('#project-created-notification') self.assertTrue(self.element_exists('#project-created-notification'),'Project creation notification not shown') self.assertTrue(project_name in element.text, @@ -35,77 +36,77 @@ class FuntionalTestBasic(SeleniumFunctionalTestCase): self.find_element_by_link_text_in_table('projectstable', 'selenium-project').click() self.assertTrue(self.element_exists('#config-nav'),'Configuration Tab does not exist') project_URL=self.get_URL() - self.driver.find_element_by_xpath('//a[@href="'+project_URL+'"]').click() + self.driver.find_element(By.XPATH, '//a[@href="'+project_URL+'"]').click() try: - self.driver.find_element_by_xpath("//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'customimages/"'+"]").click() - self.assertTrue(re.search("Custom images",self.driver.find_element_by_xpath("//div[@class='col-md-10']").text),'Custom images information is not loading properly') + self.driver.find_element(By.XPATH, "//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'customimages/"'+"]").click() + self.assertTrue(re.search("Custom images",self.driver.find_element(By.XPATH, "//div[@class='col-md-10']").text),'Custom images information is not loading properly') except: self.fail(msg='No Custom images tab available') try: - self.driver.find_element_by_xpath("//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'images/"'+"]").click() - self.assertTrue(re.search("Compatible image recipes",self.driver.find_element_by_xpath("//div[@class='col-md-10']").text),'The Compatible image recipes information is not loading properly') + self.driver.find_element(By.XPATH, "//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'images/"'+"]").click() + self.assertTrue(re.search("Compatible image recipes",self.driver.find_element(By.XPATH, "//div[@class='col-md-10']").text),'The Compatible image recipes information is not loading properly') except: self.fail(msg='No Compatible image tab available') try: - self.driver.find_element_by_xpath("//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'softwarerecipes/"'+"]").click() - self.assertTrue(re.search("Compatible software recipes",self.driver.find_element_by_xpath("//div[@class='col-md-10']").text),'The Compatible software recipe information is not loading properly') + self.driver.find_element(By.XPATH, "//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'softwarerecipes/"'+"]").click() + self.assertTrue(re.search("Compatible software recipes",self.driver.find_element(By.XPATH, "//div[@class='col-md-10']").text),'The Compatible software recipe information is not loading properly') except: self.fail(msg='No Compatible software recipe tab available') try: - self.driver.find_element_by_xpath("//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'machines/"'+"]").click() - self.assertTrue(re.search("Compatible machines",self.driver.find_element_by_xpath("//div[@class='col-md-10']").text),'The Compatible machine information is not loading properly') + self.driver.find_element(By.XPATH, "//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'machines/"'+"]").click() + self.assertTrue(re.search("Compatible machines",self.driver.find_element(By.XPATH, "//div[@class='col-md-10']").text),'The Compatible machine information is not loading properly') except: self.fail(msg='No Compatible machines tab available') try: - self.driver.find_element_by_xpath("//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'layers/"'+"]").click() - self.assertTrue(re.search("Compatible layers",self.driver.find_element_by_xpath("//div[@class='col-md-10']").text),'The Compatible layer information is not loading properly') + self.driver.find_element(By.XPATH, "//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'layers/"'+"]").click() + self.assertTrue(re.search("Compatible layers",self.driver.find_element(By.XPATH, "//div[@class='col-md-10']").text),'The Compatible layer information is not loading properly') except: self.fail(msg='No Compatible layers tab available') try: - self.driver.find_element_by_xpath("//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'configuration"'+"]").click() - self.assertTrue(re.search("Bitbake variables",self.driver.find_element_by_xpath("//div[@class='col-md-10']").text),'The Bitbake variables information is not loading properly') + self.driver.find_element(By.XPATH, "//*[@id='config-nav']/ul/li/a[@href="+'"'+project_URL+'configuration"'+"]").click() + self.assertTrue(re.search("Bitbake variables",self.driver.find_element(By.XPATH, "//div[@class='col-md-10']").text),'The Bitbake variables information is not loading properly') except: self.fail(msg='No Bitbake variables tab available') # testcase (1516) def test_review_configuration_information(self): self.get('') - self.driver.find_element_by_xpath("//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() + self.driver.find_element(By.XPATH, "//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() self.wait_until_visible('#projectstable') self.find_element_by_link_text_in_table('projectstable', 'selenium-project').click() project_URL=self.get_URL() try: self.assertTrue(self.element_exists('#machine-section'),'Machine section for the project configuration page does not exist') - self.assertTrue(re.search("qemux86",self.driver.find_element_by_xpath("//span[@id='project-machine-name']").text),'The machine type is not assigned') - self.driver.find_element_by_xpath("//span[@id='change-machine-toggle']").click() + self.assertTrue(re.search("qemux86",self.driver.find_element(By.XPATH, "//span[@id='project-machine-name']").text),'The machine type is not assigned') + self.driver.find_element(By.XPATH, "//span[@id='change-machine-toggle']").click() self.wait_until_visible('#select-machine-form') self.wait_until_visible('#cancel-machine-change') - self.driver.find_element_by_xpath("//form[@id='select-machine-form']/a[@id='cancel-machine-change']").click() + self.driver.find_element(By.XPATH, "//form[@id='select-machine-form']/a[@id='cancel-machine-change']").click() except: self.fail(msg='The machine information is wrong in the configuration page') try: - self.driver.find_element_by_id('no-most-built') + self.driver.find_element(By.ID, 'no-most-built') except: self.fail(msg='No Most built information in project detail page') try: - self.assertTrue(re.search("Yocto Project master",self.driver.find_element_by_xpath("//span[@id='project-release-title']").text),'The project release is not defined') + self.assertTrue(re.search("Yocto Project master",self.driver.find_element(By.XPATH, "//span[@id='project-release-title']").text),'The project release is not defined') except: self.fail(msg='No project release title information in project detail page') try: - self.driver.find_element_by_xpath("//div[@id='layer-container']") - self.assertTrue(re.search("3",self.driver.find_element_by_id("project-layers-count").text),'There should be 3 layers listed in the layer count') - layer_list = self.driver.find_element_by_id("layers-in-project-list") - layers = layer_list.find_elements_by_tag_name("li") + self.driver.find_element(By.XPATH, "//div[@id='layer-container']") + self.assertTrue(re.search("3",self.driver.find_element(By.ID, "project-layers-count").text),'There should be 3 layers listed in the layer count') + layer_list = self.driver.find_element(By.ID, "layers-in-project-list") + layers = layer_list.find_elements(By.TAG_NAME, "li") for layer in layers: if re.match ("openembedded-core",layer.text): print ("openembedded-core layer is a default layer in the project configuration") @@ -121,60 +122,61 @@ class FuntionalTestBasic(SeleniumFunctionalTestCase): # testcase (1517) def test_verify_machine_information(self): self.get('') - self.driver.find_element_by_xpath("//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() + self.driver.find_element(By.XPATH, "//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() self.wait_until_visible('#projectstable') self.find_element_by_link_text_in_table('projectstable', 'selenium-project').click() try: self.assertTrue(self.element_exists('#machine-section'),'Machine section for the project configuration page does not exist') - self.assertTrue(re.search("qemux86",self.driver.find_element_by_id("project-machine-name").text),'The machine type is not assigned') - self.driver.find_element_by_id("change-machine-toggle").click() + self.assertTrue(re.search("qemux86",self.driver.find_element(By.ID, "project-machine-name").text),'The machine type is not assigned') + self.driver.find_element(By.ID, "change-machine-toggle").click() self.wait_until_visible('#select-machine-form') self.wait_until_visible('#cancel-machine-change') - self.driver.find_element_by_id("cancel-machine-change").click() + self.driver.find_element(By.ID, "cancel-machine-change").click() except: self.fail(msg='The machine information is wrong in the configuration page') # testcase (1518) def test_verify_most_built_recipes_information(self): self.get('') - self.driver.find_element_by_xpath("//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() + self.driver.find_element(By.XPATH, "//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() + self.wait_until_visible('#projectstable') self.find_element_by_link_text_in_table('projectstable', 'selenium-project').click() project_URL=self.get_URL() try: - self.assertTrue(re.search("You haven't built any recipes yet",self.driver.find_element_by_id("no-most-built").text),'Default message of no builds is not present') - self.driver.find_element_by_xpath("//div[@id='no-most-built']/p/a[@href="+'"'+project_URL+'images/"'+"]").click() - self.assertTrue(re.search("Compatible image recipes",self.driver.find_element_by_xpath("//div[@class='col-md-10']").text),'The Choose a recipe to build link is not working properly') + self.assertTrue(re.search("You haven't built any recipes yet",self.driver.find_element(By.ID, "no-most-built").text),'Default message of no builds is not present') + self.driver.find_element(By.XPATH, "//div[@id='no-most-built']/p/a[@href="+'"'+project_URL+'images/"'+"]").click() + self.assertTrue(re.search("Compatible image recipes",self.driver.find_element(By.XPATH, "//div[@class='col-md-10']").text),'The Choose a recipe to build link is not working properly') except: self.fail(msg='No Most built information in project detail page') # testcase (1519) def test_verify_project_release_information(self): self.get('') - self.driver.find_element_by_xpath("//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() + self.driver.find_element(By.XPATH, "//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() self.wait_until_visible('#projectstable') self.find_element_by_link_text_in_table('projectstable', 'selenium-project').click() try: - self.assertTrue(re.search("Yocto Project master",self.driver.find_element_by_id("project-release-title").text),'The project release is not defined') + self.assertTrue(re.search("Yocto Project master",self.driver.find_element(By.ID, "project-release-title").text),'The project release is not defined') except: self.fail(msg='No project release title information in project detail page') # testcase (1520) def test_verify_layer_information(self): self.get('') - self.driver.find_element_by_xpath("//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() + self.driver.find_element(By.XPATH, "//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() self.wait_until_visible('#projectstable') self.find_element_by_link_text_in_table('projectstable', 'selenium-project').click() project_URL=self.get_URL() try: - self.driver.find_element_by_xpath("//div[@id='layer-container']") - self.assertTrue(re.search("3",self.driver.find_element_by_id("project-layers-count").text),'There should be 3 layers listed in the layer count') - layer_list = self.driver.find_element_by_id("layers-in-project-list") - layers = layer_list.find_elements_by_tag_name("li") + self.driver.find_element(By.XPATH, "//div[@id='layer-container']") + self.assertTrue(re.search("3",self.driver.find_element(By.ID, "project-layers-count").text),'There should be 3 layers listed in the layer count') + layer_list = self.driver.find_element(By.ID, "layers-in-project-list") + layers = layer_list.find_element(By.TAG_NAME, "li") for layer in layers: if re.match ("openembedded-core",layer.text): @@ -186,43 +188,43 @@ class FuntionalTestBasic(SeleniumFunctionalTestCase): else: self.fail(msg='default layers are missing from the project configuration') - self.driver.find_element_by_xpath("//input[@id='layer-add-input']") - self.driver.find_element_by_xpath("//button[@id='add-layer-btn']") - self.driver.find_element_by_xpath("//div[@id='layer-container']/form[@class='form-inline']/p/a[@id='view-compatible-layers']") - self.driver.find_element_by_xpath("//div[@id='layer-container']/form[@class='form-inline']/p/a[@href="+'"'+project_URL+'importlayer"'+"]") + self.driver.find_element(By.XPATH, "//input[@id='layer-add-input']") + self.driver.find_element(By.XPATH, "//button[@id='add-layer-btn']") + self.driver.find_element(By.XPATH, "//div[@id='layer-container']/form[@class='form-inline']/p/a[@id='view-compatible-layers']") + self.driver.find_element(By.XPATH, "//div[@id='layer-container']/form[@class='form-inline']/p/a[@href="+'"'+project_URL+'importlayer"'+"]") except: self.fail(msg='No Layer information in project detail page') # testcase (1521) def test_verify_project_detail_links(self): self.get('') - self.driver.find_element_by_xpath("//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() + self.driver.find_element(By.XPATH, "//div[@id='global-nav']/ul/li/a[@href="+'"'+'/toastergui/projects/'+'"'+"]").click() self.wait_until_visible('#projectstable') self.find_element_by_link_text_in_table('projectstable', 'selenium-project').click() project_URL=self.get_URL() - self.driver.find_element_by_xpath("//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li[@id='topbar-configuration-tab']/a[@href="+'"'+project_URL+'"'+"]").click() - self.assertTrue(re.search("Configuration",self.driver.find_element_by_xpath("//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li[@id='topbar-configuration-tab']/a[@href="+'"'+project_URL+'"'+"]").text), 'Configuration tab in project topbar is misspelled') + self.driver.find_element(By.XPATH, "//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li[@id='topbar-configuration-tab']/a[@href="+'"'+project_URL+'"'+"]").click() + self.assertTrue(re.search("Configuration",self.driver.find_element(By.XPATH, "//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li[@id='topbar-configuration-tab']/a[@href="+'"'+project_URL+'"'+"]").text), 'Configuration tab in project topbar is misspelled') try: - self.driver.find_element_by_xpath("//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'builds/"'+"]").click() - self.assertTrue(re.search("Builds",self.driver.find_element_by_xpath("//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'builds/"'+"]").text), 'Builds tab in project topbar is misspelled') - self.driver.find_element_by_xpath("//div[@id='empty-state-projectbuildstable']") + self.driver.find_element(By.XPATH, "//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'builds/"'+"]").click() + self.assertTrue(re.search("Builds",self.driver.find_element(By.XPATH, "//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'builds/"'+"]").text), 'Builds tab in project topbar is misspelled') + self.driver.find_element(By.XPATH, "//div[@id='empty-state-projectbuildstable']") except: self.fail(msg='Builds tab information is not present') try: - self.driver.find_element_by_xpath("//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'importlayer"'+"]").click() - self.assertTrue(re.search("Import layer",self.driver.find_element_by_xpath("//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'importlayer"'+"]").text), 'Import layer tab in project topbar is misspelled') - self.driver.find_element_by_xpath("//fieldset[@id='repo-select']") - self.driver.find_element_by_xpath("//fieldset[@id='git-repo']") + self.driver.find_element(By.XPATH, "//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'importlayer"'+"]").click() + self.assertTrue(re.search("Import layer",self.driver.find_element(By.XPATH, "//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'importlayer"'+"]").text), 'Import layer tab in project topbar is misspelled') + self.driver.find_element(By.XPATH, "//fieldset[@id='repo-select']") + self.driver.find_element(By.XPATH, "//fieldset[@id='git-repo']") except: self.fail(msg='Import layer tab not loading properly') try: - self.driver.find_element_by_xpath("//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'newcustomimage/"'+"]").click() - self.assertTrue(re.search("New custom image",self.driver.find_element_by_xpath("//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'newcustomimage/"'+"]").text), 'New custom image tab in project topbar is misspelled') - self.assertTrue(re.search("Select the image recipe you want to customise",self.driver.find_element_by_xpath("//div[@class='col-md-12']/h2").text),'The new custom image tab is not loading correctly') + self.driver.find_element(By.XPATH, "//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'newcustomimage/"'+"]").click() + self.assertTrue(re.search("New custom image",self.driver.find_element(By.XPATH, "//div[@id='project-topbar']/ul[@class='nav nav-tabs']/li/a[@href="+'"'+project_URL+'newcustomimage/"'+"]").text), 'New custom image tab in project topbar is misspelled') + self.assertTrue(re.search("Select the image recipe you want to customise",self.driver.find_element(By.XPATH, "//div[@class='col-md-12']/h2").text),'The new custom image tab is not loading correctly') except: self.fail(msg='New custom image tab not loading properly') diff --git a/lib/toaster/tests/toaster-tests-requirements.txt b/lib/toaster/tests/toaster-tests-requirements.txt index 4f9fcc46..f30ac070 100644 --- a/lib/toaster/tests/toaster-tests-requirements.txt +++ b/lib/toaster/tests/toaster-tests-requirements.txt @@ -1 +1 @@ -selenium==2.49.2 +selenium>=4.13.0 diff --git a/lib/toaster/tests/views/test_views.py b/lib/toaster/tests/views/test_views.py index 735d596b..f962e762 100644 --- a/lib/toaster/tests/views/test_views.py +++ b/lib/toaster/tests/views/test_views.py @@ -19,6 +19,7 @@ from orm.models import Layer_Version, Recipe from orm.models import CustomImageRecipe from orm.models import CustomImagePackage +from bldcontrol.models import BuildEnvironment import inspect import toastergui @@ -45,6 +46,9 @@ class ViewTests(TestCase): self.cust_package = CustomImagePackage.objects.first() self.package = Package.objects.first() self.lver = Layer_Version.objects.first() + if BuildEnvironment.objects.count() == 0: + BuildEnvironment.objects.create(betype=BuildEnvironment.TYPE_LOCAL) + def test_get_base_call_returns_html(self): """Basic test for all-projects view""" diff --git a/lib/toaster/toastergui/widgets.py b/lib/toaster/toastergui/widgets.py index 53696912..6e87285c 100644 --- a/lib/toaster/toastergui/widgets.py +++ b/lib/toaster/toastergui/widgets.py @@ -305,6 +305,7 @@ class ToasterTable(TemplateView): self.setup_columns(**kwargs) + self.apply_orderby('pk') if search: self.apply_search(search) if filters: