Fixed sync tests
All checks were successful
Tests et déploiement / validate (push) Successful in 2m36s
Tests et déploiement / deploy (push) Successful in 1m6s

This commit is contained in:
2026-10-10 17:10:00 +02:00
parent d651166c6a
commit 0be1d54347
3 changed files with 17 additions and 6 deletions

View File

@@ -15,9 +15,8 @@ Dans **Données et sauvegardes → Synchronisation et appareils** :
de gestionnaire de secrets. de gestionnaire de secrets.
- Ajouter un appareil depuis ce même écran. L’invitation expire après cinq minutes, - Ajouter un appareil depuis ce même écran. L’invitation expire après cinq minutes,
n’accepte qu’un candidat et doit être renouvelée par l’écran visible toutes les n’accepte qu’un candidat et doit être renouvelée par l’écran visible toutes les
quelques secondes. En quittant l’écran ou en passant à l’appareil photo, les quelques secondes. Quitter ou masquer l’écran l’annule ; après une fermeture
battements s’arrêtent et le bail serveur expire sous 25 secondes si l’invitation brutale, le bail serveur expire sous 25 secondes.
n’est pas reprise.
- Saisir les huit caractères sur le nouvel appareil ou scanner le QR avec la caméra - Saisir les huit caractères sur le nouvel appareil ou scanner le QR avec la caméra
d’un appareil compatible. Le QR ouvre l’application web ; le navigateur/profil qui d’un appareil compatible. Le QR ouvre l’application web ; le navigateur/profil qui
reçoit ce lien doit être celui dans lequel on veut utiliser Pardis. Les copies reçoit ce lien doit être celui dans lequel on veut utiliser Pardis. Les copies

View File

