74 lines
3.1 KiB
JavaScript
74 lines
3.1 KiB
JavaScript
// @ts-check
|
|
import { test, expect } from '@playwright/test';
|
|
import { loadTestUser } from '../utils/testUser.js';
|
|
|
|
test.describe('@p0 Support — submit ticket', () => {
|
|
test.setTimeout(20000);
|
|
|
|
test('open → fill form → submit → success (network or UI)', async ({ page }) => {
|
|
const user = loadTestUser();
|
|
const stamp = new Date().toISOString().replace(/[-:TZ.]/g, '');
|
|
|
|
// Sign in
|
|
await page.context().clearCookies();
|
|
await page.goto('/signin', { waitUntil: 'networkidle' });
|
|
await page.getByPlaceholder('Username', { exact: true }).fill(user.username);
|
|
await page.getByPlaceholder('Password', { exact: true }).fill(user.password);
|
|
await page.getByRole('button', { name: /^Sign In$/ }).click();
|
|
await page.waitForURL('**/signin-landing**', { timeout: 15000 });
|
|
|
|
// Open Support
|
|
const supportBtn = page.getByRole('button', { name: /^Support$/i }).or(page.getByText(/^Support$/i));
|
|
await supportBtn.click();
|
|
|
|
const overlay = page.locator('div.fixed.inset-0').first();
|
|
await expect(overlay).toBeVisible({ timeout: 5000 });
|
|
const dlg = overlay.locator('div[role="dialog"], div.bg-white').first();
|
|
|
|
// Fill Subject/Message (tolerant selectors)
|
|
const subj = dlg.getByLabel(/Subject/i)
|
|
.or(dlg.getByPlaceholder(/Subject/i))
|
|
.or(dlg.locator('input[type="text"]'))
|
|
.first();
|
|
const msg = dlg.getByLabel(/(Message|Describe|How can we help)/i)
|
|
.or(dlg.locator('textarea'))
|
|
.first();
|
|
|
|
await subj.fill(`E2E support ${stamp}`);
|
|
await msg.fill(`Automated E2E support test at ${stamp}. Please ignore. User=${user.username}`);
|
|
|
|
// Submit button
|
|
const send = dlg.getByRole('button', { name: /(Send|Submit|Send message|Submit ticket|Send request)/i }).first();
|
|
await expect(send).toBeEnabled({ timeout: 5000 });
|
|
|
|
// Start the response wait **before** clicking
|
|
const respPromise = page.waitForResponse(r =>
|
|
r.request().method() === 'POST' && /\/api\/support$/.test(r.url()),
|
|
{ timeout: 15000 }
|
|
).catch(() => null);
|
|
|
|
await send.click();
|
|
|
|
// Consider success if we saw a POST with a reasonable status
|
|
const resp = await respPromise;
|
|
const okStatus = resp ? [200, 201, 202, 204, 409, 429].includes(resp.status()) : false;
|
|
|
|
// Also allow UI signals
|
|
const successText = page.getByText(/(thanks|we'll get back|message sent|received)/i).first();
|
|
const successShown = await successText.isVisible({ timeout: 3000 }).catch(() => false);
|
|
|
|
// Close the overlay (cover multiple close mechanisms)
|
|
const closeByText = dlg.getByRole('button', { name: /(Close|Done|OK|Cancel|Dismiss)/i }).first();
|
|
const closeByAria = dlg.locator('[aria-label="Close"], [aria-label="close"]').first();
|
|
if (await closeByText.isVisible({ timeout: 500 }).catch(() => false)) {
|
|
await closeByText.click();
|
|
} else if (await closeByAria.isVisible({ timeout: 200 }).catch(() => false)) {
|
|
await closeByAria.click();
|
|
} else {
|
|
await page.keyboard.press('Escape');
|
|
}
|
|
const overlayHidden = await overlay.isHidden({ timeout: 8000 }).catch(() => false);
|
|
|
|
expect(okStatus || successShown || overlayHidden).toBeTruthy();
|
|
});
|
|
}); |