Story 4.2: Fix lint errors and code review findings
- Remove unused StripOverlayLayer import and stripOverlayLayer variable from module.js - Add comprehensive JSDoc annotations to FoundryAdapter.js methods (settings, socket, users, scenes, notifications, hooks) - Add /* global Dialog */ comment to PlayerPrivacyPanel.js for ESLint - Remove unused _force parameter from GMPlayerPrivacySelector.js render() method - Fix PlayerPrivacyPanelMenu.js: add constructor() to fallback class and call super() All 862 unit tests passing. All Story 4.2 acceptance criteria met. Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
@@ -0,0 +1,338 @@
|
||||
/**
|
||||
* Module Initialization Tests - Tests E2E
|
||||
*
|
||||
* Vérifie que le module Video View Manager s'initialise correctement
|
||||
* dans FoundryVTT et que toutes les fonctionnalités de base sont disponibles.
|
||||
*/
|
||||
|
||||
import { test, expect } from '@playwright/test';
|
||||
import {
|
||||
waitForFoundryReady,
|
||||
waitForVVMModule,
|
||||
clickFoundryButton,
|
||||
} from '../utils/foundry-helpers';
|
||||
|
||||
const MODULE_ID = 'video-view-manager';
|
||||
const MODULE_NAME = 'Video View Manager';
|
||||
|
||||
test.describe('Module Initialization', () => {
|
||||
test.setTimeout(60000);
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('https://localhost:31000', {
|
||||
waitUntil: 'domcontentloaded',
|
||||
timeout: 30000,
|
||||
});
|
||||
|
||||
await waitForFoundryReady(page);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Initialisation de base
|
||||
// ============================================================================
|
||||
|
||||
test('Module is registered in FoundryVTT', async ({ page }) => {
|
||||
const module = await page.evaluate((moduleId) => {
|
||||
return game.modules?.get(moduleId);
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(module).toBeTruthy();
|
||||
expect(module?.id).toBe(MODULE_ID);
|
||||
});
|
||||
|
||||
test('Module has correct name', async ({ page }) => {
|
||||
const module = await page.evaluate((moduleId) => {
|
||||
return game.modules?.get(moduleId);
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(module?.data?.title).toContain(MODULE_NAME);
|
||||
});
|
||||
|
||||
test('Module is active', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const isActive = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
return module?.active;
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(isActive).toBe(true);
|
||||
});
|
||||
|
||||
test('Module loads without errors', async ({ page }) => {
|
||||
// Vérifier qu'il n'y a pas d'erreurs dans la console
|
||||
const errors = [];
|
||||
|
||||
page.on('console', msg => {
|
||||
if (msg.type() === 'error') {
|
||||
errors.push(msg.text());
|
||||
}
|
||||
});
|
||||
|
||||
await waitForVVMModule(page);
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
// Filtrer les erreurs connues (qui ne sont pas liées à notre module)
|
||||
const vvmErrors = errors.filter(err => err.includes('ScryingPool') || err.includes(MODULE_ID));
|
||||
|
||||
expect(vvmErrors).toHaveLength(0);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Vérification des composants
|
||||
// ============================================================================
|
||||
|
||||
test('ScryingPoolStrip is available for GM', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const isGM = await page.evaluate(() => game.user?.isGM || false);
|
||||
|
||||
if (isGM) {
|
||||
// L'application ScryingPoolStrip devrait être enregistrée
|
||||
const app = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
if (module && module.api?.roleRenderer) {
|
||||
return module.api.roleRenderer._strip;
|
||||
}
|
||||
return null;
|
||||
}, MODULE_ID);
|
||||
|
||||
// Devrait exister après l'initialisation
|
||||
expect(app).toBeTruthy();
|
||||
}
|
||||
});
|
||||
|
||||
test('VisibilityBadges are injected into AV tiles', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
// Attendre que les badges soient injectés
|
||||
await page.waitForSelector('.sp-visibility-badge', {
|
||||
state: 'visible',
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
const badges = page.locator('.sp-visibility-badge');
|
||||
expect(await badges.count()).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('ScryingPoolController is initialized', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const controller = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
return module?.api?.controller;
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(controller).toBeTruthy();
|
||||
});
|
||||
|
||||
test('StateStore is initialized with correct data', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const stateStore = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
return module?.api?.stateStore;
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(stateStore).toBeTruthy();
|
||||
|
||||
// Vérifier que la matrice de visibilité existe
|
||||
const matrix = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
if (module?.api?.stateStore) {
|
||||
return module.api.stateStore.getMatrix();
|
||||
}
|
||||
return null;
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(matrix).toBeTruthy();
|
||||
expect(matrix).toHaveProperty('_version');
|
||||
expect(matrix).toHaveProperty('matrix');
|
||||
});
|
||||
|
||||
test('SocketHandler is registered', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const socketHandler = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
return module?.api?.socketHandler;
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(socketHandler).toBeTruthy();
|
||||
});
|
||||
|
||||
test('VisibilityManager is initialized', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const visibilityManager = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
return module?.api?.visibilityManager;
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(visibilityManager).toBeTruthy();
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Vérification des paramètres
|
||||
// ============================================================================
|
||||
|
||||
test('World settings are registered', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const settings = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
if (module) {
|
||||
return Array.from(game.settings.settings.entries())
|
||||
.filter(([key]) => key.startsWith(`${moduleId}.`))
|
||||
.map(([key, value]) => key);
|
||||
}
|
||||
return [];
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(settings.length).toBeGreaterThan(0);
|
||||
expect(settings).toContain(`${MODULE_ID}.webrtcMode`);
|
||||
});
|
||||
|
||||
test('Client settings are registered', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const clientSettings = await page.evaluate((moduleId, userId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
if (module && game.users?.get(userId)) {
|
||||
const user = game.users.get(userId);
|
||||
return Array.from(user.getSettings().entries())
|
||||
.filter(([key]) => key.includes(moduleId))
|
||||
.map(([key]) => key);
|
||||
}
|
||||
return [];
|
||||
}, MODULE_ID, 'gamemaster');
|
||||
|
||||
expect(clientSettings.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Vérification des menus
|
||||
// ============================================================================
|
||||
|
||||
test('GM Player Privacy Selector menu is registered', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const isGM = await page.evaluate(() => game.user?.isGM || false);
|
||||
|
||||
if (isGM) {
|
||||
// Le menu devrait être disponible dans les paramètres
|
||||
const menuItem = page.locator('button:has-text("Player Privacy")');
|
||||
await expect(menuItem).toBeVisible({ timeout: 10000 });
|
||||
}
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Vérification des hooks
|
||||
// ============================================================================
|
||||
|
||||
test('Hooks are registered correctly', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
// Vérifier que les hooks sont enregistrés
|
||||
const hooks = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
if (module && game.hooks) {
|
||||
const hookEvents = [];
|
||||
for (const [event, handlers] of game.hooks.events.entries()) {
|
||||
if (event.startsWith('scrying-pool.')) {
|
||||
hookEvents.push(event);
|
||||
}
|
||||
}
|
||||
return hookEvents;
|
||||
}
|
||||
return [];
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(hooks.length).toBeGreaterThan(0);
|
||||
expect(hooks).toContain('scrying-pool:stateChanged');
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Vérification des styles
|
||||
// ============================================================================
|
||||
|
||||
test('Module CSS is loaded', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
// Vérifier qu'une classe CSS du module existe
|
||||
const element = page.locator('.scrying-pool');
|
||||
|
||||
// Devrait exister même s'il n'est pas visible
|
||||
expect(await element.count()).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test('Design tokens are defined', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const tokens = await page.evaluate(() => {
|
||||
const style = getComputedStyle(document.documentElement);
|
||||
const tokenNames = [
|
||||
'--sp-surface',
|
||||
'--sp-border',
|
||||
'--sp-text-primary',
|
||||
'--sp-text-secondary',
|
||||
'--sp-accent',
|
||||
];
|
||||
|
||||
return tokenNames.filter(name => style.getPropertyValue(name).trim() !== '');
|
||||
});
|
||||
|
||||
expect(tokens.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Vérification des templates
|
||||
// ============================================================================
|
||||
|
||||
test('Handlebars templates are precompiled', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
// Vérifier que les templates sont disponibles
|
||||
const templates = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
if (module && game.templates) {
|
||||
const templatePrefix = `modules/${moduleId}/templates/`;
|
||||
return Array.from(game.templates.cache.keys())
|
||||
.filter(key => key.startsWith(templatePrefix))
|
||||
.map(key => key.replace(templatePrefix, ''));
|
||||
}
|
||||
return [];
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(templates.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Vérification des localisations
|
||||
// ============================================================================
|
||||
|
||||
test('Localization strings are available', async ({ page }) => {
|
||||
await waitForVVMModule(page);
|
||||
|
||||
const i18nKeys = await page.evaluate((moduleId) => {
|
||||
const module = game.modules?.get(moduleId);
|
||||
if (module && game.i18n) {
|
||||
const langData = game.i18n.getLanguages();
|
||||
const moduleKeys = [];
|
||||
|
||||
for (const [lang, translations] of Object.entries(langData)) {
|
||||
for (const [key] of Object.entries(translations)) {
|
||||
if (key.startsWith(`${moduleId}.`)) {
|
||||
moduleKeys.push(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return moduleKeys;
|
||||
}
|
||||
return [];
|
||||
}, MODULE_ID);
|
||||
|
||||
expect(i18nKeys.length).toBeGreaterThan(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user