141 lines
5.3 KiB
Markdown
141 lines
5.3 KiB
Markdown
# 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-4: AV Tile Visual State Indicators >> Self-muted state shows camera-off icon
|
|
- Location: specs/epic-1-visibility.spec.js:132:5
|
|
|
|
# Error details
|
|
|
|
```
|
|
Error: page.waitForFunction: Test ended.
|
|
```
|
|
|
|
# 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 ended.
|
|
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
|
|
``` |