Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
node_modules
.idea
.env
e2e_test_config.yml
e2e_test_data.json
e2e_stress_test_data.json
cypress/results/
Expand All @@ -14,3 +15,6 @@ __pycache__/
.pytest_cache/
.ruff_cache/

# Compiled translation files (generated from .po files)
translations/**/messages.mo

5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pytest-run:

setup-test-data:
cp e2e_test_data_template.json e2e_test_data.json
sed 's|__E2E_TESTS_DIR__|$(CURDIR)|g' e2e_test_config.template.yml > e2e_test_config.yml
$(MAKE) compile-translations

e2e-tests:
$(MAKE) pytest-run PYTEST_SPEC="tests/basic"
Expand All @@ -31,3 +33,6 @@ e2e-stress-tests:
run-e2e-env:
poetry --project '$(GOODMAP_PATH)' run flask --app "goodmap.goodmap:create_app(config_path='$(CONFIG_PATH)')" --debug run

compile-translations:
poetry run pybabel compile -d translations

3 changes: 3 additions & 0 deletions e2e_test_config.yml → e2e_test_config.template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ APP_NAME: Bridges in Wroclaw
SECRET_KEY: SECRET
BLOG_PREFIX: "/blog"
USE_WWW: False
# Note: __E2E_TESTS_DIR__ is replaced by `make setup-test-data` with the absolute path
# This is needed because Flask-Babel resolves relative paths to app.root_path (platzky dir)
TRANSLATION_DIRECTORIES: [__E2E_TESTS_DIR__/translations]
DB:
TYPE: json_file
PATH: e2e_test_data.json
Expand Down
17 changes: 16 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ playwright = "^1.49.1"
pytest-xdist = "^3.6.1" # For parallel test execution
ruff = "^0.8.4" # Linting and formatting
black = "^24.10.0" # Code formatting
babel = "^2.17.0" # For compiling translation files

[tool.pytest.ini_options]
testpaths = ["tests"]
Expand Down
207 changes: 207 additions & 0 deletions tests/basic/test_left_panel_translations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
"""
Test suite for left panel field translations.

Tests that category names, filter options, and help texts in the left panel
are properly translated when switching languages.
"""

import pytest
from playwright.sync_api import Page, expect

from tests.conftest import BASE_URL

# Expected translations for left panel fields
TRANSLATIONS = {
"en": {
"category_names": {
"accessible_by": "accessible by",
"type_of_place": "type of place",
},
"filter_options": {
"bikes": "bikes",
"cars": "cars",
"pedestrians": "pedestrians",
"big bridge": "big bridge",
"small bridge": "small bridge",
},
"help_texts": {
"categories_help_accessible_by": "Who can use this bridge",
"categories_options_help_small bridge": "A smaller pedestrian or bike bridge",
},
},
"pl": {
"category_names": {
"accessible_by": "dostępny dla",
"type_of_place": "typ miejsca",
},
"filter_options": {
"bikes": "rowery",
"cars": "samochody",
"pedestrians": "piesi",
"big bridge": "duży most",
"small bridge": "mały most",
},
"help_texts": {
"categories_help_accessible_by": "Kto może korzystać z tego mostu",
"categories_options_help_small bridge": "Mniejszy most dla pieszych lub rowerzystów",
},
},
}


def get_language_button(page: Page):
"""Get language switch button using ID selector."""
return page.locator("#languages-menu")


def switch_to_language(page: Page, lang_name: str):
"""Switch to a specific language by clicking the language menu."""
get_language_button(page).click()
page.get_by_role("link", name=lang_name).click()
page.wait_for_load_state("domcontentloaded")


class TestLeftPanelTranslationsEnglish:
"""Test suite for left panel translations in English (default language)"""

@pytest.fixture(autouse=True)
def setup(self, page: Page):
"""Navigate to home page and wait for filter form to load"""
page.set_viewport_size({"width": 1200, "height": 800})
page.goto(BASE_URL, wait_until="domcontentloaded")
page.wait_for_selector("#filter-form", timeout=10000)

