diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3681ad3..5bcaa5a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -22,6 +22,7 @@ jobs: node-version: '18.x' cache: 'npm' - run: npm ci + - run: npx playwright install - run: npm run build - run: npm run lint - run: npm test diff --git a/README.md b/README.md index 6b08409..351586c 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ import { suite, test } from 'playwright-decorators'; @suite() // <-- Decorate class with @suite class MyTestSuite { @test() // <-- Decorate test method with @test - async myTest() { + async myTest({ page }) { // ... } } diff --git a/lib/test.decorator.ts b/lib/test.decorator.ts index 7da0784..908c537 100644 --- a/lib/test.decorator.ts +++ b/lib/test.decorator.ts @@ -16,21 +16,12 @@ class TestDecorator implements TestDecoratorOptions { Object.assign(this, options); } - private wrapTest(testCode: () => Promise, wrapperCode: (args: (() => Promise)) => Promise) { - return new Proxy(testCode, { - apply: (target: any, thisArg: any, argArray: any[]) => - wrapperCode(() => target.apply(thisArg, argArray)) - }) - } - - private runTest(userTestCode: () => Promise) { - return userTestCode(); - } - run(executionContext: any) { - const testCallback = this.wrapTest(this.testMethod, this.runTest).bind(executionContext); - - playwright(this.name, testCallback); + // playwright function do not accept ...rest arguments, so we need to request all of them and pass to the testMethod manually + playwright(this.name, ({playwright, context, browserName, browser, contextOptions, connectOptions, page, testIdAttribute, launchOptions, defaultBrowserType, baseURL, channel, acceptDownloads, bypassCSP, deviceScaleFactor, extraHTTPHeaders, httpCredentials, ignoreHTTPSErrors, geolocation, hasTouch, headless, isMobile, javaScriptEnabled, locale, navigationTimeout, actionTimeout, offline, permissions, proxy, request, serviceWorkers, screenshot, trace, storageState, timezoneId, video, viewport, userAgent, colorScheme + }, ...args) => { + return this.testMethod.call(executionContext, {playwright, context, browserName, browser, contextOptions, connectOptions, page, testIdAttribute, launchOptions, defaultBrowserType, baseURL, channel, acceptDownloads, bypassCSP, deviceScaleFactor, extraHTTPHeaders, httpCredentials, ignoreHTTPSErrors, geolocation, hasTouch, headless, isMobile, javaScriptEnabled, locale, navigationTimeout, actionTimeout, offline, permissions, proxy, request, serviceWorkers, screenshot, trace, storageState, timezoneId, video, viewport, userAgent, colorScheme}, ...args); + }) } } @@ -44,7 +35,7 @@ export const test = (options: TestDecoratorOptions = {}) => function(originalMet const testDecorator = new TestDecorator(originalMethod, options); Object.assign(originalMethod, { testDecorator }); - + (context as ClassMemberDecoratorContext ).addInitializer(function () { testDecorator.run(this); }); diff --git a/tests/test.spec.ts b/tests/test.spec.ts index 8aeab2f..8cdc483 100644 --- a/tests/test.spec.ts +++ b/tests/test.spec.ts @@ -25,13 +25,23 @@ playwright.describe('@test decorator', () => { called.push('testThisContext'); expect(this instanceof ExampleSuite).toBeTruthy(); } + + @test() + testShouldHaveAccessToPage({ page }) { + called.push('testShouldHaveAccessToPage'); + expect(page).not.toBeUndefined(); + } } playwright('Methods with @test should be run', () => { - expect(called).toEqual(expect.arrayContaining(['testMethod', 'testMethod2', 'testThisContext'])); + expect(called).toEqual(['testMethod', 'testMethod2', 'testThisContext', 'testShouldHaveAccessToPage']); }); - + playwright('Methods without @test should not be run', () => { expect(called).toEqual(expect.not.arrayContaining(['notTestMethod'])); }); + + playwright.afterAll(() => { + expect(called.length).toEqual(4); + }) })