Files
2026-05-24 09:39:53 +02:00

187 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Instructions
- Following Playwright test failed.
- Explain why, be concise, respect Playwright best practices.
- Provide a snippet of code with the fix, if possible.
# Test info
- Name: specs/epic-1-visibility.spec.js >> Epic 1: Core Camera Visibility Control >> FR-1: Hide/Show Participant via Context Menu >> GM can hide a participant from the table via right-click
- Location: specs/epic-1-visibility.spec.js:60:5
# Error details
```
Test timeout of 120000ms exceeded while running "beforeEach" hook.
```
```
Error: page.waitForFunction: Test timeout of 120000ms exceeded.
```
# Page snapshot
```yaml
- generic [active] [ref=e1]:
- list:
- listitem [ref=e2]:
- text:
- paragraph [ref=e3]: Foundry Virtual Tabletop nécessite une résolution d'écran de 1366px par 768px ou plus. Votre écran a une résolution de 1280px par 720px. Vous devez augmenter votre résolution ou utiliser un autre périphérique d'affichage, sinon certaines fonctionnalités du logiciel ne fonctionneront pas correctement.
- text:
- banner [ref=e5]:
- heading "Donjon & Cie" [level=1] [ref=e6]
- generic [ref=e7]:
- generic [ref=e8]:
- heading "Rejoindre la partie" [level=2] [ref=e9]
- combobox [ref=e14] [cursor=pointer]:
- option [selected]
- option "Gamemaster" [disabled]
- textbox "Mot de passe" [ref=e19]
- contentinfo [ref=e20]:
- button "Rejoindre la partie" [ref=e21] [cursor=pointer]:
- generic: Rejoindre la partie
- generic [ref=e22]:
- heading "Détails de la session" [level=2] [ref=e23]
- generic [ref=e25]: Prochaine partie
- generic [ref=e27]:
- generic [ref=e28]: Joueurs présents
- generic [ref=e30]:
- generic [ref=e31]: "1"
- generic [ref=e32]: /
- generic [ref=e33]: "1"
- generic [ref=e34]:
- heading "Retour à laccueil" [level=2] [ref=e35]
- textbox [ref=e39]
- contentinfo [ref=e40]:
- button "Retour à laccueil" [ref=e41] [cursor=pointer]:
- generic: Retour à laccueil
- article [ref=e42]:
- heading "Description du monde" [level=2] [ref=e43]
- contentinfo [ref=e44]:
- paragraph [ref=e45]: Version 14 Build 361
```
# Test source
```ts
1 | /**
2 | * Helpers pour les tests E2E avec FoundryVTT
3 | *
4 | * Fournit des fonctions utilitaires pour :
5 | * - Attendre que Foundry soit prêt
6 | * - Attendre que le module soit chargé
7 | * - Interagir avec l'UI FoundryVTT
8 | * - Gérer les sélecteurs spécifiques au module
9 | */
10 |
11 | import { expect } from '@playwright/test';
12 |
13 | /**
14 | * Attend que FoundryVTT soit complètement chargé
15 | * @param {import('@playwright/test').Page} page - La page Playwright
16 | * @param {number} timeout - Timeout en ms (défaut: 30000)
17 | */
18 | export async function waitForFoundryReady(page, timeout = 30000) {
> 19 | await page.waitForFunction(() => {
| ^ Error: page.waitForFunction: Test timeout of 120000ms exceeded.
20 | return typeof game !== 'undefined' && game.ready;
21 | }, { timeout });
22 | }
23 |
24 | /**
25 | * Attend que le module Video View Manager soit actif
26 | * @param {import('@playwright/test').Page} page - La page Playwright
27 | * @param {number} timeout - Timeout en ms (défaut: 15000)
28 | */
29 | export async function waitForVVMModule(page, timeout = 15000) {
30 | await page.waitForFunction(() => {
31 | const module = game.modules?.get?.('video-view-manager');
32 | return module?.active === true;
33 | }, { timeout });
34 | }
35 |
36 | /**
37 | * Attend qu'un élément du module soit présent
38 | * @param {import('@playwright/test').Page} page - La page Playwright
39 | * @param {string} selector - Sélecteur CSS
40 | * @param {number} timeout - Timeout en ms (défaut: 10000)
41 | */
42 | export async function waitForVVMElement(page, selector, timeout = 10000) {
43 | await page.waitForSelector(selector, {
44 | state: 'visible',
45 | timeout
46 | });
47 | }
48 |
49 | /**
50 | * Clique sur un bouton dans l'UI Foundry avec retry
51 | * @param {import('@playwright/test').Page} page - La page Playwright
52 | * @param {string|import('@playwright/test').Locator} button - Sélecteur ou Locator
53 | * @param {number} retries - Nombre de tentatives (défaut: 3)
54 | */
55 | export async function clickFoundryButton(page, button, retries = 3) {
56 | for (let i = 0; i < retries; i++) {
57 | try {
58 | const locator = typeof button === 'string' ? page.locator(button) : button;
59 | await locator.click({ timeout: 5000 });
60 | return;
61 | } catch (error) {
62 | if (i === retries - 1) throw error;
63 | await page.waitForTimeout(1000);
64 | }
65 | }
66 | }
67 |
68 | /**
69 | * Ouvre le sidebar de configuration Foundry
70 | * @param {import('@playwright/test').Page} page - La page Playwright
71 | */
72 | export async function openFoundrySidebar(page) {
73 | await clickFoundryButton(page, 'button[aria-label="Configure Settings"]');
74 | await page.waitForSelector('.app-v2.settings', { state: 'visible', timeout: 10000 });
75 | }
76 |
77 | /**
78 | * Ouvre le Director's Board (Epic 2)
79 | * @param {import('@playwright/test').Page} page - La page Playwright
80 | */
81 | export async function openDirectorsBoard(page) {
82 | // Le Director's Board a un bouton dédié dans la sidebar
83 | await page.waitForSelector('button[aria-label*="Director\'s Board"]', { timeout: 10000 });
84 | await clickFoundryButton(page, 'button[aria-label*="Director\'s Board"]');
85 |
86 | // Attendre que le board soit ouvert
87 | await page.waitForSelector('.scrying-pool-directors-board', {
88 | state: 'visible',
89 | timeout: 10000
90 | });
91 | }
92 |
93 | /**
94 | * Ouvre le Player Privacy Panel pour un utilisateur
95 | * @param {import('@playwright/test').Page} page - La page Playwright
96 | * @param {string} userId - L'ID de l'utilisateur
97 | */
98 | export async function openPlayerPrivacyPanel(page, userId) {
99 | // Le panel s'ouvre via les paramètres du module
100 | await openFoundrySidebar(page);
101 |
102 | // Naviguer vers les paramètres du module
103 | await clickFoundryButton(page, 'button:has-text("Video View Manager")');
104 | await page.waitForTimeout(1000);
105 |
106 | // Cliquer sur le bouton Player Privacy
107 | await clickFoundryButton(page, 'button:has-text("Player Privacy")');
108 |
109 | // Attendre le panel
110 | await page.waitForSelector('.sp-player-privacy-panel', {
111 | state: 'visible',
112 | timeout: 10000
113 | });
114 | }
115 |
116 | /**
117 | * Sélectionne un utilisateur dans une liste Foundry
118 | * @param {import('@playwright/test').Page} page - La page Playwright
119 | * @param {string} username - Le nom de l'utilisateur
```