Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 150 additions & 0 deletions manual/tests/test_code_tabs_sql_json.py
Original file line number Diff line number Diff line change
@@ -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}'"
91 changes: 91 additions & 0 deletions manual/tests/test_language_switcher.py
Original file line number Diff line number Diff line change
@@ -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')}'"

153 changes: 153 additions & 0 deletions manual/tests/test_os_tabs_installation.py
Original file line number Diff line number Diff line change
@@ -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"