diff --git a/l10n_CM/run_l10n.py b/l10n_CM/run_l10n.py index ad4ab8afa..82973acc8 100644 --- a/l10n_CM/run_l10n.py +++ b/l10n_CM/run_l10n.py @@ -98,6 +98,13 @@ "zalando", "zara", "zooplus", + "zara", + "cocolita", + "torfs", + "standaardboekhandel", + "douglas", + "brico", + "toychamp", } loaded_valid_sites = valid_l10n_mappings().keys() diff --git a/modules/browser_object_navigation.py b/modules/browser_object_navigation.py index b64aad288..ea8201cc7 100644 --- a/modules/browser_object_navigation.py +++ b/modules/browser_object_navigation.py @@ -598,10 +598,17 @@ def open_bookmark_in_new_tab_via_context_menu( Argument: bookmark_title: The title of the bookmark to open """ - # Right-click the bookmark and open it in new tabe via context menu item + # Right-click the bookmark to make the menu appear self.panel_ui.element_clickable("bookmark-by-title", labels=[bookmark_title]) self.panel_ui.context_click("bookmark-by-title", labels=[bookmark_title]) - self.context_menu.click_on("context-menu-toolbar-open-in-new-tab") + + # Find the menu item we want to click + # We use .fetch() here to get the element without clicking it yet + menu_item = self.context_menu.fetch("context-menu-toolbar-open-in-new-tab") + + # Use ActionChains to perform a more reliable click + actions = ActionChains(self.driver) + actions.move_to_element(menu_item).click().perform() return self diff --git a/modules/data/context_menu.components.json b/modules/data/context_menu.components.json index e8847b47d..e9afb106e 100644 --- a/modules/data/context_menu.components.json +++ b/modules/data/context_menu.components.json @@ -109,6 +109,12 @@ "groups": [] }, + "context-menu-move-tab-to-start": { + "selectorData": "menuitem[data-l10n-id='move-to-start']", + "strategy": "css", + "groups": [] + }, + "context-menu-open-link-in-tab": { "selectorData": "context-openlinkintab", "strategy": "id", diff --git a/modules/page_base.py b/modules/page_base.py index e1d4fca55..c231c9522 100644 --- a/modules/page_base.py +++ b/modules/page_base.py @@ -305,6 +305,22 @@ def get_element( cache_name = f"{name}{labelscode}" if cache_name not in self.elements: self.elements[cache_name] = deepcopy(self.elements[name]) + # FIX: Check for doNotCache BEFORE trying to use cached elements + if ( + not multiple + and "doNotCache" + not in self.elements[cache_name]["groups"] # ADD THIS CHECK + and "seleniumObject" in self.elements[cache_name] + ): + # no caching for multiples + cached_element = self.elements[cache_name]["seleniumObject"] + try: + self.instawait.until_not(EC.staleness_of(cached_element)) + logging.info(f"Returned {cache_name} from object cache!") + return self.elements[cache_name]["seleniumObject"] + except (TimeoutError, TimeoutException): + # Because we have a timeout of 0, this should not cause delays + pass if multiple: logging.info(f"Multiples: Not caching {cache_name}...") if not multiple and "seleniumObject" in self.elements[cache_name]: diff --git a/tests/tabs/test_change_position_of_pinned_tabs.py b/tests/tabs/test_change_position_of_pinned_tabs.py new file mode 100644 index 000000000..f24d15848 --- /dev/null +++ b/tests/tabs/test_change_position_of_pinned_tabs.py @@ -0,0 +1,72 @@ +import logging + +import pytest +from selenium.webdriver import Firefox + +from modules.browser_object import ContextMenu, TabBar + + +@pytest.fixture() +def test_case(): + return "134723" + + +def test_change_position_of_pinned_tabs(driver: Firefox): + tabs = TabBar(driver) + tab_context_menu = ContextMenu(driver) + + tab_titles = [] + url_list = ["about:logo", "about:robots", "https://mozilla.org"] + + driver.get(url_list[0]) + tab_titles.append(driver.title) + + # Open 3 tabs + for i in range(1, len(url_list)): + tabs.new_tab_by_button() + driver.switch_to.window(driver.window_handles[-1]) + driver.get(url_list[i]) + tab_titles.append(driver.title) + + # Specific tabs we want to work with + robot_title = tab_titles[1] + mozilla_title = tab_titles[2] + + # Pin the 'Robots' tab by its title + driver.switch_to.window(driver.window_handles[0]) + robot_tab = tabs.get_tab(robot_title) + assert robot_tab is not None, "Robot tab should exist" + tabs.context_click(robot_tab) + tab_context_menu.click_and_hide_menu("context-menu-pin-tab") + pinned_tab_one = tabs.get_tab(robot_title) + assert tabs.is_pinned(pinned_tab_one) + + # Pin the 'Mozilla' tab by its title + mozilla_tab = tabs.get_tab(mozilla_title) + assert mozilla_tab is not None, "Mozilla tab should exist" + tabs.context_click(mozilla_tab) + tab_context_menu.click_and_hide_menu("context-menu-pin-tab") + pinned_tab_two = tabs.get_tab(mozilla_title) + assert tabs.is_pinned(pinned_tab_two) + + # Move second pinned tab to the left + tabs.context_click(pinned_tab_two) + tab_context_menu.click_and_hide_menu("context-menu-move-tab-to-start") + # Click-and-hide won't hide the parent popup + tabs.hide_popup("tabContextMenu") + + # Get the titles for each of the rearranged pinned tabs + driver.switch_to.window(driver.window_handles[0]) + new_pinned_tab_one_title = driver.title + logging.info("Tab title: %s", new_pinned_tab_one_title) + + driver.switch_to.window(driver.window_handles[1]) + new_pinned_tab_two_title = driver.title + logging.info("Tab title: %s", new_pinned_tab_two_title) + + assert "Mozilla" in new_pinned_tab_one_title, ( + "Mozilla should now be the first pinned tab" + ) + assert "Gort!" in new_pinned_tab_two_title, ( + "Robot should now be the second pinned tab" + ) diff --git a/tests/theme_and_toolbar/test_customize_themes_and_redirect.py b/tests/theme_and_toolbar/test_customize_themes_and_redirect.py index 4512faba6..a732c01ad 100644 --- a/tests/theme_and_toolbar/test_customize_themes_and_redirect.py +++ b/tests/theme_and_toolbar/test_customize_themes_and_redirect.py @@ -1,5 +1,6 @@ import pytest from selenium.webdriver import Firefox + from modules.browser_object import Navigation, PanelUi from modules.page_object import AboutAddons @@ -11,7 +12,7 @@ def test_case(): THEMES: dict[str, list[str]] = { "firefox-compact-dark_mozilla_org-heading": [ - "rgb(43, 42, 51)", # classic darker tone + "rgb(43, 42, 51)", # classic darker tone "rgb(143, 143, 148)", # focused dark "rgb(120, 119, 126)", # dark without focus ], @@ -82,7 +83,9 @@ def test_redirect_to_addons(driver: Firefox) -> None: @pytest.mark.parametrize("theme_name", list(THEMES.keys())) -def test_activate_theme_background_matches_expected(driver: Firefox, theme_name: str) -> None: +def test_activate_theme_background_matches_expected( + driver: Firefox, theme_name: str +) -> None: """ C118173: Ensure that activating each theme in about:addons applies the expected background color. Handles Developer Edition vs standard Firefox defaults. @@ -100,9 +103,7 @@ def test_activate_theme_background_matches_expected(driver: Firefox, theme_name: if theme_name == "firefox-compact-light_mozilla_org-heading": pytest.skip("Compact Light is default on Firefox, skipping.") - current_bg = abt_addons.activate_theme( - nav, theme_name, "", perform_assert=False - ) + current_bg = abt_addons.activate_theme(nav, theme_name, "", perform_assert=False) expected_list = THEMES[theme_name] assert any(colors_match(current_bg, exp) for exp in expected_list), ( diff --git a/tests/theme_and_toolbar/test_installed_theme_enabled.py b/tests/theme_and_toolbar/test_installed_theme_enabled.py index 3116b59df..ec39cc802 100644 --- a/tests/theme_and_toolbar/test_installed_theme_enabled.py +++ b/tests/theme_and_toolbar/test_installed_theme_enabled.py @@ -12,7 +12,9 @@ def test_case(): return "118174" -MAC_GHA: bool = environ.get("GITHUB_ACTIONS") == "true" and sys.platform.startswith("darwin") +MAC_GHA: bool = environ.get("GITHUB_ACTIONS") == "true" and sys.platform.startswith( + "darwin" +) AMO_HOST: str = "addons.mozilla.org" AMO_THEMES_PATH: str = "firefox/themes" @@ -44,7 +46,9 @@ def test_installed_theme_enabled(driver: Firefox) -> None: about_addons.choose_sidebar_option("theme") # Capture currently enabled theme title - starting_theme = about_addons.get_element("enabled-theme-title").get_attribute("innerText") + starting_theme = about_addons.get_element("enabled-theme-title").get_attribute( + "innerText" + ) # Go to AMO and install a recommended theme (POM encapsulates waits and flows) AmoThemes(driver).open().install_recommended_theme()