def test_category_names_in_english(self, page: Page):
"""Verify category names are displayed in English"""
panel = page.locator("#left-panel")
panel_text = panel.inner_text().lower()

for key, expected in TRANSLATIONS["en"]["category_names"].items():
assert (
expected.lower() in panel_text
), f"Expected '{expected}' (translation of '{key}') in left panel"

def test_filter_options_in_english(self, page: Page):
"""Verify filter options are displayed in English"""
panel = page.locator("#left-panel")
panel_text = panel.inner_text().lower()

for key, expected in TRANSLATIONS["en"]["filter_options"].items():
assert (
expected.lower() in panel_text
), f"Expected '{expected}' (translation of '{key}') in left panel"


class TestLeftPanelTranslationsPolish:
"""Test suite for left panel translations in Polish"""

@pytest.fixture(autouse=True)
def setup(self, page: Page):
"""Navigate to home page, switch to Polish, and wait for filter form"""
page.set_viewport_size({"width": 1200, "height": 800})
page.goto(BASE_URL, wait_until="domcontentloaded")
switch_to_language(page, "polski")
page.wait_for_selector("#filter-form", timeout=10000)

def test_category_names_in_polish(self, page: Page):
"""Verify category names are displayed in Polish"""
panel = page.locator("#left-panel")
panel_text = panel.inner_text().lower()

for key, expected in TRANSLATIONS["pl"]["category_names"].items():
assert (
expected.lower() in panel_text
), f"Expected '{expected}' (Polish translation of '{key}') in left panel"

def test_filter_options_in_polish(self, page: Page):
"""Verify filter options are displayed in Polish"""
panel = page.locator("#left-panel")
panel_text = panel.inner_text().lower()

for key, expected in TRANSLATIONS["pl"]["filter_options"].items():
assert (
expected.lower() in panel_text
), f"Expected '{expected}' (Polish translation of '{key}') in left panel"


class TestLeftPanelTranslationSwitching:
"""Test suite for switching languages and verifying translations update"""

def test_switch_from_english_to_polish_updates_category_names(self, page: Page):
"""Verify switching from English to Polish updates category names"""
page.set_viewport_size({"width": 1200, "height": 800})
page.goto(BASE_URL, wait_until="domcontentloaded")
page.wait_for_selector("#filter-form", timeout=10000)

# Verify English first
panel = page.locator("#left-panel")
panel_text = panel.inner_text().lower()
assert "accessible by" in panel_text, "Expected English 'accessible by'"

# Switch to Polish
switch_to_language(page, "polski")
page.wait_for_selector("#filter-form", timeout=10000)

# Verify Polish
panel = page.locator("#left-panel")
panel_text = panel.inner_text().lower()
assert "dostępny dla" in panel_text, "Expected Polish 'dostępny dla'"

def test_switch_from_polish_to_english_updates_category_names(self, page: Page):
"""Verify switching from Polish back to English restores English text"""
page.set_viewport_size({"width": 1200, "height": 800})
page.goto(BASE_URL, wait_until="domcontentloaded")

# Switch to Polish first
switch_to_language(page, "polski")
page.wait_for_selector("#filter-form", timeout=10000)

panel = page.locator("#left-panel")
panel_text = panel.inner_text().lower()
assert "dostępny dla" in panel_text, "Expected Polish 'dostępny dla'"

# Switch back to English
switch_to_language(page, "English")
page.wait_for_selector("#filter-form", timeout=10000)

# Verify English restored
panel = page.locator("#left-panel")
panel_text = panel.inner_text().lower()
assert "accessible by" in panel_text, "Expected English 'accessible by' restored"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated


class TestLeftPanelHelpTextTranslations:
"""Test suite for filter help text translations"""

def test_help_tooltip_in_english(self, page: Page):
"""Verify help tooltip shows English text"""
page.set_viewport_size({"width": 1200, "height": 800})
page.goto(BASE_URL, wait_until="domcontentloaded")
page.wait_for_selector("#filter-form", timeout=10000)

