From de29164483d0d91093325dd2582a00e7d1f112c8 Mon Sep 17 00:00:00 2001 From: George He Date: Mon, 23 Dec 2024 11:39:50 +0800 Subject: [PATCH] fix(sdk): support async function in insomnia.test (#8243) * fix: support async function in insomnia.test * test: fix and add test * fix: test failed * fix: update the solution * fix: lint * fix: test failure * fix: use regexp as replaceAll doesn't available * chore: remove useless code --- packages/insomnia-sdk/src/objects/insomnia.ts | 8 ++-- packages/insomnia-sdk/src/objects/test.ts | 14 +++---- .../fixtures/runner-collection.yaml | 39 ++++++++++++++++++- .../after-response-script-features.test.ts | 7 ++-- .../smoke/pre-request-script-features.test.ts | 7 ++-- .../tests/smoke/runner.test.ts | 32 ++++++++++++--- packages/insomnia/src/hidden-window.ts | 9 ++++- 7 files changed, 89 insertions(+), 27 deletions(-) diff --git a/packages/insomnia-sdk/src/objects/insomnia.ts b/packages/insomnia-sdk/src/objects/insomnia.ts index eb41bd02c42..f88aefe622e 100644 --- a/packages/insomnia-sdk/src/objects/insomnia.ts +++ b/packages/insomnia-sdk/src/objects/insomnia.ts @@ -82,11 +82,11 @@ export class InsomniaObject { } get test() { - const testHandler: TestHandler = (msg: string, fn: () => void) => { - this._test(msg, fn, this.pushRequestTestResult); + const testHandler: TestHandler = async (msg: string, fn: () => Promise) => { + await this._test(msg, fn, this.pushRequestTestResult); }; - testHandler.skip = (msg: string, fn: () => void) => { - this._skip(msg, fn, this.pushRequestTestResult); + testHandler.skip = async (msg: string, fn: () => Promise) => { + await this._skip(msg, fn, this.pushRequestTestResult); }; return testHandler; diff --git a/packages/insomnia-sdk/src/objects/test.ts b/packages/insomnia-sdk/src/objects/test.ts index 0300f3524a3..d924fc82ec3 100644 --- a/packages/insomnia-sdk/src/objects/test.ts +++ b/packages/insomnia-sdk/src/objects/test.ts @@ -1,12 +1,12 @@ -export function test( +export async function test( msg: string, - fn: () => void, + fn: () => Promise, log: (testResult: RequestTestResult) => void, ) { const started = performance.now(); try { - fn(); + await fn(); const executionTime = performance.now() - started; log({ testCase: msg, @@ -26,9 +26,9 @@ export function test( } } -export function skip( +export async function skip( msg: string, - _: () => void, + _: () => Promise, log: (testResult: RequestTestResult) => void, ) { log({ @@ -50,6 +50,6 @@ export interface RequestTestResult { } export interface TestHandler { - (msg: string, fn: () => void): void; - skip?: (msg: string, fn: () => void) => void; + (msg: string, fn: () => Promise): Promise; + skip?: (msg: string, fn: () => Promise) => void; }; diff --git a/packages/insomnia-smoke-test/fixtures/runner-collection.yaml b/packages/insomnia-smoke-test/fixtures/runner-collection.yaml index 0b1b1590a6a..62a02aa51c9 100644 --- a/packages/insomnia-smoke-test/fixtures/runner-collection.yaml +++ b/packages/insomnia-smoke-test/fixtures/runner-collection.yaml @@ -42,7 +42,7 @@ resources: }); insomnia.test('req1-post-check-failed', () => { insomnia.expect(insomnia.response.code).to.eql(201); - }); + }); settingStoreCookies: true settingSendCookies: true settingDisableRenderRequestBody: false @@ -373,3 +373,40 @@ resources: settingRebuildPath: true settingFollowRedirects: global _type: request + - _id: req_76bf52b201cf47269f5845795a711002 + parentId: wrk_418cad89191c418395abfeb2277fd26f + modified: 1636707449232 + created: 1636141014552 + url: http://127.0.0.1:4010/echo + name: async-test + description: "" + method: POST + body: {} + parameters: [] + headers: [] + authentication: {} + preRequestScript: |- + insomnia.test('async_pre_test', async () => { + await new Promise((resolve) => setTimeout(resolve, 50)); + insomnia.expect(false).to.eql(true); + }); + insomnia.test('sync_pre_test', () => { + insomnia.expect(false).to.eql(true); + }); + afterResponseScript: |- + insomnia.test('async_post_test', async () => { + await new Promise((resolve) => setTimeout(resolve, 50)); + insomnia.expect(false).to.eql(true); + }); + insomnia.test('sync_post_test', () => { + insomnia.expect(false).to.eql(true); + }); + metaSortKey: 164 + isPrivate: false + settingStoreCookies: true + settingSendCookies: true + settingDisableRenderRequestBody: false + settingEncodeUrl: true + settingRebuildPath: true + settingFollowRedirects: global + _type: request diff --git a/packages/insomnia-smoke-test/tests/smoke/after-response-script-features.test.ts b/packages/insomnia-smoke-test/tests/smoke/after-response-script-features.test.ts index 1cd6fd6e24d..984368e2627 100644 --- a/packages/insomnia-smoke-test/tests/smoke/after-response-script-features.test.ts +++ b/packages/insomnia-smoke-test/tests/smoke/after-response-script-features.test.ts @@ -27,10 +27,9 @@ test.describe('after-response script features tests', async () => { // verify await page.getByRole('tab', { name: 'Tests' }).click(); - const rows = page.getByTestId('test-result-row'); - await expect(rows.first()).toContainText('PASS'); - await expect(rows.nth(1)).toContainText('FAIL'); - await expect(rows.nth(1)).toContainText('AssertionError:'); + const responsePane = page.getByTestId('response-pane'); + await expect(responsePane).toContainText('PASS'); + await expect(responsePane).toContainText('FAILunhappy tests | AssertionError: expected 199 to deeply equal 200After-response Test'); }); test('environment and baseEnvironment can be persisted', async ({ page }) => { diff --git a/packages/insomnia-smoke-test/tests/smoke/pre-request-script-features.test.ts b/packages/insomnia-smoke-test/tests/smoke/pre-request-script-features.test.ts index 7768f789cb7..e71ac703721 100644 --- a/packages/insomnia-smoke-test/tests/smoke/pre-request-script-features.test.ts +++ b/packages/insomnia-smoke-test/tests/smoke/pre-request-script-features.test.ts @@ -409,10 +409,9 @@ test.describe('pre-request features tests', async () => { // verify await page.getByRole('tab', { name: 'Tests' }).click(); - const rows = page.getByTestId('test-result-row'); - await expect(rows.first()).toContainText('PASS'); - await expect(rows.nth(1)).toContainText('FAIL'); - await expect(rows.nth(1)).toContainText('AssertionError:'); + const responsePane = page.getByTestId('response-pane'); + expect(responsePane).toContainText('FAILunhappy tests | AssertionError: expected 199 to deeply equal 200Pre-request Test'); + expect(responsePane).toContainText('PASShappy tests'); }); test('environment and baseEnvironment can be persisted', async ({ page }) => { diff --git a/packages/insomnia-smoke-test/tests/smoke/runner.test.ts b/packages/insomnia-smoke-test/tests/smoke/runner.test.ts index 87de185735e..b6376eba825 100644 --- a/packages/insomnia-smoke-test/tests/smoke/runner.test.ts +++ b/packages/insomnia-smoke-test/tests/smoke/runner.test.ts @@ -115,12 +115,11 @@ test.describe('runner features tests', async () => { expect(await page.locator('input[name="Iterations"]').inputValue()).toBe('2'); // select requests to test - await page.locator('text=Select All').click(); - await page.locator('.runner-request-list-req0').click(); - await page.locator('.runner-request-list-req01').click(); - await page.locator('.runner-request-list-req02').click(); - await page.locator('.runner-request-list-set-var1').click(); - await page.locator('.runner-request-list-read-var1').click(); + await page.locator('.runner-request-list-req1').click(); + await page.locator('.runner-request-list-req2').click(); + await page.locator('.runner-request-list-req3').click(); + await page.locator('.runner-request-list-req4').click(); + await page.locator('.runner-request-list-req5').click(); // send await page.getByTestId('request-pane').getByRole('button', { name: 'Run' }).click(); @@ -227,4 +226,25 @@ test.describe('runner features tests', async () => { await verifyResultRows(page, 3, 0, 3, expectedTestOrder, 1); }); + + test('can detect sync and async test failure', async ({ page }) => { + await page.getByTestId('run-collection-btn-quick').click(); + + await page.locator('.runner-request-list-async-test').click(); + + // send + await page.getByRole('button', { name: 'Run', exact: true }).click(); + + // check result + await page.getByText('0 / 4').first().click(); + + const expectedTestOrder = [ + 'async_pre_test', + 'sync_pre_test', + 'async_post_test', + 'sync_post_test', + ]; + + await verifyResultRows(page, 0, 0, 4, expectedTestOrder, 1); + }); }); diff --git a/packages/insomnia/src/hidden-window.ts b/packages/insomnia/src/hidden-window.ts index 2b6ed02101d..5ffdc9ffaa8 100644 --- a/packages/insomnia/src/hidden-window.ts +++ b/packages/insomnia/src/hidden-window.ts @@ -37,6 +37,12 @@ window.bridge.onmessage(async (data, callback) => { } }); +// as insomnia.test accepts an async function, prepend await to it as user don't write it +function translateTestHandlers(script: string): string { + const replacedTests = script.replace(/insomnia\.test\(/g, 'await insomnia.test('); + return replacedTests.replace(/insomnia\.test\.skip\(/g, 'await insomnia.test.skip('); +} + // This function is duplicated in scriptExecutor.ts to run in nodejs // TODO: consider removing this implementation and using only nodejs scripting const runScript = async ( @@ -46,6 +52,7 @@ const runScript = async ( const executionContext = await initInsomniaObject(context, scriptConsole.log); + const translatedScript = translateTestHandlers(script); const AsyncFunction = (async () => { }).constructor; const executeScript = AsyncFunction( 'insomnia', @@ -60,7 +67,7 @@ const runScript = async ( ` const $ = insomnia; window.bridge.resetAsyncTasks(); // exclude unnecessary ones - ${script}; + ${translatedScript}; window.bridge.stopMonitorAsyncTasks(); // the next one should not be monitored await window.bridge.asyncTasksAllSettled(); return insomnia;`