Skip to content
Open
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
51 changes: 50 additions & 1 deletion task-launcher/cypress.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,47 @@
import { defineConfig } from 'cypress';

const LANGUAGE_OPTIONS_URL =
'https://storage.googleapis.com/levante-assets-dev/translations/dashboard-consolidated-flat/languageoptions.json';

async function buildLanguageLocaleTaskMatrix() {
const res = await fetch(LANGUAGE_OPTIONS_URL);
if (!res.ok) {
throw new Error(`Failed to fetch language options: ${res.status} ${res.statusText}`);
}
const languageOptions = await res.json();
const seen = new Set();

const matrix = Object.entries(languageOptions).flatMap(([locale, cfg]) => {
if (locale === 'en-US') {
return [];
}
if (!cfg || !Array.isArray(cfg.taskOptions)) {
return [];
}
return cfg.taskOptions
.filter((task) => {
const key = `${locale}\0${task}`;
if (seen.has(key)) {
return false;
}
seen.add(key);
return true;
})
.map((task) => ({ locale, task }));
});

if (matrix.length === 0) {
throw new Error(
'languageoptions.json produced an empty test matrix (no locales with taskOptions).',
);
}

return matrix;
}

export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
async setupNodeEvents(on, config) {
// implement node event listeners here
on('task', {
progress(message) {
Expand All @@ -12,6 +51,16 @@ export default defineConfig({
return null;
},
});

const matrix = await buildLanguageLocaleTaskMatrix();

return {
...config,
env: {
...config.env,
languageLocaleTaskMatrix: matrix,
},
};
},
// Video recording settings
video: true,
Expand Down
46 changes: 27 additions & 19 deletions task-launcher/cypress/e2e/task_locales.cy.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
const LOCALES = ['de-DE', 'es-CO', 'es-AR'];

const TASKS = [
'intro',
'egma-math',
'matrix-reasoning',
'mental-rotation',
'hearts-and-flowers',
'memory-game',
'same-different-selection',
'trog',
'vocab',
'theory-of-mind',
'hostile-attribution',
'child-survey',
];
/* global cy, describe, expect, it, Cypress */

function visitTaskWithLocaleAndEnterFullscreen(task, lng) {
cy.visit(`http://localhost:8080/?task=${task}&lng=${lng}`);
cy.get('button.primary').should('be.visible').first().realClick();
}

describe('tasks load in non-English locales (fullscreen only)', () => {
TASKS.forEach((task) => {
function groupLocalesByTask(matrix) {
const byTask = {};
matrix.forEach(({ locale, task }) => {
if (!byTask[task]) {
byTask[task] = [];
}
byTask[task].push(locale);
});
return byTask;
}

describe('tasks load per languageoptions.json (fullscreen only)', () => {
const matrix = Cypress.env('languageLocaleTaskMatrix');

if (!Array.isArray(matrix) || matrix.length === 0) {
it('fails when languageLocaleTaskMatrix is not preloaded (see cypress.config.js)', () => {
expect(matrix).to.be.an('array');
expect(matrix).to.have.length.greaterThan(0);
});
return;
}

const byTask = groupLocalesByTask(matrix);

Object.entries(byTask).forEach(([task, locales]) => {
describe(task, () => {
LOCALES.forEach((lng) => {
locales.forEach((lng) => {
it(`lng=${lng}`, () => {
visitTaskWithLocaleAndEnterFullscreen(task, lng);
});
Expand Down
Loading