test: enhance E2E tests with room and webhook functionality, add specific test scripts
This commit is contained in:
parent
eb9de7e9de
commit
fac7ed2636
85
.github/workflows/wc-e2e-test.yaml
vendored
85
.github/workflows/wc-e2e-test.yaml
vendored
@ -6,8 +6,8 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
e2e-test-core:
|
e2e-room-functionality-test:
|
||||||
name: E2E Tests Core
|
name: E2E Room Functionality Tests
|
||||||
runs-on: ov-actions-runner
|
runs-on: ov-actions-runner
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Node.js
|
- name: Setup Node.js
|
||||||
@ -28,7 +28,83 @@ jobs:
|
|||||||
# Install Playwright browsers
|
# Install Playwright browsers
|
||||||
mkdir -p /tmp/ms-playwright
|
mkdir -p /tmp/ms-playwright
|
||||||
PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright npx playwright install --with-deps chromium
|
PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright npx playwright install --with-deps chromium
|
||||||
npm run test:e2e-core
|
npm run test:e2e-core-room
|
||||||
|
env:
|
||||||
|
RUN_MODE: CI
|
||||||
|
PLAYWRIGHT_BROWSERS_PATH: /tmp/ms-playwright
|
||||||
|
- name: Upload failed test videos
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: test-videos
|
||||||
|
path: |
|
||||||
|
frontend/webcomponent/test-results/*/*.webm
|
||||||
|
retention-days: 2
|
||||||
|
- name: Clean up
|
||||||
|
if: always()
|
||||||
|
uses: OpenVidu/actions/cleanup@main
|
||||||
|
|
||||||
|
e2e-events-functionality-test:
|
||||||
|
name: E2E Events Functionality Tests
|
||||||
|
runs-on: ov-actions-runner
|
||||||
|
steps:
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '22.13'
|
||||||
|
- name: Setup OpenVidu Local Deployment
|
||||||
|
uses: OpenVidu/actions/start-openvidu-local-deployment@main
|
||||||
|
- name: Setup OpenVidu Meet
|
||||||
|
uses: OpenVidu/actions/start-openvidu-meet@main
|
||||||
|
env:
|
||||||
|
MEET_WEBHOOK_ENABLED: true
|
||||||
|
- name: Start OpenVidu Meet Testapp
|
||||||
|
uses: OpenVidu/actions/start-openvidu-meet-testapp@main
|
||||||
|
- name: Run tests
|
||||||
|
run: |
|
||||||
|
cd frontend/webcomponent
|
||||||
|
# Install Playwright browsers
|
||||||
|
mkdir -p /tmp/ms-playwright
|
||||||
|
PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright npx playwright install --with-deps chromium
|
||||||
|
npm run test:e2e-core-events
|
||||||
|
env:
|
||||||
|
RUN_MODE: CI
|
||||||
|
PLAYWRIGHT_BROWSERS_PATH: /tmp/ms-playwright
|
||||||
|
- name: Upload failed test videos
|
||||||
|
if: always()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: test-videos
|
||||||
|
path: |
|
||||||
|
frontend/webcomponent/test-results/*/*.webm
|
||||||
|
retention-days: 2
|
||||||
|
- name: Clean up
|
||||||
|
if: always()
|
||||||
|
uses: OpenVidu/actions/cleanup@main
|
||||||
|
|
||||||
|
e2e-webhooks-functionality-test:
|
||||||
|
name: E2E Webhooks Functionality Tests
|
||||||
|
runs-on: ov-actions-runner
|
||||||
|
steps:
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '22.13'
|
||||||
|
- name: Setup OpenVidu Local Deployment
|
||||||
|
uses: OpenVidu/actions/start-openvidu-local-deployment@main
|
||||||
|
- name: Setup OpenVidu Meet
|
||||||
|
uses: OpenVidu/actions/start-openvidu-meet@main
|
||||||
|
env:
|
||||||
|
MEET_WEBHOOK_ENABLED: true
|
||||||
|
- name: Start OpenVidu Meet Testapp
|
||||||
|
uses: OpenVidu/actions/start-openvidu-meet-testapp@main
|
||||||
|
- name: Run tests
|
||||||
|
run: |
|
||||||
|
cd frontend/webcomponent
|
||||||
|
# Install Playwright browsers
|
||||||
|
mkdir -p /tmp/ms-playwright
|
||||||
|
PLAYWRIGHT_BROWSERS_PATH=/tmp/ms-playwright npx playwright install --with-deps chromium
|
||||||
|
npm run test:e2e-core-webhooks
|
||||||
env:
|
env:
|
||||||
RUN_MODE: CI
|
RUN_MODE: CI
|
||||||
PLAYWRIGHT_BROWSERS_PATH: /tmp/ms-playwright
|
PLAYWRIGHT_BROWSERS_PATH: /tmp/ms-playwright
|
||||||
@ -79,6 +155,9 @@ jobs:
|
|||||||
path: |
|
path: |
|
||||||
frontend/webcomponent/test-results/*/*.webm
|
frontend/webcomponent/test-results/*/*.webm
|
||||||
retention-days: 2
|
retention-days: 2
|
||||||
|
- name: Clean up
|
||||||
|
if: always()
|
||||||
|
uses: OpenVidu/actions/cleanup@main
|
||||||
|
|
||||||
e2e-recording-access-test:
|
e2e-recording-access-test:
|
||||||
name: E2E Recording Access Tests
|
name: E2E Recording Access Tests
|
||||||
|
|||||||
@ -8,6 +8,9 @@
|
|||||||
"test:unit": "jest --forceExit --testPathPattern \"tests/unit\" --ci",
|
"test:unit": "jest --forceExit --testPathPattern \"tests/unit\" --ci",
|
||||||
"test:e2e": "playwright test",
|
"test:e2e": "playwright test",
|
||||||
"test:e2e-core": "playwright test tests/e2e/core/",
|
"test:e2e-core": "playwright test tests/e2e/core/",
|
||||||
|
"test:e2e-core-room": "playwright test tests/e2e/core/room.test.ts",
|
||||||
|
"test:e2e-core-events": "playwright test tests/e2e/core/events.test.ts",
|
||||||
|
"test:e2e-core-webhooks": "playwright test tests/e2e/core/webhooks.test.ts",
|
||||||
"test:e2e-ui-features": "playwright test tests/e2e/ui-feature-preferences.test.ts",
|
"test:e2e-ui-features": "playwright test tests/e2e/ui-feature-preferences.test.ts",
|
||||||
"test:e2e-recording-access": "playwright test tests/e2e/recording-access.test.ts",
|
"test:e2e-recording-access": "playwright test tests/e2e/recording-access.test.ts",
|
||||||
"lint": "eslint 'src/**/*.ts'"
|
"lint": "eslint 'src/**/*.ts'"
|
||||||
|
|||||||
@ -1,5 +1,10 @@
|
|||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import { waitForElementInIframe } from '../helpers/function-helpers';
|
import {
|
||||||
|
deleteAllRecordings,
|
||||||
|
deleteAllRooms,
|
||||||
|
joinRoomAs,
|
||||||
|
waitForElementInIframe
|
||||||
|
} from '../../helpers/function-helpers';
|
||||||
|
|
||||||
let subscribedToAppErrors = false;
|
let subscribedToAppErrors = false;
|
||||||
|
|
||||||
@ -41,40 +46,34 @@ test.describe('Web Component E2E Tests', () => {
|
|||||||
await context.storageState({ path: 'test_localstorage_state.json' });
|
await context.storageState({ path: 'test_localstorage_state.json' });
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Component Rendering', () => {
|
test.afterAll(async ({ browser }) => {
|
||||||
test('should load the web component with proper iframe', async ({ page }) => {
|
const tempContext = await browser.newContext();
|
||||||
await page.click('#join-as-moderator');
|
const tempPage = await tempContext.newPage();
|
||||||
const component = page.locator('openvidu-meet');
|
await deleteAllRooms(tempPage);
|
||||||
await expect(component).toBeVisible();
|
await deleteAllRecordings(tempPage);
|
||||||
|
|
||||||
const hasIframe = await page.evaluate(() => {
|
await tempContext.close();
|
||||||
const component = document.querySelector('openvidu-meet');
|
await tempPage.close();
|
||||||
return !!component?.shadowRoot?.querySelector('iframe');
|
|
||||||
});
|
|
||||||
expect(hasIframe).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Event Handling', () => {
|
test.describe('Event Handling', () => {
|
||||||
test('should successfully join as moderator and receive JOIN event', async ({ page }) => {
|
test('should successfully join as moderator and receive JOIN event', async ({ page }) => {
|
||||||
await page.click('#join-as-moderator');
|
await joinRoomAs('moderator', `P-${Math.random().toString(36).substring(2, 9)}`, page);
|
||||||
await waitForElementInIframe(page, 'ov-session');
|
|
||||||
await page.waitForSelector('.event-JOIN');
|
await page.waitForSelector('.event-JOIN');
|
||||||
const joinElements = await page.locator('.event-JOIN').all();
|
const joinElements = await page.locator('.event-JOIN').all();
|
||||||
expect(joinElements.length).toBe(1);
|
expect(joinElements.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully join as publisher and receive JOIN event', async ({ page }) => {
|
test('should successfully join as publisher and receive JOIN event', async ({ page }) => {
|
||||||
await page.click('#join-as-publisher');
|
await joinRoomAs('publisher', `P-${Math.random().toString(36).substring(2, 9)}`, page);
|
||||||
await waitForElementInIframe(page, 'ov-session');
|
|
||||||
await page.waitForSelector('.event-JOIN');
|
await page.waitForSelector('.event-JOIN');
|
||||||
const joinElements = await page.locator('.event-JOIN').all();
|
const joinElements = await page.locator('.event-JOIN').all();
|
||||||
expect(joinElements.length).toBe(1);
|
expect(joinElements.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should successfully join to room and receive LEFT event when using leave command', async ({ page }) => {
|
test('should successfully join to room and receive LEFT event when using leave command', async ({ page }) => {
|
||||||
await page.click('#join-as-moderator');
|
await joinRoomAs('moderator', `P-${Math.random().toString(36).substring(2, 9)}`, page);
|
||||||
await waitForElementInIframe(page, 'ov-session');
|
|
||||||
await page.click('#leave-room-btn');
|
await page.click('#leave-room-btn');
|
||||||
await page.waitForSelector('.event-LEFT');
|
await page.waitForSelector('.event-LEFT');
|
||||||
const leftElements = await page.locator('.event-LEFT').all();
|
const leftElements = await page.locator('.event-LEFT').all();
|
||||||
@ -84,8 +83,8 @@ test.describe('Web Component E2E Tests', () => {
|
|||||||
test('should successfully join to room and receive LEFT event when using disconnect button', async ({
|
test('should successfully join to room and receive LEFT event when using disconnect button', async ({
|
||||||
page
|
page
|
||||||
}) => {
|
}) => {
|
||||||
await page.click('#join-as-moderator');
|
await joinRoomAs('moderator', `P-${Math.random().toString(36).substring(2, 9)}`, page);
|
||||||
await waitForElementInIframe(page, 'ov-session');
|
|
||||||
const button = await waitForElementInIframe(page, '#leave-btn');
|
const button = await waitForElementInIframe(page, '#leave-btn');
|
||||||
await button.click();
|
await button.click();
|
||||||
await page.waitForSelector('.event-LEFT');
|
await page.waitForSelector('.event-LEFT');
|
||||||
@ -96,8 +95,8 @@ test.describe('Web Component E2E Tests', () => {
|
|||||||
test('should successfully join to room and receive MEETING_ENDED event when using end meeting command', async ({
|
test('should successfully join to room and receive MEETING_ENDED event when using end meeting command', async ({
|
||||||
page
|
page
|
||||||
}) => {
|
}) => {
|
||||||
await page.click('#join-as-moderator');
|
await joinRoomAs('moderator', `P-${Math.random().toString(36).substring(2, 9)}`, page);
|
||||||
await waitForElementInIframe(page, 'ov-session');
|
|
||||||
await page.click('#end-meeting-btn');
|
await page.click('#end-meeting-btn');
|
||||||
await page.waitForSelector('.event-MEETING_ENDED');
|
await page.waitForSelector('.event-MEETING_ENDED');
|
||||||
const meetingEndedElements = await page.locator('.event-MEETING_ENDED').all();
|
const meetingEndedElements = await page.locator('.event-MEETING_ENDED').all();
|
||||||
@ -108,23 +107,4 @@ test.describe('Web Component E2E Tests', () => {
|
|||||||
expect(leftEventElements.length).toBe(0);
|
expect(leftEventElements.length).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Webhook Handling', () => {
|
|
||||||
test('should successfully receive meetingStarted and meetingEnded webhooks', async ({ page }) => {
|
|
||||||
await page.click('#join-as-moderator');
|
|
||||||
|
|
||||||
await page.waitForTimeout(1000); // Wait for 1 second to ensure the meeting has started
|
|
||||||
await page.screenshot({ path: 'screenshot.png' });
|
|
||||||
await waitForElementInIframe(page, 'ov-session');
|
|
||||||
await page.waitForSelector('.webhook-meetingStarted');
|
|
||||||
const meetingStartedElements = await page.locator('.webhook-meetingStarted').all();
|
|
||||||
expect(meetingStartedElements.length).toBe(1);
|
|
||||||
|
|
||||||
// End the meeting
|
|
||||||
await page.click('#end-meeting-btn');
|
|
||||||
await page.waitForSelector('.webhook-meetingEnded');
|
|
||||||
const meetingEndedElements = await page.locator('.webhook-meetingEnded').all();
|
|
||||||
expect(meetingEndedElements.length).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
@ -19,6 +19,7 @@ import {
|
|||||||
|
|
||||||
let subscribedToAppErrors = false;
|
let subscribedToAppErrors = false;
|
||||||
|
|
||||||
|
// Test suite for room functionality in OpenVidu Meet
|
||||||
test.describe('Room Functionality Tests', () => {
|
test.describe('Room Functionality Tests', () => {
|
||||||
const testAppUrl = 'http://localhost:5080';
|
const testAppUrl = 'http://localhost:5080';
|
||||||
const testRoomPrefix = 'testing-room';
|
const testRoomPrefix = 'testing-room';
|
||||||
@ -69,6 +70,24 @@ test.describe('Room Functionality Tests', () => {
|
|||||||
await tempPage.close();
|
await tempPage.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// COMPONENT RENDERING TESTS
|
||||||
|
// ==========================================
|
||||||
|
test.describe('Component Rendering', () => {
|
||||||
|
test('should load the web component with proper iframe', async ({ page }) => {
|
||||||
|
await joinRoomAs('moderator', `P-${Math.random().toString(36).substring(2, 9)}`, page);
|
||||||
|
|
||||||
|
const component = page.locator('openvidu-meet');
|
||||||
|
await expect(component).toBeVisible();
|
||||||
|
|
||||||
|
const hasIframe = await page.evaluate(() => {
|
||||||
|
const component = document.querySelector('openvidu-meet');
|
||||||
|
return !!component?.shadowRoot?.querySelector('iframe');
|
||||||
|
});
|
||||||
|
expect(hasIframe).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// BASIC FUNCTIONALITY TESTS
|
// BASIC FUNCTIONALITY TESTS
|
||||||
// ==========================================
|
// ==========================================
|
||||||
|
|||||||
93
frontend/webcomponent/tests/e2e/core/webhooks.test.ts
Normal file
93
frontend/webcomponent/tests/e2e/core/webhooks.test.ts
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
import { deleteAllRecordings, deleteAllRooms, joinRoomAs, startStopRecording } from '../../helpers/function-helpers';
|
||||||
|
|
||||||
|
let subscribedToAppErrors = false;
|
||||||
|
|
||||||
|
test.describe('Web Component E2E Tests', () => {
|
||||||
|
const testAppUrl = 'http://localhost:5080';
|
||||||
|
const testRoomPrefix = 'test-room';
|
||||||
|
|
||||||
|
test.beforeAll(async ({ browser }) => {
|
||||||
|
// Create a test room before all tests
|
||||||
|
const tempContext = await browser.newContext();
|
||||||
|
const tempPage = await tempContext.newPage();
|
||||||
|
await tempPage.goto(testAppUrl);
|
||||||
|
await tempPage.waitForSelector('.create-room');
|
||||||
|
await tempPage.fill('#room-id-prefix', testRoomPrefix);
|
||||||
|
await tempPage.click('.create-room-btn');
|
||||||
|
await tempPage.waitForSelector(`#${testRoomPrefix}`);
|
||||||
|
await tempPage.close();
|
||||||
|
await tempContext.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
test.beforeEach(async ({ page }) => {
|
||||||
|
if (!subscribedToAppErrors) {
|
||||||
|
page.on('console', (msg) => {
|
||||||
|
const type = msg.type();
|
||||||
|
const tag = type === 'error' ? 'ERROR' : type === 'warning' ? 'WARNING' : 'LOG';
|
||||||
|
console.log('[' + tag + ']', msg.text());
|
||||||
|
});
|
||||||
|
subscribedToAppErrors = true;
|
||||||
|
}
|
||||||
|
await page.goto(testAppUrl);
|
||||||
|
await page.waitForSelector('.rooms-container');
|
||||||
|
await page.waitForSelector(`#${testRoomPrefix}`);
|
||||||
|
await page.click('.dropdown-button');
|
||||||
|
await page.waitForSelector('#join-as-moderator');
|
||||||
|
await page.waitForSelector('#join-as-publisher');
|
||||||
|
});
|
||||||
|
|
||||||
|
test.afterEach(async ({ context }) => {
|
||||||
|
await context.storageState({ path: 'test_localstorage_state.json' });
|
||||||
|
});
|
||||||
|
|
||||||
|
test.afterAll(async ({ browser }) => {
|
||||||
|
const tempContext = await browser.newContext();
|
||||||
|
const tempPage = await tempContext.newPage();
|
||||||
|
await deleteAllRooms(tempPage);
|
||||||
|
await deleteAllRecordings(tempPage);
|
||||||
|
|
||||||
|
await tempContext.close();
|
||||||
|
await tempPage.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Webhook Handling', () => {
|
||||||
|
test('should successfully receive meetingStarted and meetingEnded webhooks', async ({ page }) => {
|
||||||
|
await joinRoomAs('moderator', `P-${Math.random().toString(36).substring(2, 9)}`, page);
|
||||||
|
|
||||||
|
await page.waitForSelector('.webhook-meetingStarted');
|
||||||
|
const meetingStartedElements = await page.locator('.webhook-meetingStarted').all();
|
||||||
|
expect(meetingStartedElements.length).toBe(1);
|
||||||
|
|
||||||
|
// End the meeting
|
||||||
|
await page.click('#end-meeting-btn');
|
||||||
|
await page.waitForSelector('.webhook-meetingEnded');
|
||||||
|
const meetingEndedElements = await page.locator('.webhook-meetingEnded').all();
|
||||||
|
expect(meetingEndedElements.length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should successfully receive recordingStarted, recordingUpdated and recordingEnded webhooks', async ({
|
||||||
|
page
|
||||||
|
}) => {
|
||||||
|
await joinRoomAs('moderator', `P-${Math.random().toString(36).substring(2, 9)}`, page);
|
||||||
|
|
||||||
|
// Start recording
|
||||||
|
await startStopRecording(page, 'start');
|
||||||
|
await page.waitForSelector('.webhook-recordingStarted');
|
||||||
|
const recordingStartedElements = await page.locator('.webhook-recordingStarted').all();
|
||||||
|
expect(recordingStartedElements.length).toBe(1);
|
||||||
|
|
||||||
|
// Update recording
|
||||||
|
await page.waitForTimeout(2000); // Wait for a bit before updating
|
||||||
|
await page.waitForSelector('.webhook-recordingUpdated');
|
||||||
|
const recordingUpdatedElements = await page.locator('.webhook-recordingUpdated').all();
|
||||||
|
expect(recordingUpdatedElements.length).toBe(1);
|
||||||
|
|
||||||
|
// End recording
|
||||||
|
await startStopRecording(page, 'stop');
|
||||||
|
await page.waitForSelector('.webhook-recordingEnded');
|
||||||
|
const recordingEndedElements = await page.locator('.webhook-recordingEnded').all();
|
||||||
|
expect(recordingEndedElements.length).toBe(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user