capture.mjs 95 lignes · 4319 octets
// Capture Playwright de l'UI gitrust pour la documentation.
//
// Usage :
//   GITRUST_USER=claude GITRUST_PASS='Pa33Word:' \
//   GITRUST_URL=https://gitrust.nuage.ebii \
//   node scripts/screenshot-runner/capture.mjs
//
// Sortie : docs/screenshots/*.png

import { chromium } from 'playwright';
import { mkdir } from 'node:fs/promises';
import { fileURLToPath } from 'node:url';
import { dirname, resolve } from 'node:path';

const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, '..', '..');
const OUT = resolve(ROOT, 'screenshots');

const URL = process.env.GITRUST_URL || 'https://gitrust.nuage.ebii';
const USER = process.env.GITRUST_USER || 'claude';
const PASS = process.env.GITRUST_PASS || 'Pa33Word:';

const SCREENS = [
  // Public
  { name: '001-home',                 path: '/',                                   auth: false },
  { name: '002-login',                path: '/login',                              auth: false },
  { name: '003-register',             path: '/register',                           auth: false },
  { name: '004-explore-public',       path: '/explore',                            auth: false },

  // Authentifié — user_manual
  { name: '100-dashboard',            path: '/dashboard',                          auth: true  },
  { name: '101-explore-repos',        path: '/explore',                            auth: true  },
  { name: '110-settings-profile',     path: '/settings/profile',                   auth: true  },
  { name: '111-settings-password',    path: '/settings/password',                  auth: true  },
  { name: '112-settings-security',    path: '/settings/security',                  auth: true  },
  { name: '113-settings-keys-ssh',    path: '/settings/keys',                      auth: true  },
  { name: '114-settings-tokens-pat',  path: '/settings/tokens',                    auth: true  },
  { name: '115-settings-sessions',    path: '/settings/sessions',                  auth: true  },
  { name: '116-settings-activity',    path: '/settings/activity',                  auth: true  },
  { name: '117-settings-preferences', path: '/settings/preferences',               auth: true  },
  { name: '118-settings-notifications',path: '/settings/notifications',            auth: true  },
  { name: '120-teams-new',            path: '/teams/new',                          auth: true  },

  // API docs (swagger)
  { name: '200-api-docs',             path: '/api/docs',                           auth: true  },
];

async function main() {
  await mkdir(OUT, { recursive: true });
  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    ignoreHTTPSErrors: true,
    viewport: { width: 1440, height: 900 },
    locale: 'fr-FR',
  });
  const page = await context.newPage();

  // Login
  console.log('→ login');
  await page.goto(URL + '/login', { waitUntil: 'networkidle' });
  await page.fill('input[name="username"], input[name="login"], input[type="text"]', USER);
  await page.fill('input[name="password"], input[type="password"]', PASS);
  await Promise.all([
    page.waitForURL(/\/(dashboard|login\/2fa|$)/, { timeout: 10000 }).catch(() => {}),
    page.click('button[type="submit"], input[type="submit"]'),
  ]);
  const loggedUrl = page.url();
  console.log('  logged in, landed on', loggedUrl);

  for (const s of SCREENS) {
    try {
      const url = URL + s.path;
      console.log(`→ ${s.name}: ${url}`);

      if (!s.auth) {
        // Use a fresh unauth context for public pages
        const publicCtx = await browser.newContext({ ignoreHTTPSErrors: true, viewport: { width: 1440, height: 900 } });
        const pubPage = await publicCtx.newPage();
        await pubPage.goto(url, { waitUntil: 'networkidle', timeout: 15000 });
        await pubPage.screenshot({ path: `${OUT}/${s.name}.png`, fullPage: true });
        await publicCtx.close();
      } else {
        await page.goto(url, { waitUntil: 'networkidle', timeout: 15000 });
        await page.screenshot({ path: `${OUT}/${s.name}.png`, fullPage: true });
      }
    } catch (e) {
      console.warn(`  ✗ ${s.name}: ${e.message}`);
    }
  }

  await browser.close();
  console.log('\n✓ captures écrites dans', OUT);
}

main().catch(e => { console.error(e); process.exit(1); });