Nested UI for data & storage options
This commit is contained in:
@@ -12,6 +12,8 @@ async function importFixture(page, payload = fixture()) {
|
||||
await page.clock.install({ time:now });
|
||||
await page.goto('/#/settings');
|
||||
await expect(page.getByRole('heading',{name:'Réglages',exact:true})).toBeVisible();
|
||||
await page.getByRole('button',{name:'Gérer les données et sauvegardes'}).click();
|
||||
await expect(page.getByRole('heading',{name:'Données et sauvegardes',exact:true})).toBeVisible();
|
||||
await page.locator('input[type=file]').setInputFiles({ name:'fixture-synthetique.json',mimeType:'application/json',buffer:Buffer.from(JSON.stringify(payload)) });
|
||||
await page.getByRole('button',{name:'Remplacer tout',exact:true}).click();
|
||||
await page.getByRole('dialog',{name:'Remplacer les données'}).getByRole('button',{name:'Confirmer',exact:true}).click();
|
||||
@@ -88,6 +90,42 @@ test('date conservée, rechargement et Retour depuis les trois nouvelles pages',
|
||||
await expect(page.getByRole('heading',{name:'Réglages',exact:true})).toBeVisible();
|
||||
});
|
||||
|
||||
test('écran données dédié, conservation persistée et accès depuis le rappel', async ({page}) => {
|
||||
await importFixture(page,fixture({dates:['2025-01-01',date]}));
|
||||
await page.getByRole('button',{name:'Réglages',exact:true}).click();
|
||||
await expect(page.getByRole('button',{name:'Exporter les données',exact:true})).toHaveCount(0);
|
||||
await expect(page.getByLabel('Conserver (jours)')).toHaveCount(0);
|
||||
await page.getByRole('button',{name:'Gérer les données et sauvegardes'}).click();
|
||||
await expect(page.getByRole('heading',{name:'Données et sauvegardes',exact:true})).toBeVisible();
|
||||
await expect(page.locator('nav').getByRole('button',{name:'Réglages',exact:true})).toHaveAttribute('aria-current','true');
|
||||
const retention = page.getByLabel('Conserver (jours)');
|
||||
await expect(retention).toHaveValue('30');
|
||||
await retention.fill('60');
|
||||
await retention.press('Tab');
|
||||
await expect.poll(() => page.evaluate(() => new Promise((resolve,reject) => {
|
||||
const request = indexedDB.open('TimeLogDB');
|
||||
request.onerror = () => reject(request.error);
|
||||
request.onsuccess = () => {
|
||||
const db = request.result;
|
||||
const query = db.transaction('settings').objectStore('settings').get('app');
|
||||
query.onsuccess = () => { resolve(query.result.value.retentionDays); db.close(); };
|
||||
query.onerror = () => { reject(query.error); db.close(); };
|
||||
};
|
||||
}))).toBe(60);
|
||||
await page.reload();
|
||||
await expect(retention).toHaveValue('60');
|
||||
expect(await entries(page)).toHaveLength(6);
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true);
|
||||
await page.getByRole('button',{name:'Retour aux réglages'}).click();
|
||||
await expect(page.getByRole('heading',{name:'Réglages',exact:true})).toBeVisible();
|
||||
await page.getByRole('button',{name:'Gérer les données et sauvegardes'}).click();
|
||||
await page.goBack();
|
||||
await expect(page.getByRole('heading',{name:'Réglages',exact:true})).toBeVisible();
|
||||
await page.getByRole('button',{name:'Récap',exact:true}).click();
|
||||
await page.getByRole('button',{name:'Sauvegarder',exact:true}).click();
|
||||
await expect(page.getByRole('heading',{name:'Données et sauvegardes',exact:true})).toBeVisible();
|
||||
});
|
||||
|
||||
test('reprise annulée puis concurrente entre deux onglets, choix pause par défaut', async ({page,context}) => {
|
||||
await importFixture(page,fixture({pause:false}));
|
||||
const before = await entries(page);
|
||||
@@ -101,7 +139,11 @@ test('reprise annulée puis concurrente entre deux onglets, choix pause par déf
|
||||
await other.clock.install({time:now}); await other.goto('/#/today');
|
||||
await Promise.all([page.getByRole('button',{name:'Reprendre la journée',exact:true}).click(),other.getByRole('button',{name:'Reprendre la journée',exact:true}).click()]);
|
||||
await Promise.all([page.getByRole('button',{name:'Confirmer la reprise'}).dblclick(),other.getByRole('button',{name:'Confirmer la reprise'}).click()]);
|
||||
await expect(page.getByRole('heading',{name:'En cours',exact:true})).toBeVisible();
|
||||
// Either tab may win the transaction; the resumed entries must remain unique.
|
||||
await expect.poll(async () =>
|
||||
await page.getByRole('heading',{name:'En cours',exact:true}).isVisible() ||
|
||||
await other.getByRole('heading',{name:'En cours',exact:true}).isVisible()
|
||||
).toBe(true);
|
||||
const rows = await entries(page);
|
||||
expect(rows.map(row=>row.kind)).toEqual(['work','break','work']);
|
||||
expect(rows[0].endTs).toBe(at('17:00')); expect(rows[1].startTs).toBe(at('17:00'));
|
||||
@@ -136,6 +178,7 @@ for (const kind of ['lunch','break']) test(`reprise après ${kind} garde sa natu
|
||||
test('export relu et vérifié, PWA relancée hors ligne', async ({page,context}) => {
|
||||
await importFixture(page);
|
||||
await page.getByRole('button',{name:'Réglages',exact:true}).click();
|
||||
await page.getByRole('button',{name:'Gérer les données et sauvegardes'}).click();
|
||||
const downloading = page.waitForEvent('download');
|
||||
await page.getByRole('button',{name:'Exporter les données',exact:true}).click();
|
||||
const download = await downloading;
|
||||
@@ -147,7 +190,7 @@ test('export relu et vérifié, PWA relancée hors ligne', async ({page,context}
|
||||
await expect.poll(() => page.evaluate(() => Boolean(navigator.serviceWorker.controller))).toBe(true);
|
||||
await context.setOffline(true);
|
||||
await page.reload();
|
||||
await expect(page.getByRole('heading',{name:'Réglages',exact:true})).toBeVisible();
|
||||
await expect(page.getByRole('heading',{name:'Données et sauvegardes',exact:true})).toBeVisible();
|
||||
await page.getByRole('button',{name:'Récap',exact:true}).click();
|
||||
await expect(page.locator('.total')).toContainText('8h30');
|
||||
});
|
||||
@@ -168,6 +211,7 @@ test('échec IndexedDB visible et reprise avec Réessayer', async ({page}) => {
|
||||
test('purge confirmée et restauration de sa sauvegarde récupérable', async ({page}) => {
|
||||
await importFixture(page,fixture({dates:['2025-01-01',date]}));
|
||||
await page.getByRole('button',{name:'Réglages',exact:true}).click();
|
||||
await page.getByRole('button',{name:'Gérer les données et sauvegardes'}).click();
|
||||
await page.getByRole('button',{name:'Purger maintenant'}).click();
|
||||
const dialog = page.getByRole('dialog',{name:'Confirmer la purge'});
|
||||
await expect(dialog).toContainText('2025-01-01');
|
||||
|
||||
Reference in New Issue
Block a user