mirror of
https://github.com/usebruno/bruno.git
synced 2026-06-22 20:25:38 +00:00
192 lines
7.9 KiB
TypeScript
192 lines
7.9 KiB
TypeScript
import { Page, expect } from '../../../playwright';
|
|
|
|
/**
|
|
* Reads test result counts from the filter buttons in the runner results view
|
|
* @param page - The Playwright page object
|
|
* @returns An object with totalRequests, passed, failed, and skipped counts
|
|
*/
|
|
export const getRunnerResultCounts = async (page: Page) => {
|
|
const allButton = page.locator('button').filter({ hasText: /^All/ });
|
|
const passedButton = page.locator('button').filter({ hasText: /^Passed/ });
|
|
const failedButton = page.locator('button').filter({ hasText: /^Failed/ });
|
|
const skippedButton = page.locator('button').filter({ hasText: /^Skipped/ });
|
|
|
|
const totalRequests = parseInt(await allButton.locator('span').innerText());
|
|
const passed = parseInt(await passedButton.locator('span').innerText());
|
|
const failed = parseInt(await failedButton.locator('span').innerText());
|
|
const skipped = parseInt(await skippedButton.locator('span').innerText());
|
|
|
|
return { totalRequests, passed, failed, skipped };
|
|
};
|
|
|
|
/**
|
|
* Runs a collection by clicking the Run menu item and handling the runner tab
|
|
* Includes logic to reset existing results if present
|
|
* @param page - The Playwright page object
|
|
* @param collectionName - The name of the collection to run
|
|
* @returns void
|
|
*/
|
|
export const runCollection = async (page: Page, collectionName: string) => {
|
|
// Ensure collection is visible and loaded
|
|
const collectionContainer = page.locator('.collection-name').filter({ hasText: collectionName });
|
|
await collectionContainer.waitFor({ state: 'visible' });
|
|
// Wait a bit for the UI to stabilize
|
|
await page.waitForTimeout(300);
|
|
|
|
// Open collection actions menu
|
|
await collectionContainer.locator('.collection-actions').hover();
|
|
const icon = collectionContainer.locator('.collection-actions .icon');
|
|
await icon.waitFor({ state: 'visible', timeout: 5000 });
|
|
await page.waitForTimeout(200); // Small delay to ensure hover state is stable
|
|
await icon.click();
|
|
|
|
// Click Run menu item
|
|
await page.getByText('Run', { exact: true }).click();
|
|
|
|
// Handle runner tab - reset if needed, then run
|
|
const resetButton = page.getByRole('button', { name: 'Reset' });
|
|
const runCollectionButton = page.getByRole('button', { name: 'Run Collection' });
|
|
|
|
// Check if Reset button is visible (means there are existing results)
|
|
const resetVisible = await resetButton.isVisible().catch(() => false);
|
|
if (resetVisible) {
|
|
await resetButton.click();
|
|
// Wait a bit for the reset to complete
|
|
await page.waitForTimeout(500);
|
|
}
|
|
|
|
// Now wait for and click Run Collection button
|
|
await runCollectionButton.waitFor({ state: 'visible', timeout: 10000 });
|
|
await runCollectionButton.click();
|
|
|
|
// Wait for the run to complete
|
|
await page.getByRole('button', { name: 'Run Again' }).waitFor({ timeout: 2 * 60 * 1000 });
|
|
};
|
|
|
|
/**
|
|
* Sets up the JavaScript sandbox mode for a collection
|
|
* @param page - The Playwright page object
|
|
* @param collectionName - The name of the collection (can be title or text)
|
|
* @param mode - 'developer' or 'safe' mode
|
|
* @returns void
|
|
*/
|
|
export const setSandboxMode = async (page: Page, collectionName: string, mode: 'developer' | 'safe') => {
|
|
// Click on the collection name - try sidebar first, then fall back to collection tab/name
|
|
// First try sidebar collection name (more reliable)
|
|
const sidebarCollection = page.locator('#sidebar-collection-name').filter({ hasText: collectionName });
|
|
const sidebarExists = await sidebarCollection.count().then((count) => count > 0).catch(() => false);
|
|
|
|
if (sidebarExists) {
|
|
await sidebarCollection.click();
|
|
} else {
|
|
// Fall back to collection by title or text
|
|
const collectionByTitle = page.getByTitle(collectionName);
|
|
const collectionByText = page.getByText(collectionName);
|
|
const titleExists = await collectionByTitle.count().then((count) => count > 0).catch(() => false);
|
|
if (titleExists) {
|
|
await collectionByTitle.click();
|
|
} else {
|
|
await collectionByText.click();
|
|
}
|
|
}
|
|
|
|
// Wait a moment for the UI to load
|
|
await page.waitForTimeout(300);
|
|
|
|
// Check if there's already a mode selected - if so, we need to click the badge to open settings tab
|
|
// Look for the Developer Mode or Safe Mode badge/button
|
|
const developerModeBadge = page.locator('.developer-mode').filter({ hasText: 'Developer Mode' });
|
|
const safeModeBadge = page.locator('.safe-mode').filter({ hasText: 'Safe Mode' });
|
|
|
|
const developerBadgeExists = await developerModeBadge.count().then((count) => count > 0).catch(() => false);
|
|
const safeBadgeExists = await safeModeBadge.count().then((count) => count > 0).catch(() => false);
|
|
|
|
// If a badge exists, click it to open the security settings tab
|
|
if (developerBadgeExists || safeBadgeExists) {
|
|
// Click the appropriate badge to open the security settings tab
|
|
if (developerBadgeExists) {
|
|
await developerModeBadge.click();
|
|
} else {
|
|
await safeModeBadge.click();
|
|
}
|
|
|
|
// Wait for the security settings tab to be active and form to be visible
|
|
// Look for the security settings content - it should have "JavaScript Sandbox" heading
|
|
await page.getByText('JavaScript Sandbox').waitFor({ state: 'visible', timeout: 10000 });
|
|
await page.waitForTimeout(300);
|
|
}
|
|
// If no badge exists, the modal should have appeared automatically (first time selection)
|
|
|
|
// Wait for security settings form to be visible - wait for either radio button
|
|
// These should be in the active tab (either modal or tab)
|
|
const safeModeRadio = page.getByLabel('Safe Mode');
|
|
const developerRadio = page.getByLabel('Developer Mode(use only if');
|
|
|
|
// Wait for at least one of them to be visible
|
|
await Promise.race([
|
|
safeModeRadio.waitFor({ state: 'visible', timeout: 10000 }).catch(() => {}),
|
|
developerRadio.waitFor({ state: 'visible', timeout: 10000 }).catch(() => {})
|
|
]);
|
|
|
|
// Additional wait to ensure UI is stable
|
|
await page.waitForTimeout(300);
|
|
|
|
if (mode === 'developer') {
|
|
await developerRadio.waitFor({ state: 'visible', timeout: 5000 });
|
|
await developerRadio.check();
|
|
} else {
|
|
// For safe mode, check if developer mode is currently selected
|
|
const developerModeChecked = await developerRadio.isChecked().catch(() => false);
|
|
|
|
if (developerModeChecked) {
|
|
// Click the Developer Mode label text inside the security settings form
|
|
// Scope to the form container to avoid clicking the badge
|
|
// The form should have the "JavaScript Sandbox" heading, so scope to that container
|
|
const securityForm = page.locator('div').filter({ hasText: 'JavaScript Sandbox' }).locator('..').first();
|
|
const developerLabel = securityForm.locator('label').filter({ hasText: /^Developer Mode/ }).first();
|
|
await developerLabel.waitFor({ state: 'visible', timeout: 5000 });
|
|
await developerLabel.click();
|
|
// Wait for UI to update
|
|
await page.waitForTimeout(300);
|
|
}
|
|
|
|
// Ensure Safe Mode radio is visible and check it
|
|
await safeModeRadio.waitFor({ state: 'visible', timeout: 5000 });
|
|
await safeModeRadio.check();
|
|
}
|
|
|
|
await page.getByRole('button', { name: 'Save' }).click();
|
|
};
|
|
|
|
/**
|
|
* Validates runner results against expected counts
|
|
* @param page - The Playwright page object
|
|
* @param expected - Expected counts
|
|
* @returns void
|
|
*/
|
|
export const validateRunnerResults = async (page: Page,
|
|
expected: {
|
|
totalRequests?: number;
|
|
passed?: number;
|
|
failed?: number;
|
|
skipped?: number;
|
|
}) => {
|
|
const { totalRequests, passed, failed, skipped } = await getRunnerResultCounts(page);
|
|
|
|
if (expected.totalRequests !== undefined) {
|
|
await expect(totalRequests).toBe(expected.totalRequests);
|
|
}
|
|
if (expected.passed !== undefined) {
|
|
await expect(passed).toBe(expected.passed);
|
|
}
|
|
if (expected.failed !== undefined) {
|
|
await expect(failed).toBe(expected.failed);
|
|
}
|
|
if (expected.skipped !== undefined) {
|
|
await expect(skipped).toBe(expected.skipped);
|
|
}
|
|
|
|
// Validate that passed + failed + skipped = totalRequests
|
|
await expect(passed).toBe(totalRequests - skipped - failed);
|
|
};
|