All checks were successful
Publish FaceAI Container / publish (push) Successful in 4m43s
- Added a retry mechanism for page navigation in `live-site-test-utils.js` to handle transient errors during login. - Introduced a new function `performLiveLoginRequest` to handle login requests via API, improving the login flow. - Updated the login process to utilize the new API request method, ensuring a more robust authentication. - Implemented new utility functions in `rus-ecom-240621.js` for managing FaceAI state and filtering. - Created `faceai_photo_lookup.jsp` to handle photo lookups, returning JSON responses for better integration with the frontend. - Updated `faceai_return.php` to redirect users with appropriate parameters after FaceAI processing. - Modified `fotoCR.jsp` and `fotoCR-en.jsp` to include FaceAI photo IDs in the image elements for better tracking. - Enhanced the UI to display the number of matched photos dynamically based on FaceAI results.
173 lines
No EOL
5.8 KiB
JavaScript
173 lines
No EOL
5.8 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const { expect } = require('@playwright/test');
|
|
|
|
const WORKSPACE_ROOT = path.resolve(__dirname, '..', '..', '..');
|
|
const LIVE_SITE_BASE_URL = process.env.LIVE_SITE_BASE_URL || 'https://www.regalamiunsorriso.it';
|
|
const LIVE_SITE_LOGIN_URL = process.env.LIVE_SITE_LOGIN_URL || `${LIVE_SITE_BASE_URL}/login_clienti-it.html`;
|
|
const LIVE_SITE_RACE_URL = process.env.LIVE_SITE_RACE_URL || `${LIVE_SITE_BASE_URL}/42%20HALF%20MARATHON%20FIRENZE_gara-1018545---96-1.html`;
|
|
const LIVE_FACEAI_BASE_URL = process.env.LIVE_FACEAI_BASE_URL || 'https://ai.regalamiunsorriso.it';
|
|
const LIVE_SITE_RESULT_URL_PATTERN = process.env.LIVE_SITE_RESULT_URL_PATTERN || `${LIVE_SITE_BASE_URL}/faceai_return.php`;
|
|
const LIVE_SITE_USERNAME = process.env.LIVE_SITE_USERNAME || '';
|
|
const LIVE_SITE_PASSWORD = process.env.LIVE_SITE_PASSWORD || '';
|
|
const LIVE_SITE_PORTRAIT_PATH = process.env.LIVE_SITE_PORTRAIT_PATH || path.join(WORKSPACE_ROOT, 'test_pkl', 'live', 'test_portrait_1.png');
|
|
const LIVE_SITE_RUN_UPLOAD_FLOW = process.env.LIVE_SITE_RUN_UPLOAD_FLOW === '1';
|
|
const AUTH_FILE = path.join(__dirname, '.auth', 'user.json');
|
|
|
|
function ensureAuthDirectory() {
|
|
fs.mkdirSync(path.dirname(AUTH_FILE), { recursive: true });
|
|
}
|
|
|
|
function requireCredentials() {
|
|
if (!LIVE_SITE_USERNAME || !LIVE_SITE_PASSWORD) {
|
|
throw new Error('LIVE_SITE_USERNAME and LIVE_SITE_PASSWORD must be set before running the live-site Playwright suite.');
|
|
}
|
|
}
|
|
|
|
async function dismissCookieBanner(page) {
|
|
const cookieButton = page.getByRole('button', { name: /^(Accetto|Accept)$/i });
|
|
if (await cookieButton.count()) {
|
|
await cookieButton.first().click({ timeout: 5000 }).catch(() => {});
|
|
return;
|
|
}
|
|
|
|
const fallbackButton = page.locator('.cc-btn, .cc-dismiss, .cc-allow').filter({ hasText: /Accetto|Accept/i });
|
|
if (await fallbackButton.count()) {
|
|
await fallbackButton.first().click({ timeout: 5000 }).catch(() => {});
|
|
}
|
|
}
|
|
|
|
function loginSubmitLocator(page) {
|
|
return page.locator('a.btn').filter({ hasText: /Accedi|Sign in/i }).first();
|
|
}
|
|
|
|
function buildLoginFormData() {
|
|
requireCredentials();
|
|
return {
|
|
login: LIVE_SITE_USERNAME,
|
|
pwd: LIVE_SITE_PASSWORD,
|
|
cmdIU: 'check',
|
|
act: '',
|
|
thePage: ''
|
|
};
|
|
}
|
|
|
|
async function gotoWithRetry(page, url, options = {}, maxAttempts = 3) {
|
|
let lastError = null;
|
|
|
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
try {
|
|
await page.goto(url, options);
|
|
return;
|
|
} catch (error) {
|
|
lastError = error;
|
|
if (!/ERR_ABORTED/i.test(String(error)) || attempt === maxAttempts) {
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
throw lastError;
|
|
}
|
|
|
|
async function performLiveLogin(page) {
|
|
requireCredentials();
|
|
|
|
await gotoWithRetry(page, LIVE_SITE_LOGIN_URL, { waitUntil: 'commit' });
|
|
await dismissCookieBanner(page);
|
|
await page.locator('#login').fill(LIVE_SITE_USERNAME);
|
|
await page.locator('#pwd').fill(LIVE_SITE_PASSWORD);
|
|
await loginSubmitLocator(page).click();
|
|
await waitForLoggedInUi(page);
|
|
}
|
|
|
|
async function performLiveLoginRequest(requestContext) {
|
|
const response = await requestContext.post(`${LIVE_SITE_BASE_URL}/Logon.abl`, {
|
|
form: buildLoginFormData(),
|
|
failOnStatusCode: false
|
|
});
|
|
|
|
const finalUrl = response.url();
|
|
const bodyText = await response.text();
|
|
|
|
if (!response.ok()) {
|
|
throw new Error(`Live login request failed with HTTP ${response.status()} at ${finalUrl}`);
|
|
}
|
|
|
|
if (/login_clienti|Username \/ Email|Password/iu.test(bodyText) && !/user_logout|dettaglio_clienti|Il mio account/iu.test(bodyText)) {
|
|
throw new Error(`Live login request appears to have remained on the login page at ${finalUrl}`);
|
|
}
|
|
}
|
|
|
|
async function waitForLoggedInUi(page) {
|
|
const accountMenu = page.locator('#navbarDropdownMenuLink');
|
|
const accountLink = page.locator('a[href*="dettaglio_clienti"]');
|
|
const logoutLink = page.locator('a[href*="user_logout"]');
|
|
|
|
await expect.poll(async () => {
|
|
if (await accountMenu.count() && await accountMenu.first().isVisible().catch(() => false)) {
|
|
return 'account-menu';
|
|
}
|
|
if (await accountLink.count() && await accountLink.first().isVisible().catch(() => false)) {
|
|
return 'account-link';
|
|
}
|
|
if (await logoutLink.count() && await logoutLink.first().isVisible().catch(() => false)) {
|
|
return 'logout-link';
|
|
}
|
|
return '';
|
|
}, {
|
|
timeout: 30 * 1000,
|
|
message: 'Expected the logged-in account UI to appear after authenticating.'
|
|
}).not.toBe('');
|
|
}
|
|
|
|
async function expectRacePageLoaded(page) {
|
|
await expect(page.locator('form[onsubmit="return searching()"]')).toBeVisible();
|
|
await expect(page.locator('#id_gara')).toHaveValue(/\d+/);
|
|
await expect(page.locator('script[src*="_js/rus-ecom-240621.js"]')).toHaveCount(1);
|
|
}
|
|
|
|
async function ensureLiveAuthenticatedRacePage(page) {
|
|
await gotoWithRetry(page, LIVE_SITE_RACE_URL, { waitUntil: 'commit' });
|
|
await dismissCookieBanner(page);
|
|
|
|
try {
|
|
await waitForLoggedInUi(page);
|
|
} catch (error) {
|
|
await performLiveLoginRequest(page.context().request);
|
|
await gotoWithRetry(page, LIVE_SITE_RACE_URL, { waitUntil: 'commit' });
|
|
await dismissCookieBanner(page);
|
|
await waitForLoggedInUi(page);
|
|
}
|
|
|
|
await expectRacePageLoaded(page);
|
|
}
|
|
|
|
function requirePortraitFixture() {
|
|
if (!fs.existsSync(LIVE_SITE_PORTRAIT_PATH)) {
|
|
throw new Error(`LIVE_SITE_PORTRAIT_PATH does not exist: ${LIVE_SITE_PORTRAIT_PATH}`);
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
AUTH_FILE,
|
|
LIVE_FACEAI_BASE_URL,
|
|
LIVE_SITE_BASE_URL,
|
|
LIVE_SITE_LOGIN_URL,
|
|
LIVE_SITE_PASSWORD,
|
|
LIVE_SITE_PORTRAIT_PATH,
|
|
LIVE_SITE_RACE_URL,
|
|
LIVE_SITE_RESULT_URL_PATTERN,
|
|
LIVE_SITE_RUN_UPLOAD_FLOW,
|
|
LIVE_SITE_USERNAME,
|
|
dismissCookieBanner,
|
|
ensureLiveAuthenticatedRacePage,
|
|
ensureAuthDirectory,
|
|
expectRacePageLoaded,
|
|
loginSubmitLocator,
|
|
performLiveLogin,
|
|
performLiveLoginRequest,
|
|
requirePortraitFixture,
|
|
requireCredentials,
|
|
waitForLoggedInUi
|
|
}; |