Skip to content

Commit

Permalink
Merge pull request #2026 from Sefaria/rtl-client
Browse files Browse the repository at this point in the history
Rtl client
  • Loading branch information
akiva10b authored Jan 15, 2025
2 parents e418850 + 48130ca commit 06ca513
Show file tree
Hide file tree
Showing 65 changed files with 2,249 additions and 1,112 deletions.
2 changes: 1 addition & 1 deletion api/api_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class APIWarningCode(Enum):

"""
classes for data warnings in API calls.
used when part of the data that was requested exists and returned, and part is missing.
used when part of the data that was requested exists and returned, and part is missing.
"""

class APIDatawarning():
Expand Down
6 changes: 6 additions & 0 deletions e2e-tests/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ export const LANGUAGES = {
'HE': 'hebrew',
}

export const SOURCE_LANGUAGES = {
'EN': /^(תרגום|Translation)$/,
'HE': /^(מקור|Source)$/,
'BI': /^(מקור ותרגום|Source with Translation)$/
}

export const cookieObject = {
"name": "interfaceLang",
"value": DEFAULT_LANGUAGE,
Expand Down
57 changes: 57 additions & 0 deletions e2e-tests/tests/interface-language-is-sticky.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {test, expect} from '@playwright/test';
import {changeLanguageOfText, goToPageWithLang, isIsraelIp} from "../utils";
import {LANGUAGES, SOURCE_LANGUAGES} from '../globals'

const interfaceTextHE = 'מקורות';
const interfaceTextEN = 'Texts';

[
// Hebrew Interface and English Source
{interfaceLanguage: 'Hebrew', interfaceLanguageToggle: LANGUAGES.HE,
sourceLanguage: 'English', sourceLanguageToggle: SOURCE_LANGUAGES.EN,
expectedSourceText: 'When God began to create', expectedBilingualText: '', expectedInterfaceText: interfaceTextHE },

// Hebrew Interface and Bilingual Source
{interfaceLanguage: 'Hebrew', interfaceLanguageToggle: LANGUAGES.HE,
sourceLanguage: 'Bilingual', sourceLanguageToggle: SOURCE_LANGUAGES.BI,
expectedSourceText: 'רֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ׃', expectedBilingualText: 'When God began to create', expectedInterfaceText: interfaceTextHE },

// Hebrew Interface and Hebrew Source
{interfaceLanguage: 'Hebrew', interfaceLanguageToggle: LANGUAGES.HE,
sourceLanguage: 'Hebrew', sourceLanguageToggle: SOURCE_LANGUAGES.HE,
expectedSourceText: 'רֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ׃', expectedBilingualText: '', expectedInterfaceText: interfaceTextHE },

// English Interface and English Source
{interfaceLanguage: 'English', interfaceLanguageToggle: LANGUAGES.EN,
sourceLanguage: 'English', sourceLanguageToggle: SOURCE_LANGUAGES.EN,
expectedSourceText: 'When God began to create', expectedBilingualText: '', expectedInterfaceText: interfaceTextEN },

// English Interface and Bilingual Source
{interfaceLanguage: 'English', sinterfaceLanguageToggle: LANGUAGES.EN,
sourceLanguage: 'Bilingual', sourceLanguageToggle: SOURCE_LANGUAGES.BI,
expectedSourceText: 'רֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ׃', expectedBilingualText: 'When God began to create',
expectedInterfaceText: interfaceTextEN },

// English Interface and Hebrew Source
{interfaceLanguage: 'English', interfaceLanguageToggle: LANGUAGES.EN,
sourceLanguage: 'Hebrew', sourceLanguageToggle: SOURCE_LANGUAGES.HE,
expectedSourceText: 'רֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ׃', expectedBilingualText: '', expectedInterfaceText: interfaceTextEN }

].forEach(({interfaceLanguage, interfaceLanguageToggle, sourceLanguage, sourceLanguageToggle, expectedSourceText, expectedBilingualText, expectedInterfaceText}) => {
test(`${interfaceLanguage} Interface Language with ${sourceLanguage} Source`, async ({ context }) => {

// Navigating to Bereshit with selected Interface Language, Hebrew or English
const page = await goToPageWithLang(context,'/Genesis.1',`${interfaceLanguageToggle}`)

// Selecting Source Language
await changeLanguageOfText(page, sourceLanguageToggle)

// Locating the source text segment, then verifying translation
await expect(page.locator('div.segmentNumber').first().locator('..').locator('p')).toContainText(`${expectedSourceText}`)

// Validate Hebrew interface language is still toggled
const textLink = page.locator('a.textLink').first()
await expect(textLink).toHaveText(`${expectedInterfaceText}`)

})
})
8 changes: 4 additions & 4 deletions e2e-tests/tests/reader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ test('Navigate to bereshit', async ({ context }) => {
});

test('Verify translations', async ({ context }) => {
const page = await goToPageWithLang(context, '/Berakhot.28b.4?vhe=Wikisource_Talmud_Bavli&lang=bi&with=all&lang2=he');
const page = await goToPageWithLang(context, '/Berakhot.28b.4?vhe=hebrew|Wikisource_Talmud_Bavli&lang=bi&with=all&lang2=he');
await page.getByRole('link', { name: 'Translations (4)' }).click();
await page.locator('#panel-1').getByText('Loading...').waitFor({ state: 'detached' });
page.getByText('A. Cohen, Cambridge University Press, 1921', { exact: true })
});

test('Get word description', async ({ context }) => {
const page = await goToPageWithLang(context, '/Berakhot.28b.4?vhe=Wikisource_Talmud_Bavli&lang=bi&with=all&lang2=he');
const page = await goToPageWithLang(context, '/Berakhot.28b.4?vhe=hebrew|Wikisource_Talmud_Bavli&lang=bi&with=all&lang2=he');
await page.getByRole('link', { name: 'ר\' נחוניא בן הקנה' }).click();
await page.locator('#panel-1').getByText('Loading...').waitFor({ state: 'detached' });
await page.getByText('Looking up words...').waitFor({ state: 'detached' });
Expand All @@ -31,11 +31,11 @@ test('Get word description', async ({ context }) => {


test('Open panel window', async ({ context }) => {
const page = await goToPageWithLang(context, '/Berakhot.28b.4?vhe=Wikisource_Talmud_Bavli&lang=bi&with=all&lang2=he');
const page = await goToPageWithLang(context, '/Berakhot.28b.4?vhe=hebrew|Wikisource_Talmud_Bavli&&lang=bi&with=all&lang2=he');
await page.getByText('ולית הלכתא לא כרב הונא ולא כריב"ל כרב הונא הא דאמרן כריב"ל דאריב"ל כיון שהגיע זמ').click();
await page.locator('#panel-1').getByText('Loading...').waitFor({ state: 'detached' });
await page.getByRole('link', { name: 'תלמוד (1)' }).click();
await page.getByRole('link', { name: 'שבת (1) מלאכות האסורות בשבת ודינים הקשורים לקדושת היום.' }).click();
await page.getByRole('link', { name: /^שבת/ }).click();
await page.getByText('טעינה...').waitFor({ state: 'detached' });
await page.getByRole('link', { name: 'Open' }).click();
await page.getByRole('heading', { name: 'Loading...' }).getByText('Loading...').waitFor({ state: 'detached' });
Expand Down
80 changes: 80 additions & 0 deletions e2e-tests/tests/translation-version-name-appears-in-title.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {test, expect} from '@playwright/test';
import {goToPageWithLang, changeLanguageOfText} from "../utils";
import {LANGUAGES, SOURCE_LANGUAGES} from '../globals'

[
// Hebrew Interface and Hebrew Source
{interfaceLanguage: 'Hebrew', interfaceLanguageToggle: LANGUAGES.HE,
sourceLanguage: 'Hebrew', sourceLanguageToggle: SOURCE_LANGUAGES.HE,
translations: 'תרגומים', select: 'בחירה', currentlySelected: 'נוכחי'},

// Hebrew Interface and Bilingual Source
{interfaceLanguage: 'Hebrew', interfaceLanguageToggle: LANGUAGES.HE,
sourceLanguage: 'Bilingual', sourceLanguageToggle: SOURCE_LANGUAGES.BI,
translations: 'תרגומים', select: 'בחירה', currentlySelected: 'נוכחי'},

// Hebrew Interface and English Source
{interfaceLanguage: 'Hebrew', interfaceLanguageToggle: LANGUAGES.HE,
sourceLanguage: 'English', sourceLanguageToggle: SOURCE_LANGUAGES.EN,
translations: 'תרגומים', select: 'בחירה', currentlySelected: 'נוכחי'},

// English Interface and English Source
{interfaceLanguage: 'English', interfaceLanguageToggle: LANGUAGES.EN,
sourceLanguage: 'English', sourceLanguageToggle: SOURCE_LANGUAGES.EN,
translations: 'Translations', select: 'Select', currentlySelected: 'Currently Selected'},

// English Interface and English Source
{interfaceLanguage: 'English', interfaceLanguageToggle: LANGUAGES.EN,
sourceLanguage: 'Bilingual', sourceLanguageToggle: SOURCE_LANGUAGES.BI,
translations: 'Translations', select: 'Select', currentlySelected: 'Currently Selected'},

// English Interface and Hebrew Source
{interfaceLanguage: 'English', interfaceLanguageToggle: LANGUAGES.EN,
sourceLanguage: 'Hebrew', sourceLanguageToggle: SOURCE_LANGUAGES.HE,
translations: 'Translations', select: 'Select', currentlySelected: 'Currently Selected'}

].forEach(({interfaceLanguage, interfaceLanguageToggle, sourceLanguage, sourceLanguageToggle, translations, currentlySelected, select}) => {
test(`${interfaceLanguage} - translation name appears in title for ${sourceLanguage} source text`, async ({ context }) => {
// Navigate to Bereshit in specified Interface Language
const page = await goToPageWithLang(context,'/Genesis.1', `${interfaceLanguageToggle}`)

// Change the Source Language of the text
await changeLanguageOfText(page, sourceLanguageToggle)

// Retain the translation name locator
const translationNameInTitle = page.locator('span.readerTextVersion')

// Navigate to the Translations sidebar by clicking on the text title
//Clicks on בראשית א׳ / Genesis I
await page.locator('h1').click()

// Click on Translations
await page.getByRole('link', {name: `${translations}`}).click()

// Wait for Translations side-bar to load by waiting for 'Translations' header
await page.waitForSelector('h3')

// Check if the default translation in the title matches the selected translation
// NOTE: We are skipping checking for the default translation here, due to the Hebrew text being default Masoretic
if(sourceLanguage !== 'Hebrew'){
const defaultTranslation = await translationNameInTitle.textContent()
await expect(page.locator('div.version-with-preview-title-line', {hasText: defaultTranslation!}).getByRole('link')).toHaveText(`${currentlySelected}`)
}

// TODO: 4th translation, handling Hebrew Interface translations in Hebrew. For example: 'חומש רש״י, רבי שרגא זילברשטיין' should appear in the translation title as written.
const translationNames = ['The Schocken Bible, Everett Fox, 1995 ©', '«Да» project']

// Utilizing the traditional for-loop as there are async issues with foreach
for(let i = 0; i < translationNames.length; i++){

// "Select" another translation.
await page.locator('div.version-with-preview-title-line', {hasText: translationNames[i]}).getByText(`${select}`).click()

// Validate selected translation is reflected in title
await expect(translationNameInTitle).toHaveText(translationNames[i])

// Validate selected translation says 'Currently Selected'
await expect(page.locator('div.version-with-preview-title-line', {hasText: translationNames[i]}).getByRole('link')).toHaveText(`${currentlySelected}`)
}
})
});
39 changes: 32 additions & 7 deletions e2e-tests/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {DEFAULT_LANGUAGE, LANGUAGES, testUser} from './globals'
import {DEFAULT_LANGUAGE, LANGUAGES, SOURCE_LANGUAGES, testUser} from './globals'
import {BrowserContext} from 'playwright-core';
import type { Page } from 'playwright-core';

Expand All @@ -23,13 +23,16 @@ export const changeLanguage = async (page: Page, language: string) => {
}

export const goToPageWithLang = async (context: BrowserContext, url: string, language=DEFAULT_LANGUAGE) => {
if (!langCookies.length) {
const page: Page = await context.newPage();
await page.goto('');
await changeLanguage(page, language);
langCookies = await context.cookies();
}
// If a cookie already has contents, clear it so that the language cookie can be reset
if (langCookies.length) {
await context.clearCookies()
}
const page: Page = await context.newPage();
await page.goto('');
await changeLanguage(page, language);
langCookies = await context.cookies();
await context.addCookies(langCookies);

// this is a hack to get the cookie to work
const newPage: Page = await context.newPage();
await newPage.goto(url);
Expand Down Expand Up @@ -65,4 +68,26 @@ export const goToPageWithUser = async (context: BrowserContext, url: string, use
export const getPathAndParams = (url: string) => {
const urlObj = new URL(url);
return urlObj.pathname + urlObj.search;
}

export const changeLanguageOfText = async (page: Page, sourceLanguage: RegExp) => {
// Clicking on the Source Language toggle
await page.getByAltText('Toggle Reader Menu Display Settings').click()

// Selecting Source Language
await page.locator('div').filter({ hasText: sourceLanguage }).click()
}

export const getCountryByIp = async (page: Page) => {
const data = await page.evaluate(() => {
return fetch('https://ipapi.co/json/')
.then(response => response.json())
.then(data => data)
})
return data.country;
}

export const isIsraelIp = async (page: Page) => {
const country = await getCountryByIp(page);
return country === "IL";
}
Loading

0 comments on commit 06ca513

Please sign in to comment.