@@ -181,7 +181,15 @@
const hash = () => { void resumePairback(); }; const hash = () => { void resumePairback(); };
window.addEventListener('hashchange', hash); window.addEventListener('hashchange', hash);
const timer = setInterval(poll, 3000); const timer = setInterval(poll, 3000);
return () => { alive = false; clearInterval(timer); window.removeEventListener('hashchange', hash); void stopScanner(); }; const hide = () => { if (document.visibilityState === 'hidden' && invite) void stopInvitation(); };
const leave = () => { void stopInvitation(); };
document.addEventListener('visibilitychange', hide);
window.addEventListener('pagehide', leave);
return () => {
alive = false; clearInterval(timer); window.removeEventListener('hashchange', hash);
document.removeEventListener('visibilitychange', hide); window.removeEventListener('pagehide', leave);
void stopScanner(); void cancelInvitation();
};
}); });
const settingLabels = { const settingLabels = {
workdays: 'Jours travaillés', nonWorkingDates: 'Jours non travaillés', workdays: 'Jours travaillés', nonWorkingDates: 'Jours non travaillés',

View File

@@ -26,11 +26,11 @@ async function ready(page) {
async function create(page) { async function create(page) {
await ready(page); await ready(page);
await page.getByLabel('Nom de cet appareil', { exact: true }).fill('Téléphone test'); await page.getByLabel('Nom de cet appareil', { exact: true }).fill('Téléphone test');
await page.getByRole('button', { name: 'Préparer la synchronisation', exact: true }).click(); await page.getByRole('button', { name: 'Créer mon coffre', exact: true }).click();
await page.getByText('Afficher le document pour le copier', { exact: true }).click(); await page.getByText('Afficher le document pour le copier', { exact: true }).click();
const recovery = await page.getByLabel('Contenu du document de secours').inputValue(); const recovery = await page.getByLabel('Contenu du document de secours').inputValue();
await page.getByRole('checkbox', { name: 'J’ai conservé une copie du document à part' }).check(); await page.getByRole('checkbox', { name: 'J’ai conservé une copie du document à part' }).check();
await page.getByRole('button', { name: 'Activer la synchronisation', exact: true }).click(); await page.getByRole('button', { name: 'Créer le coffre et activer la synchronisation', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Appareils autorisés', exact: true })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Appareils autorisés', exact: true })).toBeVisible();
await expect(page.getByRole('button', { name: 'Synchroniser maintenant', exact: true })).toBeEnabled(); await expect(page.getByRole('button', { name: 'Synchroniser maintenant', exact: true })).toBeEnabled();
await expect(page.locator('fieldset')).not.toContainText('Opération impossible'); await expect(page.locator('fieldset')).not.toContainText('Opération impossible');
@@ -54,6 +54,8 @@ async function pair(a, b) {
await a.getByLabel('Nom du nouvel appareil', { exact: true }).fill('Ordinateur test'); await a.getByLabel('Nom du nouvel appareil', { exact: true }).fill('Ordinateur test');
await a.getByRole('checkbox', { name: 'Les deux empreintes sont identiques' }).check(); await a.getByRole('checkbox', { name: 'Les deux empreintes sont identiques' }).check();
await a.getByRole('button', { name: 'Autoriser cet appareil', exact: true }).click(); await a.getByRole('button', { name: 'Autoriser cet appareil', exact: true }).click();
await expect(b.getByRole('heading', { name: 'Choisir les données à conserver', exact: true })).toBeVisible({ timeout: 15000 });
await b.getByRole('button', { name: 'Tout conserver du coffre existant', exact: true }).click();
await expect(b.getByRole('heading', { name: 'Appareils autorisés', exact: true })).toBeVisible({ timeout: 15000 }); await expect(b.getByRole('heading', { name: 'Appareils autorisés', exact: true })).toBeVisible({ timeout: 15000 });
await sync(b); await sync(b);
} }
@@ -85,6 +87,7 @@ test('association, modification hors ligne, conflit, rôle et révocation entre
await editTask(page, 'Modification téléphone'); await editTask(other, 'Modification ordinateur'); await editTask(page, 'Modification téléphone'); await editTask(other, 'Modification ordinateur');
await page.context().setOffline(false); await sync(page); await page.context().setOffline(false); await sync(page);
await otherContext.setOffline(false); await sync(other); await sync(page); await otherContext.setOffline(false); await sync(other); await sync(page);
await page.getByRole('button', { name: 'Fusion manuelle détaillée (1)', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Versions à départager (1)', exact: true })).toBeVisible(); await expect(page.getByRole('heading', { name: 'Versions à départager (1)', exact: true })).toBeVisible();
await expect(page.locator('.conflict')).toContainText('Modification téléphone'); await expect(page.locator('.conflict')).toContainText('Modification téléphone');
await expect(page.locator('.conflict')).toContainText('Modification ordinateur'); await expect(page.locator('.conflict')).toContainText('Modification ordinateur');
@@ -96,6 +99,7 @@ test('association, modification hors ligne, conflit, rôle et révocation entre
expect((await store(other, 'entries', 'getAll'))[0].task).toBe('Modification ordinateur'); expect((await store(other, 'entries', 'getAll'))[0].task).toBe('Modification ordinateur');
await other.getByRole('button', { name: 'Utiliser cet appareil pour les automatismes', exact: true }).click(); await other.getByRole('button', { name: 'Utiliser cet appareil pour les automatismes', exact: true }).click();
await expect(other.getByRole('button', { name: 'Utiliser cet appareil pour les automatismes', exact: true })).toHaveCount(0); await expect(other.getByRole('button', { name: 'Utiliser cet appareil pour les automatismes', exact: true })).toHaveCount(0);
await page.getByRole('button', { name: 'Retour aux appareils', exact: true }).click();
await sync(page); await sync(page);
await expect(page.getByRole('button', { name: 'Utiliser cet appareil pour les automatismes', exact: true })).toBeVisible(); await expect(page.getByRole('button', { name: 'Utiliser cet appareil pour les automatismes', exact: true })).toBeVisible();
await page.getByRole('button', { name: 'Retirer cet appareil…', exact: true }).click(); await page.getByRole('button', { name: 'Retirer cet appareil…', exact: true }).click();