This commit is contained in:
+187
@@ -0,0 +1,187 @@
|
||||
# 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
|
||||
|
||||
```
|
||||
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 à l’accueil" [level=2] [ref=e35]
|
||||
- textbox [ref=e39]
|
||||
- contentinfo [ref=e40]:
|
||||
- button "Retour à l’accueil" [ref=e41] [cursor=pointer]:
|
||||
- generic: Retour à l’accueil
|
||||
- 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
|
||||
```
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+187
@@ -0,0 +1,187 @@
|
||||
# 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 >> Visibility change is immediate (no layout shift)
|
||||
- Location: specs/epic-1-visibility.spec.js:92: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 à l’accueil" [level=2] [ref=e35]
|
||||
- textbox [ref=e39]
|
||||
- contentinfo [ref=e40]:
|
||||
- button "Retour à l’accueil" [ref=e41] [cursor=pointer]:
|
||||
- generic: Retour à l’accueil
|
||||
- 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
|
||||
```
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+187
@@ -0,0 +1,187 @@
|
||||
# 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 show a hidden participant via right-click
|
||||
- Location: specs/epic-1-visibility.spec.js:76: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 à l’accueil" [level=2] [ref=e35]
|
||||
- textbox [ref=e39]
|
||||
- contentinfo [ref=e40]:
|
||||
- button "Retour à l’accueil" [ref=e41] [cursor=pointer]:
|
||||
- generic: Retour à l’accueil
|
||||
- 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
|
||||
```
|
||||
BIN
Binary file not shown.
+187
@@ -0,0 +1,187 @@
|
||||
# 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 à l’accueil" [level=2] [ref=e35]
|
||||
- textbox [ref=e39]
|
||||
- contentinfo [ref=e40]:
|
||||
- button "Retour à l’accueil" [ref=e41] [cursor=pointer]:
|
||||
- generic: Retour à l’accueil
|
||||
- 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
|
||||
```
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
# 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 >> Hidden state shows grey overlay + lock icon + tooltip
|
||||
- Location: specs/epic-1-visibility.spec.js:115: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 à l’accueil" [level=2] [ref=e35]
|
||||
- textbox [ref=e39]
|
||||
- contentinfo [ref=e40]:
|
||||
- button "Retour à l’accueil" [ref=e41] [cursor=pointer]:
|
||||
- generic: Retour à l’accueil
|
||||
- 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
|
||||
```
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
+141
@@ -0,0 +1,141 @@
|
||||
# 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
|
||||
```
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
|
After Width: | Height: | Size: 316 KiB |
BIN
Binary file not shown.
Reference in New Issue
Block a user