From 7f33bddb306f3ef1d22fb99a84d271d5cbbbd6bd Mon Sep 17 00:00:00 2001 From: Polle Pas Date: Wed, 18 Oct 2023 14:58:31 +0200 Subject: [PATCH] #648 Add ontology test and fix other tests --- .../forms/SearchBox/SearchBoxWindow.tsx | 2 +- .../src/helpers/getNamePartFromProps.ts | 8 +-- browser/data-browser/tests/e2e.spec.ts | 65 +++++++++---------- browser/data-browser/tests/test-utils.ts | 38 ++++++++++- 4 files changed, 70 insertions(+), 43 deletions(-) diff --git a/browser/data-browser/src/components/forms/SearchBox/SearchBoxWindow.tsx b/browser/data-browser/src/components/forms/SearchBox/SearchBoxWindow.tsx index 3810a56b3..a51b5dfc3 100644 --- a/browser/data-browser/src/components/forms/SearchBox/SearchBoxWindow.tsx +++ b/browser/data-browser/src/components/forms/SearchBox/SearchBoxWindow.tsx @@ -161,7 +161,7 @@ export function SearchBoxWindow({ onKeyDown={handleKeyDown} onPaste={handlePaste} /> - + {!searchValue && Start Searching}
    diff --git a/browser/data-browser/src/helpers/getNamePartFromProps.ts b/browser/data-browser/src/helpers/getNamePartFromProps.ts index 40639ce41..2a78a22cc 100644 --- a/browser/data-browser/src/helpers/getNamePartFromProps.ts +++ b/browser/data-browser/src/helpers/getNamePartFromProps.ts @@ -1,14 +1,14 @@ -import { JSONValue, properties } from '@tomic/react'; +import { core, JSONValue } from '@tomic/react'; import { randomString } from './randomString'; const normalizeName = (name: string) => - encodeURIComponent(name.replaceAll('/t', '-')); + encodeURIComponent(name.replace(/\s/g, '-')); export const getNamePartFromProps = ( props: Record, ): string => normalizeName( - (props?.[properties.shortname] as string) ?? - (props?.[properties.name] as string) ?? + (props?.[core.properties.shortname] as string) ?? + (props?.[core.properties.name] as string) ?? randomString(8), ); diff --git a/browser/data-browser/tests/e2e.spec.ts b/browser/data-browser/tests/e2e.spec.ts index 1a04f3d32..d8f555821 100644 --- a/browser/data-browser/tests/e2e.spec.ts +++ b/browser/data-browser/tests/e2e.spec.ts @@ -31,6 +31,8 @@ import { signIn, timestamp, waitForCommit, + openAgentPage, + fillSearchBox, } from './test-utils'; test.describe('data-browser', async () => { @@ -62,7 +64,7 @@ test.describe('data-browser', async () => { }); // Sign out - await page.click('text=user settings'); + await openAgentPage(page); await page.click('[data-test="sign-out"]'); await expect(page.locator('text=Enter your Agent secret')).toBeVisible(); await page.reload(); @@ -249,9 +251,6 @@ test.describe('data-browser', async () => { await page2.keyboard.press('Enter'); // Both pages should see then new chat message await expect(page.locator(`text=${teststring2}`)).toBeVisible(); - // TODO: get rid of this reload! It should not be necessary - // For some reason the page does not see the new message - await page2.reload(); await expect(page2.locator(`text=${teststring2}`)).toBeVisible(); }); @@ -342,7 +341,7 @@ test.describe('data-browser', async () => { // await expect(page.locator(currentDriveTitle)).toHaveText('Atomic Data'); // Cleanup drives for signed in user - await page.click('text=user settings'); + await openAgentPage(page); await page.click('text=Edit profile'); await page.click('[data-test="input-drives-clear"]'); await page.click('[data-test="save"]'); @@ -376,35 +375,24 @@ test.describe('data-browser', async () => { const shortnameInput = '[data-test="input-shortname"]'; // Try entering a wrong slug await page.click(shortnameInput); - await page.keyboard.type('not valid'); - await expect(page.locator('text=Not a valid slug')).toBeVisible(); + await page.keyboard.type('not valid-'); + await page.locator(shortnameInput).blur(); + await expect(page.getByText('Invalid Slug')).toBeVisible(); await page.locator(shortnameInput).fill(''); await page.keyboard.type('is-valid'); await expect(page.locator('text=Not a valid slug')).not.toBeVisible(); - // Add a new property - const input = page.locator( - '[placeholder="Select a property or enter a property URL..."]', + await fillSearchBox( + page, + 'Search for a property or enter a URL', + 'https://atomicdata.dev/properties/invite/usagesLeft', ); - await input.click(); - - await expect(page.locator('text=Create property:')).toBeVisible(); - await input.fill('https://atomicdata.dev/properties/invite/usagesLeft'); await page.keyboard.press('Enter'); - await page.click('[title="Add this property"]'); await expect(page.locator('text=Usages-left').first()).toBeVisible(); // Integer validation await page.click('[data-test="input-usages-left"]'); - await page.keyboard.type('asdf' + '1'); + await page.keyboard.type('asdf1'); await expect(page.locator('text=asdf')).not.toBeVisible(); - // Dropdown select - await page.click('[data-test="input-recommends-add-resource"]'); - await page.locator('text=append').click(); - await expect( - page.locator( - '[data-test="input-recommends"] >> text=https://atomicdata.dev', - ), - ).not.toBeVisible(); // Try to save without a description page.locator('button:has-text("Save")').click(); @@ -505,20 +493,27 @@ test.describe('data-browser', async () => { .locator('[title="Add an item to the recommends list"]') .first() .click(); - await page.locator('[data-test="input-recommends"]').click(); - await page.locator('[data-test="input-recommends"]').fill('test-prop'); // Create new Property using dialog - await page.locator('text=Create property: test-prop').click(); + + const clickOption = await fillSearchBox( + page, + 'Search for a property or enter a URL', + 'test-prop', + { nth: 0 }, + ); + + await clickOption('Create test-prop'); + await expect(page.locator('h1:has-text("new property")')).toBeVisible(); - await page.locator('[data-test="input-datatype"]').click(); - // click twice, first click is buggy, it closes the dropdown from earlier - await page.locator('[data-test="input-datatype"]').click(); - await page - .locator( - 'li:has-text("boolean - Either `true` or `false`. In JSON-AD, th...")', - ) - .click(); + // Set datatype of new property to boolean + + const selectDatatypeOption = await fillSearchBox( + page, + 'Search for a datatype or enter a URL', + 'boolean', + ); + await selectDatatypeOption('boolean - Either `true` or `false`'); await page.locator('dialog textarea[name="yamdeContent"]').click(); await page .locator('dialog textarea[name="yamdeContent"]') diff --git a/browser/data-browser/tests/test-utils.ts b/browser/data-browser/tests/test-utils.ts index 85da31570..bd6a244a4 100644 --- a/browser/data-browser/tests/test-utils.ts +++ b/browser/data-browser/tests/test-utils.ts @@ -1,4 +1,4 @@ -import { Page, expect, Browser } from '@playwright/test'; +import { Page, expect, Browser, Locator } from '@playwright/test'; export const DEMO_FILENAME = 'testimage.svg'; export const SERVER_URL = 'http://localhost:9883'; @@ -120,6 +120,10 @@ export async function getCurrentSubject(page: Page) { return page.locator(addressBar).getAttribute('value'); } +export async function openAgentPage(page: Page) { + page.goto(`${FRONTEND_URL}/app/agent`); +} + /** Set atomicdata.dev as current server */ export async function openAtomic(page: Page) { await changeDrive('https://atomicdata.dev', page); @@ -129,7 +133,7 @@ export async function openAtomic(page: Page) { /** Opens the users' profile, sets a username */ export async function editProfileAndCommit(page: Page) { - await page.click('text=user settings'); + await openAgentPage(page); await page.click('text=Edit profile'); await expect(page.locator('text=add another property')).toBeVisible(); const username = `Test user edited at ${new Date().toLocaleDateString()}`; @@ -141,6 +145,34 @@ export async function editProfileAndCommit(page: Page) { await expect(page.locator(`text=${username}`).first()).toBeVisible(); } +export async function fillSearchBox( + page: Page, + placeholder: string, + fillText: string, + options: { + nth?: number; + container?: Locator; + } = {}, +) { + const { nth, container } = options; + const selector = container ?? page; + + if (nth !== undefined) { + await selector.getByRole('button', { name: placeholder }).nth(nth).click(); + } else { + await selector.getByRole('button', { name: placeholder }).click(); + } + + await selector.getByPlaceholder(placeholder).type(fillText); + + return async (name: string) => { + // wait for the search to load (TODO: make this better) + await page.waitForTimeout(100); + selector.getByTestId('searchbox-results').getByText(name).hover(); + selector.getByTestId('searchbox-results').getByText(name).click(); + }; +} + /** Create a new Resource in the current Drive. * Class can be an Class URL or a shortname available in the new page. */ export async function newResource(klass: string, page: Page) { @@ -148,7 +180,7 @@ export async function newResource(klass: string, page: Page) { await expect(page).toHaveURL(`${FRONTEND_URL}/app/new`); if (klass.startsWith('https://')) { - await page.getByPlaceholder('Select a class').fill(klass); + await fillSearchBox(page, 'Search for a class or enter a URL', klass); await page.keyboard.press('Enter'); await page.click(`button:has-text("new ")`); } else {