diff --git a/manual/tests/test_code_tabs_sql_json.py b/manual/tests/test_code_tabs_sql_json.py new file mode 100644 index 0000000..e3c2f77 --- /dev/null +++ b/manual/tests/test_code_tabs_sql_json.py @@ -0,0 +1,150 @@ +import pytest +import time +from selenium.webdriver.common.by import By +from core.base_test import BaseTest + +OS_KEYWORDS = [ + 'Ubuntu', 'Debian', 'Centos', 'RHEL', 'MacOS', + 'Windows', 'Docker', 'Kubernetes', 'Alma', 'Amazon', 'Oracle', 'Mint', +] + + +@pytest.mark.usefixtures("setup_driver") +class TestCodeTabsSqlJson(BaseTest): + """Tests for SQL/HTTP/PHP code tab switching in documentation examples.""" + + PAGE_URL = "https://manual.manticoresearch.com/Quick_start_guide" + + def _find_code_tab_blocks(self, tab_names): + """Find all visible code lang-sel blocks containing specified tab names. + + Returns a list of WebElements. Excludes OS-related tab blocks. + """ + blocks = self.driver.find_elements(By.CSS_SELECTOR, "div.lang-sel") + result = [] + for block in blocks: + example = block.find_element( + By.XPATH, "./ancestor::div[contains(@class, 'example')]" + ) + if not example.is_displayed(): + continue + tabs = block.find_elements( + By.CSS_SELECTOR, "ul.lang-tabs li span.lang-text" + ) + tab_texts = [t.get_attribute("textContent").strip() for t in tabs] + if any(kw in text for kw in OS_KEYWORDS for text in tab_texts): + continue + if all(name in tab_texts for name in tab_names): + result.append(block) + return result + + def _find_code_tab_block(self, tab_names): + """Find the first visible code lang-sel block with specified tabs.""" + blocks = self._find_code_tab_blocks(tab_names) + if not blocks: + pytest.fail(f"Code tab block with tabs {tab_names} not found") + return blocks[0] + + def _get_visible_body_text(self, block): + """Get text of the currently visible example-body.""" + example = block.find_element( + By.XPATH, "./ancestor::div[contains(@class, 'example')]" + ) + bodies = example.find_elements(By.CSS_SELECTOR, ".example-body") + for body in bodies: + if body.is_displayed(): + return body.text.strip() + return "" + + def _get_active_tab_text(self, block): + """Get the text of the currently active tab.""" + active = block.find_element( + By.CSS_SELECTOR, "li.active span.lang-text" + ) + return active.get_attribute("textContent").strip() + + def _click_tab(self, block, text): + """Click a tab by its text content.""" + tabs = block.find_elements(By.CSS_SELECTOR, "ul.lang-tabs li") + for tab in tabs: + span = tab.find_element(By.CSS_SELECTOR, "span.lang-text") + if span.get_attribute("textContent").strip() == text: + tab.click() + time.sleep(2) + return + pytest.fail(f"Tab '{text}' not found in block") + + def test_default_tab_is_sql(self): + """Verify that SQL is the default active tab in code examples.""" + self.driver.get(self.PAGE_URL) + time.sleep(2) + + block = self._find_code_tab_block(["SQL", "HTTP"]) + active = self._get_active_tab_text(block) + assert active == "SQL", f"Default active tab should be 'SQL', got: '{active}'" + + @pytest.mark.parametrize("tab_name", ["HTTP", "PHP", "Python"]) + def test_switch_to_tab(self, tab_name): + """Verify switching to a specific tab activates it and shows different content.""" + self.driver.get(self.PAGE_URL) + time.sleep(2) + + block = self._find_code_tab_block(["SQL", tab_name]) + + self._click_tab(block, "SQL") + sql_content = self._get_visible_body_text(block) + + self._click_tab(block, tab_name) + + active = self._get_active_tab_text(block) + assert active == tab_name, f"Active tab should be '{tab_name}', got: '{active}'" + + content = self._get_visible_body_text(block) + assert content, f"{tab_name} tab should have visible content" + assert content != sql_content, f"{tab_name} content should differ from SQL content" + + def test_tab_content_changes_on_switch(self): + """Verify that content changes when switching tabs and restores when switching back.""" + self.driver.get(self.PAGE_URL) + time.sleep(2) + + block = self._find_code_tab_block(["SQL", "HTTP"]) + + self._click_tab(block, "SQL") + sql_content = self._get_visible_body_text(block) + + self._click_tab(block, "HTTP") + http_content = self._get_visible_body_text(block) + + self._click_tab(block, "SQL") + sql_again = self._get_visible_body_text(block) + + assert sql_content != http_content, \ + "SQL and HTTP content should be different" + assert sql_content == sql_again, \ + "SQL content should be the same after switching back" + + def test_global_tab_sync(self): + """Verify that switching a code tab in one block syncs all code blocks. + + The documentation site syncs tab selection globally — switching to HTTP + in one block should switch all blocks to HTTP. + """ + self.driver.get(self.PAGE_URL) + time.sleep(2) + + code_blocks = self._find_code_tab_blocks(["SQL", "HTTP"]) + if len(code_blocks) < 2: + pytest.skip("Need at least 2 visible SQL/HTTP code blocks") + + block1, block2 = code_blocks[0], code_blocks[1] + + self._click_tab(block1, "SQL") + assert self._get_active_tab_text(block1) == "SQL" + + # Switch block1 to HTTP — block2 should sync automatically + self._click_tab(block1, "HTTP") + + active2 = self._get_active_tab_text(block2) + assert active2 == "HTTP", \ + f"Tab sync: block2 should also switch to HTTP, got: '{active2}'" diff --git a/manual/tests/test_language_switcher.py b/manual/tests/test_language_switcher.py new file mode 100644 index 0000000..3cf0dc2 --- /dev/null +++ b/manual/tests/test_language_switcher.py @@ -0,0 +1,91 @@ +import pytest +import time +from selenium.webdriver.common.by import By +from selenium.webdriver.support.ui import Select, WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from core.base_test import BaseTest + + +@pytest.mark.usefixtures("setup_driver") +class TestLanguageSwitcher(BaseTest): + """Tests for language switching functionality on the documentation site.""" + + BASE_URL = "https://manual.manticoresearch.com/" + + def test_switch_to_russian(self): + """Verify switching language to Russian changes content and URL.""" + self.driver.get(self.BASE_URL) + time.sleep(2) + + select = Select(self.driver.find_element(By.ID, "language-select")) + select.select_by_value("ru") + time.sleep(2) + + assert "/ru/" in self.driver.current_url, \ + f"URL should contain '/ru/', got: {self.driver.current_url}" + + h1 = self.driver.find_element(By.TAG_NAME, "h1") + assert h1.text == "Введение", \ + f"H1 should be 'Введение', got: '{h1.text}'" + + + def test_switch_to_chinese(self): + """Verify switching language to Chinese changes content and URL.""" + self.driver.get(self.BASE_URL) + time.sleep(2) + + select = Select(self.driver.find_element(By.ID, "language-select")) + select.select_by_value("zh") + time.sleep(2) + + assert "/zh/" in self.driver.current_url, \ + f"URL should contain '/zh/', got: {self.driver.current_url}" + + + def test_switch_back_to_english(self): + """Verify switching from Russian back to English restores content.""" + self.driver.get(self.BASE_URL) + time.sleep(2) + + # Switch to Russian first + select = Select(self.driver.find_element(By.ID, "language-select")) + select.select_by_value("ru") + time.sleep(2) + + assert "/ru/" in self.driver.current_url + + # Switch back to English + select = Select(self.driver.find_element(By.ID, "language-select")) + select.select_by_value("") + time.sleep(2) + + assert "/ru/" not in self.driver.current_url, \ + f"URL should not contain '/ru/' after switching back, got: {self.driver.current_url}" + + h1 = self.driver.find_element(By.TAG_NAME, "h1") + assert h1.text == "Introduction", \ + f"H1 should be 'Introduction', got: '{h1.text}'" + + + def test_language_cookie_persists(self): + """Verify that language selection is saved in cookie.""" + self.driver.get(self.BASE_URL) + time.sleep(2) + + select = Select(self.driver.find_element(By.ID, "language-select")) + select.select_by_value("ru") + time.sleep(2) + + cookies = {c['name']: c['value'] for c in self.driver.get_cookies()} + assert cookies.get('selected-language') == 'ru', \ + f"Cookie 'selected-language' should be 'ru', got: {cookies.get('selected-language')}" + + # Navigate to another page — language should persist + self.driver.get("https://manual.manticoresearch.com/ru/Starting_the_server/Linux") + time.sleep(2) + + select_after = Select(self.driver.find_element(By.ID, "language-select")) + selected_option = select_after.first_selected_option + assert selected_option.get_attribute("value") == "ru", \ + f"Language selector should still be 'ru', got: '{selected_option.get_attribute('value')}'" + diff --git a/manual/tests/test_os_tabs_installation.py b/manual/tests/test_os_tabs_installation.py new file mode 100644 index 0000000..8fbc6a0 --- /dev/null +++ b/manual/tests/test_os_tabs_installation.py @@ -0,0 +1,153 @@ +import pytest +import time +from selenium.webdriver.common.by import By +from selenium.webdriver.support.ui import WebDriverWait +from selenium.webdriver.support import expected_conditions as EC +from core.base_test import BaseTest + + +@pytest.mark.usefixtures("setup_driver") +class TestOsTabsInstallation(BaseTest): + """Tests for OS tab switching on the Installation page.""" + + INSTALL_URL = "https://manual.manticoresearch.com/Installation/Installation" + + def _get_tab_block(self): + """Find the OS tabs block on the Installation page.""" + self.driver.get(self.INSTALL_URL) + time.sleep(2) + + # Find the lang-sel block that contains OS tabs (RHEL, Debian, etc.) + blocks = self.driver.find_elements(By.CSS_SELECTOR, "div.lang-sel") + for block in blocks: + tabs = block.find_elements(By.CSS_SELECTOR, "li span.lang-text") + tab_texts = [t.get_attribute("textContent").strip() for t in tabs] + if any("RHEL" in t for t in tab_texts): + return block + pytest.fail("OS tabs block not found on Installation page") + + def _get_visible_body_text(self, block): + """Get text content of the currently visible example-body.""" + example = block.find_element(By.XPATH, "./ancestor::div[contains(@class, 'example')]") + bodies = example.find_elements(By.CSS_SELECTOR, ".example-body") + for body in bodies: + if body.is_displayed(): + return body.text.strip() + return "" + + def _get_active_tab_text(self, block): + """Get the text of the currently active tab.""" + active_li = block.find_element(By.CSS_SELECTOR, "li.active span.lang-text") + return active_li.get_attribute("textContent").strip() + + def _click_tab(self, block, tab_text): + """Click a tab by its text content.""" + old_content = self._get_visible_body_text(block) + tabs = block.find_elements(By.CSS_SELECTOR, "li") + for tab in tabs: + span = tab.find_element(By.CSS_SELECTOR, "span.lang-text") + if span.get_attribute("textContent").strip() == tab_text: + self.driver.execute_script("arguments[0].click();", tab) + # Wait for content to change (up to 5 seconds) + for _ in range(10): + time.sleep(0.5) + new_content = self._get_visible_body_text(block) + if new_content != old_content: + break + return + pytest.fail(f"Tab '{tab_text}' not found") + + def test_default_tab_is_rhel(self): + """Verify that RHEL tab is active by default.""" + block = self._get_tab_block() + + active = self._get_active_tab_text(block) + assert "RHEL" in active, \ + f"Default active tab should contain 'RHEL', got: '{active}'" + + content = self._get_visible_body_text(block) + assert "yum install" in content, \ + f"RHEL tab should show yum install command, got: '{content[:100]}'" + + + def test_switch_to_debian(self): + """Verify switching to Debian tab shows apt/wget commands.""" + block = self._get_tab_block() + + self._click_tab(block, "Debian, Ubuntu, Mint") + + active = self._get_active_tab_text(block) + assert "Debian" in active, \ + f"Active tab should contain 'Debian', got: '{active}'" + + content = self._get_visible_body_text(block) + assert "wget" in content or "apt" in content, \ + f"Debian tab should show wget/apt commands, got: '{content[:100]}'" + + + def test_switch_to_docker(self): + """Verify switching to Docker tab shows docker commands.""" + block = self._get_tab_block() + + self._click_tab(block, "Docker") + + active = self._get_active_tab_text(block) + assert "Docker" in active, \ + f"Active tab should be 'Docker', got: '{active}'" + + content = self._get_visible_body_text(block) + assert "docker" in content.lower(), \ + f"Docker tab should show docker commands, got: '{content[:100]}'" + + + def test_switch_to_macos(self): + """Verify switching to MacOS tab shows brew commands.""" + block = self._get_tab_block() + + self._click_tab(block, "MacOS") + + active = self._get_active_tab_text(block) + assert "MacOS" in active, \ + f"Active tab should be 'MacOS', got: '{active}'" + + content = self._get_visible_body_text(block) + assert "brew" in content, \ + f"MacOS tab should show brew command, got: '{content[:100]}'" + + + def test_switch_to_kubernetes(self): + """Verify switching to Kubernetes tab shows helm commands.""" + block = self._get_tab_block() + + self._click_tab(block, "Kubernetes") + + active = self._get_active_tab_text(block) + assert "Kubernetes" in active, \ + f"Active tab should be 'Kubernetes', got: '{active}'" + + content = self._get_visible_body_text(block) + assert "helm" in content, \ + f"Kubernetes tab should show helm commands, got: '{content[:100]}'" + + + def test_switching_tabs_changes_content(self): + """Verify that switching between tabs actually changes visible content.""" + block = self._get_tab_block() + + # Explicitly select RHEL first + self._click_tab(block, "RHEL, Centos, Alma, Amazon, Oracle") + rhel_content = self._get_visible_body_text(block) + + # Switch to Docker + self._click_tab(block, "Docker") + docker_content = self._get_visible_body_text(block) + + assert rhel_content != docker_content, \ + "Content should change when switching between RHEL and Docker tabs" + + # Switch back to RHEL + self._click_tab(block, "RHEL, Centos, Alma, Amazon, Oracle") + rhel_again = self._get_visible_body_text(block) + + assert rhel_again == rhel_content, \ + "Content should be the same when switching back to RHEL"