From 768460b4cec4b160dff613c58ed839c203f4624e Mon Sep 17 00:00:00 2001 From: Egor Poderiagin Date: Mon, 14 Sep 2026 12:13:38 +0700 Subject: [PATCH] feat: added link to the repo --- README.md | 10 +++++ src/frontend/e2e/footer.spec.js | 70 ++++++++++++++++++++++++++++++++ src/frontend/src/App.vue | 37 +++++++++++++---- src/frontend/src/locales/de.json | 3 ++ src/frontend/src/locales/en.json | 3 ++ src/frontend/src/locales/fr.json | 3 ++ src/frontend/src/locales/hu.json | 3 ++ src/frontend/src/locales/ru.json | 3 ++ src/frontend/src/locales/th.json | 3 ++ 9 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 src/frontend/e2e/footer.spec.js diff --git a/README.md b/README.md index 5b4303e..88b8cd0 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,16 @@ it for you. Any text not translated yet shows in English. To change the English wording or add a language, see [docs/translation.md](docs/translation.md). +## Audio + +The exercise clips and their sentences come from +[Mozilla Common Voice](https://commonvoice.mozilla.org/)'s Thai dataset: +sentences read aloud by volunteers and released into the public domain under +CC0. The clips aren't stored in this repository; they are loaded from a local +copy of the dataset (see [Running it locally](#running-it-locally)). You can +record or check Thai sentences for the dataset at +[commonvoice.mozilla.org/th](https://commonvoice.mozilla.org/th). + ## License AGPL-3.0-or-later — see [LICENSE](LICENSE). Running a modified copy of this diff --git a/src/frontend/e2e/footer.spec.js b/src/frontend/e2e/footer.spec.js new file mode 100644 index 0000000..ec6dbbb --- /dev/null +++ b/src/frontend/e2e/footer.spec.js @@ -0,0 +1,70 @@ +import { expect, test } from '@playwright/test' + +import { LONGEST, mockBackend, sentenceOnScreen } from './fixtures' + +/** The lowest point any part of the exercise reaches, and the footer's box. */ +async function layout(page) { + return page.evaluate(() => ({ + contentBottom: Math.max( + ...[...document.querySelector('main').children].map((el) => el.getBoundingClientRect().bottom), + ), + footer: document.querySelector('footer').getBoundingClientRect().toJSON(), + scrolls: document.documentElement.scrollHeight > window.innerHeight, + })) +} + +test.describe('the footer', () => { + test('links to the source code', async ({ page }) => { + await mockBackend(page) + await page.goto('/') + await sentenceOnScreen(page) + + const footer = page.getByRole('contentinfo') + await expect(footer.getByRole('link', { name: 'Source code on GitHub' })).toHaveAttribute( + 'href', + 'https://github.com/Akay7/TypeLearn', + ) + }) + + // The laptop screen the "fits on one screen" requirement names: the footer + // must not be what pushes the keyboard below the fold. + test('fits under the longest exercise without scrolling the page', async ({ page }) => { + await mockBackend(page, [LONGEST]) + await page.goto('/') + await sentenceOnScreen(page) + await page.waitForFunction(() => document.fonts.status === 'loaded') + + const { contentBottom, footer, scrolls } = await layout(page) + + expect(scrolls).toBe(false) + expect(footer.top).toBeGreaterThanOrEqual(contentBottom) + }) + + test.describe('on a screen shorter than the exercise', () => { + test.use({ viewport: { width: 1280, height: 560 } }) + + test('sits below the keyboard legend instead of over it', async ({ page }) => { + await mockBackend(page, [LONGEST]) + await page.goto('/') + await sentenceOnScreen(page) + await page.waitForFunction(() => document.fonts.status === 'loaded') + + const { contentBottom, footer, scrolls } = await layout(page) + + expect(scrolls).toBe(true) + expect(footer.top).toBeGreaterThanOrEqual(contentBottom) + }) + }) + + test('follows the interface language', async ({ page }) => { + await mockBackend(page) + await page.goto('/') + await sentenceOnScreen(page) + + await page.locator('button[aria-haspopup="true"]').click() + await page.locator('#interface-language').selectOption('ru') + + const footer = page.getByRole('contentinfo') + await expect(footer.getByRole('link', { name: 'Исходный код на GitHub' })).toBeVisible() + }) +}) diff --git a/src/frontend/src/App.vue b/src/frontend/src/App.vue index f0632f0..3dd8537 100644 --- a/src/frontend/src/App.vue +++ b/src/frontend/src/App.vue @@ -1,23 +1,42 @@ diff --git a/src/frontend/src/locales/de.json b/src/frontend/src/locales/de.json index df350bc..2b0efd4 100644 --- a/src/frontend/src/locales/de.json +++ b/src/frontend/src/locales/de.json @@ -76,5 +76,8 @@ "today": "Heute", "last7Days": "Letzte 7 Tage", "next": "Nächste Übung →" + }, + "footer": { + "source": "Quellcode auf GitHub" } } diff --git a/src/frontend/src/locales/en.json b/src/frontend/src/locales/en.json index c467767..2094480 100644 --- a/src/frontend/src/locales/en.json +++ b/src/frontend/src/locales/en.json @@ -76,5 +76,8 @@ "today": "Today", "last7Days": "Last 7 days", "next": "Next exercise →" + }, + "footer": { + "source": "Source code on GitHub" } } diff --git a/src/frontend/src/locales/fr.json b/src/frontend/src/locales/fr.json index 5a64798..3fc8f92 100644 --- a/src/frontend/src/locales/fr.json +++ b/src/frontend/src/locales/fr.json @@ -77,5 +77,8 @@ "today": "Aujourd'hui", "last7Days": "7 derniers jours", "next": "Exercice suivant →" + }, + "footer": { + "source": "Code source sur GitHub" } } diff --git a/src/frontend/src/locales/hu.json b/src/frontend/src/locales/hu.json index 49745df..57349c0 100644 --- a/src/frontend/src/locales/hu.json +++ b/src/frontend/src/locales/hu.json @@ -76,5 +76,8 @@ "today": "Ma", "last7Days": "Elmúlt 7 nap", "next": "Következő gyakorlat →" + }, + "footer": { + "source": "Forráskód a GitHubon" } } diff --git a/src/frontend/src/locales/ru.json b/src/frontend/src/locales/ru.json index e8df924..88e463d 100644 --- a/src/frontend/src/locales/ru.json +++ b/src/frontend/src/locales/ru.json @@ -78,5 +78,8 @@ "today": "Сегодня", "last7Days": "Последние 7 дней", "next": "Следующее упражнение →" + }, + "footer": { + "source": "Исходный код на GitHub" } } diff --git a/src/frontend/src/locales/th.json b/src/frontend/src/locales/th.json index 6d34070..5f94af9 100644 --- a/src/frontend/src/locales/th.json +++ b/src/frontend/src/locales/th.json @@ -75,5 +75,8 @@ "today": "วันนี้", "last7Days": "7 วันที่ผ่านมา", "next": "แบบฝึกหัดถัดไป →" + }, + "footer": { + "source": "ซอร์สโค้ดบน GitHub" } }