From 8960df5a6d41ccd1bf3d774db442ab002227ec54 Mon Sep 17 00:00:00 2001 From: Raphael Schweikert Date: Tue, 19 Nov 2024 20:22:20 +0100 Subject: [PATCH] Create separate test for runner functionality --- src/test/playwright/basic.spec.ts | 26 +----- ...-linux.png => render-1-chromium-linux.png} | Bin src/test/playwright/run.spec.ts | 77 ++++++++++++++++++ .../run-simple-1-chromium-linux.png | Bin 0 -> 25100 bytes 4 files changed, 78 insertions(+), 25 deletions(-) rename src/test/playwright/basic.spec.ts-snapshots/{renders-1-chromium-linux.png => render-1-chromium-linux.png} (100%) create mode 100644 src/test/playwright/run.spec.ts create mode 100644 src/test/playwright/run.spec.ts-snapshots/run-simple-1-chromium-linux.png diff --git a/src/test/playwright/basic.spec.ts b/src/test/playwright/basic.spec.ts index 17ba67f..0cbf42f 100644 --- a/src/test/playwright/basic.spec.ts +++ b/src/test/playwright/basic.spec.ts @@ -1,6 +1,6 @@ import { test, expect, Request } from '@playwright/test'; -test('renders', async ({ page }) => { +test('render', async ({ page }) => { await page.goto('/'); await expect(page).toHaveTitle(/JCR Hopper Script Builder/); @@ -37,28 +37,4 @@ test('add step', async ({ page }) => { await step.getByLabel('Selector Name:').press('Tab'); await expect(step).toHaveScreenshot(); - - let runScriptRequest: Promise | Request = page.waitForRequest('/mock/mock-response.jsonl'); - await page.getByRole('button', { name: 'Run' }).click(); - runScriptRequest = await runScriptRequest; - - expect(runScriptRequest.method()).toBe('POST'); - expect(runScriptRequest.postData()).toContain( - '{"logLevel":"trace","hops":[{"type":"nodeQuery","query":"SELECT * FROM [cq:Page] AS page","queryType":"JCR-SQL2","hops":[],"selectorName":"page"}],"parameters":[]}', - ); - - const output = page.locator('.output'); - - await expect(output).toMatchAriaSnapshot(` - - group: - - text: ▼ - - heading /✅ \\d+\\/\\d+\\/\\d+, \\d+:\\d+:\\d+/ [level=3] - - text: "/trace Starting JCR Hopper with 6 parameters, for 4 of which arguments were passed: \\\\[\\\\] debug JCR Hopper script started at \\\\d+ Some plain text output/" - - img "file csv" - - text: /Test\\.csv text\\/csv;charset=utf-8 \\d+ bytes/ - - link "Download": - - button "Download" - - text: /info JCR Hopper script finished after \\d+[hmsp]+ warn Not saving changes as dry run is enabled error Script execution aborted with exception/ - - button "!!" - `); }); diff --git a/src/test/playwright/basic.spec.ts-snapshots/renders-1-chromium-linux.png b/src/test/playwright/basic.spec.ts-snapshots/render-1-chromium-linux.png similarity index 100% rename from src/test/playwright/basic.spec.ts-snapshots/renders-1-chromium-linux.png rename to src/test/playwright/basic.spec.ts-snapshots/render-1-chromium-linux.png diff --git a/src/test/playwright/run.spec.ts b/src/test/playwright/run.spec.ts new file mode 100644 index 0000000..ba2f6f5 --- /dev/null +++ b/src/test/playwright/run.spec.ts @@ -0,0 +1,77 @@ +import { test, expect, Request } from '@playwright/test'; + +test('run simple', async ({ page }) => { + await page.goto('/'); + + await page.getByRole('button', { name: 'Add', exact: true }).click(); + await page.getByRole('option', { name: 'Query JCR' }).click(); + await page.getByLabel('Log Level: INFO').click(); + await page.getByRole('option', { name: 'ERROR' }).click(); + + let runScriptRequest: Promise | Request = page.waitForRequest('/mock/mock-response.jsonl'); + await page.getByRole('button', { name: 'Run' }).click(); + runScriptRequest = await runScriptRequest; + + expect(runScriptRequest.method()).toBe('POST'); + expect(runScriptRequest.postData()).toContain( + '{"logLevel":"error","hops":[{"type":"nodeQuery","query":"SELECT * FROM [cq:Page] AS page","queryType":"JCR-SQL2","hops":[]}],"parameters":[]}', + ); + + const output = page.locator('.output'); + await expect(output).toMatchAriaSnapshot(` + - group: + - text: ▼ + - heading /✅ \\d+\\/\\d+\\/\\d+, \\d+:\\d+:\\d+/ [level=3] + - text: "/trace Starting JCR Hopper with 6 parameters, for 4 of which arguments were passed: \\\\[\\\\] debug JCR Hopper script started at \\\\d+ Some plain text output/" + - img "file csv" + - text: /Test\\.csv text\\/csv;charset=utf-8 \\d+ bytes/ + - link "Download": + - button "Download" + - text: /info JCR Hopper script finished after \\d+ms warn Not saving changes as dry run is enabled error Script execution aborted with exception/ + - button "!!" + `); + + await expect(output).toHaveScreenshot({ + mask: [output.getByRole('heading', { level: 3 })], + }); +}); + +test('run with arguments', async ({ page }) => { + await page.goto('/'); + + await page.getByRole('button', { name: 'Add', exact: true }).click(); + await page.getByRole('option', { name: 'Resolve Specific Node' }).click(); + await page.getByRole('button', { name: 'add circle' }).click(); + await page.getByRole('option', { name: 'Get Child Nodes' }).click(); + await page.getByRole('heading', { name: 'Get Child Nodes Matching' }).click(); + + const namePattern = page.getByLabel('Name Pattern:'); + await namePattern.click(); + await namePattern.press('ControlOrMeta+a'); + await namePattern.fill(''); + await namePattern.press('Tab'); + + await page.getByRole('button', { name: 'add', exact: true }).click(); + const paramName = page.getByPlaceholder('Name'); + await paramName.click(); + await paramName.press('ControlOrMeta+a'); + await paramName.fill('myparam'); + await paramName.press('Tab'); + + const argValue = page.getByLabel('myparam:'); + await argValue.click(); + await argValue.fill('myvalue'); + await argValue.press('Tab'); + await page.getByRole('button', { name: 'Run' }).click(); + + let runScriptRequest: Promise | Request = page.waitForRequest('/mock/mock-response.jsonl'); + await page.getByRole('button', { name: 'Run' }).click(); + runScriptRequest = await runScriptRequest; + + expect(runScriptRequest.method()).toBe('POST'); + expect(runScriptRequest.postData()).toContain( + '{"logLevel":"info","hops":[{"type":"resolveNode","conflict":"ignore","name":"child-name","hops":[{"type":"childNodes","namePattern":"","hops":[]}]}],"parameters":[{"name":"myparam","defaultValue":"","type":"text","evaluation":"STRING"}]}', + ); + expect(runScriptRequest.postData()).toContain('myparam'); + expect(runScriptRequest.postData()).toContain('myvalue'); +}); diff --git a/src/test/playwright/run.spec.ts-snapshots/run-simple-1-chromium-linux.png b/src/test/playwright/run.spec.ts-snapshots/run-simple-1-chromium-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..43c6972d12e5e2c72caeac720e653c4259603898 GIT binary patch literal 25100 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 literal 0 HcmV?d00001