# Find and hover over a help icon
help_icon = page.get_by_label("Help: categories_options_help_small bridge")
if help_icon.count() > 0:
help_icon.first.hover()
tooltip = page.locator('[role="tooltip"]')
expect(tooltip).to_be_visible()
tooltip_text = tooltip.inner_text()
expected = TRANSLATIONS["en"]["help_texts"]["categories_options_help_small bridge"]
assert expected in tooltip_text, f"Expected '{expected}' in tooltip"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

def test_help_tooltip_in_polish(self, page: Page):
"""Verify help tooltip shows Polish text after language switch"""
page.set_viewport_size({"width": 1200, "height": 800})
page.goto(BASE_URL, wait_until="domcontentloaded")
switch_to_language(page, "polski")
page.wait_for_selector("#filter-form", timeout=10000)

# Find and hover over a help icon
help_icon = page.get_by_label("Help: categories_options_help_small bridge")
if help_icon.count() > 0:
help_icon.first.hover()
tooltip = page.locator('[role="tooltip"]')
expect(tooltip).to_be_visible()
tooltip_text = tooltip.inner_text()
expected = TRANSLATIONS["pl"]["help_texts"]["categories_options_help_small bridge"]
assert expected in tooltip_text, f"Expected '{expected}' in tooltip"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
56 changes: 56 additions & 0 deletions translations/en/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# English translations for E2E tests.
# This file contains test-specific translations for the "Bridges in Wroclaw" test data.
#
msgid ""
msgstr ""
"Project-Id-Version: goodmap-e2e-tests\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
"PO-Revision-Date: 2024-01-01 00:00+0000\n"
"Language: en\n"
"Language-Team: en <en@example.com>\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"

# Category names
msgid "accessible_by"
msgstr "accessible by"

msgid "type_of_place"
msgstr "type of place"

msgid "remark"
msgstr "remark"

# Category values - accessible_by
msgid "bikes"
msgstr "bikes"

msgid "cars"
msgstr "cars"

msgid "pedestrians"
msgstr "pedestrians"

# Category values - type_of_place
msgid "big bridge"
msgstr "big bridge"

msgid "small bridge"
msgstr "small bridge"

# Help texts - category headers
msgid "categories_help_accessible_by"
msgstr "Who can use this bridge"

# Help texts - category options
msgid "categories_options_help_small bridge"
msgstr "A smaller pedestrian or bike bridge"

msgid "categories_options_help_cars"
msgstr "Bridge allows car traffic"

msgid "categories_options_help_pedestrians"
msgstr "Bridge allows pedestrian access"
56 changes: 56 additions & 0 deletions translations/pl/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Polish translations for E2E tests.
# This file contains test-specific translations for the "Bridges in Wroclaw" test data.
#
msgid ""
msgstr ""
"Project-Id-Version: goodmap-e2e-tests\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-01-01 00:00+0000\n"
"PO-Revision-Date: 2024-01-01 00:00+0000\n"
"Language: pl\n"
"Language-Team: pl <pl@example.com>\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"

# Category names
msgid "accessible_by"
msgstr "dostępny dla"

msgid "type_of_place"
msgstr "typ miejsca"

msgid "remark"
msgstr "uwaga"

# Category values - accessible_by
msgid "bikes"
msgstr "rowery"

msgid "cars"
msgstr "samochody"

msgid "pedestrians"
msgstr "piesi"

# Category values - type_of_place
msgid "big bridge"
msgstr "duży most"

msgid "small bridge"
msgstr "mały most"

# Help texts - category headers
msgid "categories_help_accessible_by"
msgstr "Kto może korzystać z tego mostu"

# Help texts - category options
msgid "categories_options_help_small bridge"
msgstr "Mniejszy most dla pieszych lub rowerzystów"

msgid "categories_options_help_cars"
msgstr "Most umożliwia ruch samochodowy"

msgid "categories_options_help_pedestrians"
msgstr "Most umożliwia przejście pieszych"
Loading