Skip to content

Commit

Permalink
vp test: adding new test to handle ESM page + small refactoring (#684)
Browse files Browse the repository at this point in the history
* vp test: adding new test to handle ESM page + small refactoring

* vp test: remove flaky adaptive streaming

* vp test: remove skip from ESM profile page and skip adaptive streaming
  • Loading branch information
ShayLevi authored Jul 18, 2024
1 parent 945366f commit afa898f
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 36 deletions.
37 changes: 4 additions & 33 deletions test/e2e/specs/linksConsolErros.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { ConsoleMessage, Page, expect } from '@playwright/test';
import { ConsoleMessage, expect } from '@playwright/test';
import { vpTest } from '../fixtures/vpTest';
import { LINKS } from '../testData/pageLinksData';
import { waitForPageToLoadWithTimeout } from '../src/helpers/waitForPageToLoadWithTimeout';
import { validatePageErrors } from '../src/helpers/validatePageErrors';

/**
* Console error test generated by LINKS object array data.
*/
for (const link of LINKS) {
vpTest(`Test console errors on link ${link.name}`, async ({ page, consoleErrors, vpExamples }) => {
vpTest.skip(link.name === 'Adaptive Streaming', 'Flaky on CI');
await vpExamples.clickLinkByName(link.name);
await waitForPageToLoadWithTimeout(page, 5000);
expect(page.url()).toContain(link.endpoint);
Expand Down Expand Up @@ -45,35 +48,3 @@ function handleCommonBrowsersErrors(linkName: string, consoleErrors: ConsoleMess
expect(consoleErrors, `The following unexpected console errors were found: ${JSON.stringify(consoleErrors)}`).toHaveLength(0);
}
}

/**
* Wait until there are no network connections for at least 5000 ms or for given timeout to pass.
* Needed for console logs to appear. and in pages that loading video 'waitForLoadState('networkidle')' entering a long loop.
*/
async function waitForPageToLoadWithTimeout(page: Page, timeout: number): Promise<unknown> {
return Promise.race([page.waitForLoadState('networkidle'), new Promise((r) => setTimeout(r, timeout))]);
}

/**
* Validating that the expected error is part of the console errors
*/
function validatePageErrors(consoleErrors: ConsoleMessage[], expectedErrorMessages: string[], ignoreErrorMessages: string[]): void {
/**
* Filters console messages to exclude ignored messages
*/
const relevantMessages = consoleErrors.filter((consoleError) => !ignoreErrorMessages.some((ignoreError) => consoleError.text().includes(ignoreError)));

/**
* Filters expected error messages that are not found in relevant console messages
*/
const missingExpectedErrors = expectedErrorMessages.filter((expectedErrorMessage) => !relevantMessages.some((relevantError) => relevantError.text().includes(expectedErrorMessage)));

expect(missingExpectedErrors.length, `The following expected console errors were not found: ${JSON.stringify(missingExpectedErrors)}`).toBe(0);

/**
* Filters relevant console messages that are not part of the expected error messages
*/
const unexpectedErrors = relevantMessages.filter((relevantError) => !expectedErrorMessages.some((expectedErrorMessage) => relevantError.text().includes(expectedErrorMessage)));

expect(unexpectedErrors.length, `The following unexpected console errors were found: ${JSON.stringify(unexpectedErrors)}`).toBe(0);
}
52 changes: 52 additions & 0 deletions test/e2e/specs/linksConsoleErrorsEsmPage.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { ConsoleMessage, expect } from '@playwright/test';
import { vpTest } from '../fixtures/vpTest';
import { ESM_LINKS } from '../testData/esmPageLinksData';
import { waitForPageToLoadWithTimeout } from '../src/helpers/waitForPageToLoadWithTimeout';
import { validatePageErrors } from '../src/helpers/validatePageErrors';

const ESM_URL = 'https://cld-vp-esm-pages.netlify.app/';
/**
* Console error test generated by LINKS object array data.
*/
for (const link of ESM_LINKS) {
vpTest(`Test console errors on link ${link.name}`, async ({ page, consoleErrors, vpExamples }) => {
vpTest.skip(link.name === 'Adaptive Streaming', 'Flaky on CI');
/**
* Navigate to ESM Imports examples page
*/
await page.goto(ESM_URL);
await vpExamples.clickLinkByName(link.name);
await waitForPageToLoadWithTimeout(page, 5000);
expect(page.url()).toContain(link.endpoint);
handleCommonEsmBrowsersErrors(link.name, consoleErrors);
});
}

/**
* Testing number of links in page.
*/
vpTest('ESM page Link count test', async ({ page }) => {
await page.goto(ESM_URL);
const expectedNumberOfLinks = 32;
const numberOfLinks = await page.getByRole('link').count();
expect(numberOfLinks).toBe(expectedNumberOfLinks);
});
/**
* Helper function to handle common browser errors.
*/
function handleCommonEsmBrowsersErrors(linkName: string, consoleErrors: ConsoleMessage[]) {
switch (linkName) {
case 'Custom Errors':
validatePageErrors(
consoleErrors,
['(CODE:999 undefined) My custom error message'],
['No compatible source was found for this media', 'Video cannot be played Public ID snow_horses not found', 'the server responded with a status of 404', 'Cannot read properties of undefined']
);
break;
case 'VAST & VPAID Support':
validatePageErrors(consoleErrors, [], ["Blocked script execution in 'about:blank' because the document's frame is sandboxed and the 'allow-scripts' permission is not set"]);
break;
default:
expect(consoleErrors, `The following unexpected console errors were found: ${JSON.stringify(consoleErrors)}`).toHaveLength(0);
}
}
25 changes: 25 additions & 0 deletions test/e2e/src/helpers/validatePageErrors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ConsoleMessage, expect } from '@playwright/test';

/**
* Validating that the expected error is part of the console errors
*/
export function validatePageErrors(consoleErrors: ConsoleMessage[], expectedErrorMessages: string[], ignoreErrorMessages: string[]): void {
/**
* Filters console messages to exclude ignored messages
*/
const relevantMessages = consoleErrors.filter((consoleError) => !ignoreErrorMessages.some((ignoreError) => consoleError.text().includes(ignoreError)));

/**
* Filters expected error messages that are not found in relevant console messages
*/
const missingExpectedErrors = expectedErrorMessages.filter((expectedErrorMessage) => !relevantMessages.some((relevantError) => relevantError.text().includes(expectedErrorMessage)));

expect(missingExpectedErrors.length, `The following expected console errors were not found: ${JSON.stringify(missingExpectedErrors)}`).toBe(0);

/**
* Filters relevant console messages that are not part of the expected error messages
*/
const unexpectedErrors = relevantMessages.filter((relevantError) => !expectedErrorMessages.some((expectedErrorMessage) => relevantError.text().includes(expectedErrorMessage)));

expect(unexpectedErrors.length, `The following unexpected console errors were found: ${JSON.stringify(unexpectedErrors)}`).toBe(0);
}
9 changes: 9 additions & 0 deletions test/e2e/src/helpers/waitForPageToLoadWithTimeout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Page } from '@playwright/test';

/**
* Wait until there are no network connections for at least 5000 ms or for given timeout to pass.
* Needed for console logs to appear. and in pages that loading video 'waitForLoadState('networkidle')' entering a long loop.
*/
export async function waitForPageToLoadWithTimeout(page: Page, timeout: number): Promise<unknown> {
return Promise.race([page.waitForLoadState('networkidle'), new Promise((r) => setTimeout(r, timeout))]);
}
39 changes: 39 additions & 0 deletions test/e2e/testData/esmPageLinksData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { ExampleLinkType } from '../types/exampleLinkType';

/**
* Array of all the examples pages names and links on ESM import page.
*/
export const ESM_LINKS: ExampleLinkType[] = [
{ name: 'Adaptive Streaming', endpoint: 'adaptive-streaming' },
{ name: 'Analytics', endpoint: 'analytics' },
{ name: 'API and Events', endpoint: 'api' },
{ name: 'Audio Player', endpoint: 'audio' },
{ name: 'Autoplay on Scroll', endpoint: 'autoplay-on-scroll' },
{ name: 'Chapters', endpoint: 'chapters' },
{ name: 'Cloudinary Analytics', endpoint: 'cloudinary-analytics' },
{ name: 'Codecs and formats', endpoint: 'codec-formats' },
{ name: 'Colors API', endpoint: 'colors' },
{ name: 'Components', endpoint: 'components' },
{ name: 'Custom Errors', endpoint: 'custom-cld-errors' },
{ name: 'Display Configurations', endpoint: 'ui-config' },
{ name: 'Debug', endpoint: 'debug' },
{ name: 'Floating Player', endpoint: 'floating-player' },
{ name: 'Fluid Layouts', endpoint: 'fluid' },
{ name: 'Force HLS Subtitles', endpoint: 'force-hls-subtitles' },
{ name: 'Highlights Graph', endpoint: 'highlights-graph' },
{ name: 'Interaction Area', endpoint: 'interaction-area' },
{ name: 'Multiple Players', endpoint: 'multiple-players' },
{ name: 'Playlist', endpoint: 'playlist' },
{ name: 'Playlist by Tag', endpoint: 'playlist-by-tag' },
{ name: 'Poster Options', endpoint: 'poster' },
{ name: 'Profiles', endpoint: 'profiles' },
{ name: 'Raw URL', endpoint: 'raw-url' },
{ name: 'Recommendations', endpoint: 'recommendations' },
{ name: 'Seek Thumbnails', endpoint: 'seek-thumbs' },
{ name: 'Shoppable Videos', endpoint: 'shoppable' },
{ name: 'Subtitles & Captions', endpoint: 'subtitles-and-captions' },
{ name: 'Video Transformations', endpoint: 'transformations' },
{ name: 'UI Config', endpoint: 'ui-config' },
{ name: 'VAST & VPAID Support', endpoint: 'vast-vpaid' },
{ name: 'VR/360 Videos', endpoint: '360' },
];
6 changes: 3 additions & 3 deletions test/e2e/testData/pageLinksData.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
type Link = { name: string; endpoint: string };
import { ExampleLinkType } from '../types/exampleLinkType';

/**
* Array of all the examples pages names and links.
*/
export const LINKS: Link[] = [
//{ name: 'Adaptive Streaming', endpoint: 'adaptive-streaming.html' },
export const LINKS: ExampleLinkType[] = [
{ name: 'Adaptive Streaming', endpoint: 'adaptive-streaming.html' },
{ name: 'AI Highlights Graph', endpoint: 'highlights-graph.html' },
{ name: 'Analytics', endpoint: 'analytics.html' },
{ name: 'API and Events', endpoint: 'api.html' },
Expand Down
4 changes: 4 additions & 0 deletions test/e2e/types/exampleLinkType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* Example links type
*/
export type ExampleLinkType = { name: string; endpoint: string };

0 comments on commit afa898f

Please sign in to comment.