diff --git a/README.md b/README.md index e7d81d623..d3fb5d570 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ and navigate to http://localhost:4000 in the browser. The running app will autom #### Specifying non-default user Pick a user from the list of users in -[`libs/api-mocks/user.ts`](/libs/api-mocks/user.ts). The one without fleet +[`mock-api/user.ts`](/mock-api/user.ts). The one without fleet viewer permissions is `Hans Jonas`. Open the browser console and run: ```js @@ -153,7 +153,7 @@ This will start a preview environment for UI components at `http://localhost:610 ### E2E tests with [Playwright](https://playwright.dev/) -Playwright tests live in [`app/test/e2e`](app/test/e2e/). `npm run e2e` runs the tests in Chrome, Firefox, and Safari, but this is rarely necessary in local dev. `npm run e2ec` is a shortcut for `playwright test --project=chrome`, which runs the tests in Chrome only (the fastest one, useful for local dev). Playwright has an excellent [UI mode](https://playwright.dev/docs/test-ui-mode) for running and debugging tests that you can get to by running `npm run e2e -- --ui`. +Playwright tests live in [`test/e2e`](test/e2e/). `npm run e2e` runs the tests in Chrome, Firefox, and Safari, but this is rarely necessary in local dev. `npm run e2ec` is a shortcut for `playwright test --project=chrome`, which runs the tests in Chrome only (the fastest one, useful for local dev). Playwright has an excellent [UI mode](https://playwright.dev/docs/test-ui-mode) for running and debugging tests that you can get to by running `npm run e2e -- --ui`. To debug end-to-end failures on CI, check out the branch with the failure and run `./tools/debug-ci-e2e-fail.sh`. It'll download the latest failures from CI and allow you to open a [playwright trace](https://playwright.dev/docs/trace-viewer-intro#viewing-the-trace) of the failure. diff --git a/app/components/form/fields/DateTimeRangePicker.spec.tsx b/app/components/form/fields/DateTimeRangePicker.spec.tsx index 155a41827..0d9e37ec2 100644 --- a/app/components/form/fields/DateTimeRangePicker.spec.tsx +++ b/app/components/form/fields/DateTimeRangePicker.spec.tsx @@ -10,10 +10,13 @@ import { fireEvent, render, screen } from '@testing-library/react' import ResizeObserverPolyfill from 'resize-observer-polyfill' import { beforeAll, describe, expect, it, vi } from 'vitest' -import { clickByRole } from 'app/test/unit' - import { DateTimeRangePicker, type RangeKey } from './DateTimeRangePicker' +export function clickByRole(role: string, name: string) { + const element = screen.getByRole(role, { name }) + fireEvent.click(element) +} + const now = getNow(getLocalTimeZone()) function renderLastDay() { diff --git a/app/test/unit/index.tsx b/app/test/unit/index.tsx deleted file mode 100644 index 40a8fcca9..000000000 --- a/app/test/unit/index.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, you can obtain one at https://mozilla.org/MPL/2.0/. - * - * Copyright Oxide Computer Company - */ -import { fireEvent, screen } from '@testing-library/react' - -export { overrideOnce } from './server' - -export * from '@testing-library/react' - -// convenience functions so we can click and type in a one-liner. these were -// initially created to use the user-event library, but it was remarkably slow. -// see if those issues are improved before trying that again - -export function clickByRole(role: string, name: string) { - const element = screen.getByRole(role, { name }) - fireEvent.click(element) -} - -export function typeByRole(role: string, name: string, text: string) { - const element = screen.getByRole(role, { name }) - fireEvent.change(element, { target: { value: text } }) -} diff --git a/docs/mock-api-differences.md b/docs/mock-api-differences.md index d49378578..0e302d169 100644 --- a/docs/mock-api-differences.md +++ b/docs/mock-api-differences.md @@ -14,7 +14,7 @@ on the callback ensures we are returning the right kind of thing from the endpoint. The manual implementation has an in-memory "database" (see -[`libs/api-mocks/msw/db.ts`](/libs/api-mocks/msw/db.ts)) which is just a JS +[`mock-api/msw/db.ts`](/mock-api/msw/db.ts)) which is just a JS object with a property for each "table", which is just an array of models. We use the generated types to make sure our mock seed data has the correct shape. @@ -35,10 +35,9 @@ the mock server runs in the browser, it gets reset on pageload. ### Authentication and authorization -This is a big one. At time of writing, we only do one kind of authz check in the -mock API, and that's whether the user has fleet viewer permission. See -`requireFleetViewer` in -[`libs/api-mocks/msw/util.ts`](/libs/api-mocks/msw/util.ts). All +This is a big one. At time of writing, we only do one kind of authz check in +the mock API, and that's whether the user has fleet viewer permission. See +`requireFleetViewer` in [`mock-api/msw/util.ts`](/mock-api/msw/util.ts). All operator-related endpoints (i.e., ones that start with `/v1/system`) require fleet viewer permissions (at least, but viewer is all we enforce). On other resources (i.e., silos and projects) we do not currently do any authz checks in diff --git a/libs/api/__tests__/hooks.spec.tsx b/libs/api/__tests__/hooks.spec.tsx index e8d21b5ab..0f3d014b3 100644 --- a/libs/api/__tests__/hooks.spec.tsx +++ b/libs/api/__tests__/hooks.spec.tsx @@ -11,10 +11,9 @@ import { describe, expect, it, vi } from 'vitest' import { project } from '@oxide/api-mocks' -import { overrideOnce } from 'app/test/unit' - import { useApiMutation, useApiQuery } from '..' import type { DiskCreate } from '../__generated__/Api' +import { overrideOnce } from '../../../test/unit/server' // because useApiQuery and useApiMutation are almost entirely typed wrappers // around React Query's useQuery and useMutation, these tests are mostly about diff --git a/libs/api/__tests__/safety.spec.ts b/libs/api/__tests__/safety.spec.ts index 4eb510ee4..51ccaced1 100644 --- a/libs/api/__tests__/safety.spec.ts +++ b/libs/api/__tests__/safety.spec.ts @@ -33,22 +33,19 @@ const grepFiles = (s: string) => .filter((f) => !/safety\.spec\.ts/.test(f)) // this file doesn't count it('@oxide/api-mocks is only referenced in test files', () => { - const files = grepFiles('api-mocks') - expect(files).toMatchInlineSnapshot(` + expect(grepFiles('api-mocks')).toMatchInlineSnapshot(` [ - "README.md", "app/msw-mock-api.ts", - "app/test/e2e/instance-create.e2e.ts", - "app/test/e2e/inventory.e2e.ts", - "app/test/e2e/profile.e2e.ts", - "app/test/e2e/project-access.e2e.ts", - "app/test/e2e/silo-access.e2e.ts", - "app/test/e2e/utils.ts", - "app/test/unit/server.ts", - "app/test/unit/setup.ts", - "docs/mock-api-differences.md", - "libs/api-mocks/msw/db.ts", "libs/api/__tests__/hooks.spec.tsx", + "mock-api/msw/db.ts", + "test/e2e/instance-create.e2e.ts", + "test/e2e/inventory.e2e.ts", + "test/e2e/profile.e2e.ts", + "test/e2e/project-access.e2e.ts", + "test/e2e/silo-access.e2e.ts", + "test/e2e/utils.ts", + "test/unit/server.ts", + "test/unit/setup.ts", "tools/start_mock_api.ts", "tsconfig.json", ] @@ -66,8 +63,8 @@ const listFiles = (s: string) => execSync(`git ls-files | grep "${s}"`).toString().trim().split('\n') // avoid accidentally making an e2e file in the wrong place -it('e2e tests are only in app/test/e2e', () => { +it('e2e tests are only in test/e2e', () => { for (const file of listFiles('\\.e2e\\.')) { - expect(file).toMatch(/^app\/test\/e2e/) + expect(file).toMatch(/^test\/e2e/) } }) diff --git a/libs/api-mocks/disk.ts b/mock-api/disk.ts similarity index 100% rename from libs/api-mocks/disk.ts rename to mock-api/disk.ts diff --git a/libs/api-mocks/external-ip.ts b/mock-api/external-ip.ts similarity index 100% rename from libs/api-mocks/external-ip.ts rename to mock-api/external-ip.ts diff --git a/libs/api-mocks/floating-ip.ts b/mock-api/floating-ip.ts similarity index 100% rename from libs/api-mocks/floating-ip.ts rename to mock-api/floating-ip.ts diff --git a/libs/api-mocks/image.ts b/mock-api/image.ts similarity index 100% rename from libs/api-mocks/image.ts rename to mock-api/image.ts diff --git a/libs/api-mocks/index.ts b/mock-api/index.ts similarity index 100% rename from libs/api-mocks/index.ts rename to mock-api/index.ts diff --git a/libs/api-mocks/instance.ts b/mock-api/instance.ts similarity index 100% rename from libs/api-mocks/instance.ts rename to mock-api/instance.ts diff --git a/libs/api-mocks/ip-pool.ts b/mock-api/ip-pool.ts similarity index 100% rename from libs/api-mocks/ip-pool.ts rename to mock-api/ip-pool.ts diff --git a/libs/api-mocks/json-type.ts b/mock-api/json-type.ts similarity index 100% rename from libs/api-mocks/json-type.ts rename to mock-api/json-type.ts diff --git a/libs/api-mocks/json-type.type-spec.ts b/mock-api/json-type.type-spec.ts similarity index 100% rename from libs/api-mocks/json-type.type-spec.ts rename to mock-api/json-type.type-spec.ts diff --git a/libs/api-mocks/metrics.ts b/mock-api/metrics.ts similarity index 100% rename from libs/api-mocks/metrics.ts rename to mock-api/metrics.ts diff --git a/libs/api-mocks/msw/db.ts b/mock-api/msw/db.ts similarity index 100% rename from libs/api-mocks/msw/db.ts rename to mock-api/msw/db.ts diff --git a/libs/api-mocks/msw/handlers.ts b/mock-api/msw/handlers.ts similarity index 100% rename from libs/api-mocks/msw/handlers.ts rename to mock-api/msw/handlers.ts diff --git a/libs/api-mocks/msw/util.spec.ts b/mock-api/msw/util.spec.ts similarity index 100% rename from libs/api-mocks/msw/util.spec.ts rename to mock-api/msw/util.spec.ts diff --git a/libs/api-mocks/msw/util.ts b/mock-api/msw/util.ts similarity index 100% rename from libs/api-mocks/msw/util.ts rename to mock-api/msw/util.ts diff --git a/libs/api-mocks/network-interface.ts b/mock-api/network-interface.ts similarity index 100% rename from libs/api-mocks/network-interface.ts rename to mock-api/network-interface.ts diff --git a/libs/api-mocks/physical-disk.ts b/mock-api/physical-disk.ts similarity index 100% rename from libs/api-mocks/physical-disk.ts rename to mock-api/physical-disk.ts diff --git a/libs/api-mocks/project.ts b/mock-api/project.ts similarity index 100% rename from libs/api-mocks/project.ts rename to mock-api/project.ts diff --git a/libs/api-mocks/rack.ts b/mock-api/rack.ts similarity index 100% rename from libs/api-mocks/rack.ts rename to mock-api/rack.ts diff --git a/libs/api-mocks/role-assignment.ts b/mock-api/role-assignment.ts similarity index 100% rename from libs/api-mocks/role-assignment.ts rename to mock-api/role-assignment.ts diff --git a/libs/api-mocks/serial.ts b/mock-api/serial.ts similarity index 100% rename from libs/api-mocks/serial.ts rename to mock-api/serial.ts diff --git a/libs/api-mocks/silo.ts b/mock-api/silo.ts similarity index 100% rename from libs/api-mocks/silo.ts rename to mock-api/silo.ts diff --git a/libs/api-mocks/sled.ts b/mock-api/sled.ts similarity index 100% rename from libs/api-mocks/sled.ts rename to mock-api/sled.ts diff --git a/libs/api-mocks/snapshot.ts b/mock-api/snapshot.ts similarity index 100% rename from libs/api-mocks/snapshot.ts rename to mock-api/snapshot.ts diff --git a/libs/api-mocks/sshKeys.ts b/mock-api/sshKeys.ts similarity index 100% rename from libs/api-mocks/sshKeys.ts rename to mock-api/sshKeys.ts diff --git a/libs/api-mocks/user-group.ts b/mock-api/user-group.ts similarity index 100% rename from libs/api-mocks/user-group.ts rename to mock-api/user-group.ts diff --git a/libs/api-mocks/user.ts b/mock-api/user.ts similarity index 100% rename from libs/api-mocks/user.ts rename to mock-api/user.ts diff --git a/libs/api-mocks/vpc.ts b/mock-api/vpc.ts similarity index 100% rename from libs/api-mocks/vpc.ts rename to mock-api/vpc.ts diff --git a/playwright.config.ts b/playwright.config.ts index b6902f1b7..fc6aa3940 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -11,7 +11,7 @@ import { devices, type PlaywrightTestConfig } from '@playwright/test' * See https://playwright.dev/docs/test-configuration. */ const config: PlaywrightTestConfig = { - testDir: './app/test/e2e', + testDir: './test/e2e', testMatch: /\.e2e\.ts/, // Fail the build on CI if you accidentally left test.only in the source code forbidOnly: !!process.env.CI, diff --git a/app/test/e2e/authz.e2e.ts b/test/e2e/authz.e2e.ts similarity index 100% rename from app/test/e2e/authz.e2e.ts rename to test/e2e/authz.e2e.ts diff --git a/app/test/e2e/click-everything.e2e.ts b/test/e2e/click-everything.e2e.ts similarity index 100% rename from app/test/e2e/click-everything.e2e.ts rename to test/e2e/click-everything.e2e.ts diff --git a/app/test/e2e/disks.e2e.ts b/test/e2e/disks.e2e.ts similarity index 100% rename from app/test/e2e/disks.e2e.ts rename to test/e2e/disks.e2e.ts diff --git a/app/test/e2e/error-pages.e2e.ts b/test/e2e/error-pages.e2e.ts similarity index 100% rename from app/test/e2e/error-pages.e2e.ts rename to test/e2e/error-pages.e2e.ts diff --git a/app/test/e2e/firewall-rules.e2e.ts b/test/e2e/firewall-rules.e2e.ts similarity index 100% rename from app/test/e2e/firewall-rules.e2e.ts rename to test/e2e/firewall-rules.e2e.ts diff --git a/app/test/e2e/floating-ip-create.e2e.ts b/test/e2e/floating-ip-create.e2e.ts similarity index 100% rename from app/test/e2e/floating-ip-create.e2e.ts rename to test/e2e/floating-ip-create.e2e.ts diff --git a/app/test/e2e/image-upload.e2e.ts b/test/e2e/image-upload.e2e.ts similarity index 100% rename from app/test/e2e/image-upload.e2e.ts rename to test/e2e/image-upload.e2e.ts diff --git a/app/test/e2e/images.e2e.ts b/test/e2e/images.e2e.ts similarity index 100% rename from app/test/e2e/images.e2e.ts rename to test/e2e/images.e2e.ts diff --git a/app/test/e2e/instance-create.e2e.ts b/test/e2e/instance-create.e2e.ts similarity index 100% rename from app/test/e2e/instance-create.e2e.ts rename to test/e2e/instance-create.e2e.ts diff --git a/app/test/e2e/instance/disks.e2e.ts b/test/e2e/instance/disks.e2e.ts similarity index 100% rename from app/test/e2e/instance/disks.e2e.ts rename to test/e2e/instance/disks.e2e.ts diff --git a/app/test/e2e/instance/list.e2e.ts b/test/e2e/instance/list.e2e.ts similarity index 100% rename from app/test/e2e/instance/list.e2e.ts rename to test/e2e/instance/list.e2e.ts diff --git a/app/test/e2e/instance/networking.e2e.ts b/test/e2e/instance/networking.e2e.ts similarity index 100% rename from app/test/e2e/instance/networking.e2e.ts rename to test/e2e/instance/networking.e2e.ts diff --git a/app/test/e2e/inventory.e2e.ts b/test/e2e/inventory.e2e.ts similarity index 100% rename from app/test/e2e/inventory.e2e.ts rename to test/e2e/inventory.e2e.ts diff --git a/app/test/e2e/ip-pools.e2e.ts b/test/e2e/ip-pools.e2e.ts similarity index 100% rename from app/test/e2e/ip-pools.e2e.ts rename to test/e2e/ip-pools.e2e.ts diff --git a/app/test/e2e/login-saml.e2e.ts b/test/e2e/login-saml.e2e.ts similarity index 100% rename from app/test/e2e/login-saml.e2e.ts rename to test/e2e/login-saml.e2e.ts diff --git a/app/test/e2e/login.e2e.ts b/test/e2e/login.e2e.ts similarity index 100% rename from app/test/e2e/login.e2e.ts rename to test/e2e/login.e2e.ts diff --git a/app/test/e2e/lookup-routes.e2e.ts b/test/e2e/lookup-routes.e2e.ts similarity index 100% rename from app/test/e2e/lookup-routes.e2e.ts rename to test/e2e/lookup-routes.e2e.ts diff --git a/app/test/e2e/network-interface-create.e2e.ts b/test/e2e/network-interface-create.e2e.ts similarity index 100% rename from app/test/e2e/network-interface-create.e2e.ts rename to test/e2e/network-interface-create.e2e.ts diff --git a/app/test/e2e/networking.e2e.ts b/test/e2e/networking.e2e.ts similarity index 100% rename from app/test/e2e/networking.e2e.ts rename to test/e2e/networking.e2e.ts diff --git a/app/test/e2e/pagination.e2e.ts b/test/e2e/pagination.e2e.ts similarity index 100% rename from app/test/e2e/pagination.e2e.ts rename to test/e2e/pagination.e2e.ts diff --git a/app/test/e2e/profile.e2e.ts b/test/e2e/profile.e2e.ts similarity index 100% rename from app/test/e2e/profile.e2e.ts rename to test/e2e/profile.e2e.ts diff --git a/app/test/e2e/project-access.e2e.ts b/test/e2e/project-access.e2e.ts similarity index 100% rename from app/test/e2e/project-access.e2e.ts rename to test/e2e/project-access.e2e.ts diff --git a/app/test/e2e/project-create.e2e.ts b/test/e2e/project-create.e2e.ts similarity index 100% rename from app/test/e2e/project-create.e2e.ts rename to test/e2e/project-create.e2e.ts diff --git a/app/test/e2e/row-select.e2e.ts b/test/e2e/row-select.e2e.ts similarity index 100% rename from app/test/e2e/row-select.e2e.ts rename to test/e2e/row-select.e2e.ts diff --git a/app/test/e2e/scroll-restore.e2e.ts b/test/e2e/scroll-restore.e2e.ts similarity index 100% rename from app/test/e2e/scroll-restore.e2e.ts rename to test/e2e/scroll-restore.e2e.ts diff --git a/app/test/e2e/silo-access.e2e.ts b/test/e2e/silo-access.e2e.ts similarity index 100% rename from app/test/e2e/silo-access.e2e.ts rename to test/e2e/silo-access.e2e.ts diff --git a/app/test/e2e/silos.e2e.ts b/test/e2e/silos.e2e.ts similarity index 100% rename from app/test/e2e/silos.e2e.ts rename to test/e2e/silos.e2e.ts diff --git a/app/test/e2e/snapshots.e2e.ts b/test/e2e/snapshots.e2e.ts similarity index 100% rename from app/test/e2e/snapshots.e2e.ts rename to test/e2e/snapshots.e2e.ts diff --git a/app/test/e2e/ssh-keys.e2e.ts b/test/e2e/ssh-keys.e2e.ts similarity index 100% rename from app/test/e2e/ssh-keys.e2e.ts rename to test/e2e/ssh-keys.e2e.ts diff --git a/app/test/e2e/utilization.e2e.ts b/test/e2e/utilization.e2e.ts similarity index 100% rename from app/test/e2e/utilization.e2e.ts rename to test/e2e/utilization.e2e.ts diff --git a/app/test/e2e/utils.ts b/test/e2e/utils.ts similarity index 100% rename from app/test/e2e/utils.ts rename to test/e2e/utils.ts diff --git a/app/test/e2e/vpcs.e2e.ts b/test/e2e/vpcs.e2e.ts similarity index 100% rename from app/test/e2e/vpcs.e2e.ts rename to test/e2e/vpcs.e2e.ts diff --git a/app/test/e2e/z-index.e2e.ts b/test/e2e/z-index.e2e.ts similarity index 100% rename from app/test/e2e/z-index.e2e.ts rename to test/e2e/z-index.e2e.ts diff --git a/app/test/unit/server.ts b/test/unit/server.ts similarity index 100% rename from app/test/unit/server.ts rename to test/unit/server.ts diff --git a/app/test/unit/setup.ts b/test/unit/setup.ts similarity index 100% rename from app/test/unit/setup.ts rename to test/unit/setup.ts diff --git a/tsconfig.json b/tsconfig.json index c5694b3a5..a2f0318a9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,7 +16,7 @@ "app/*": ["app/*"], "@oxide/gen/*": ["libs/api/__generated__/*"], "@oxide/api": ["libs/api/index.ts"], - "@oxide/api-mocks": ["libs/api-mocks/index.ts"], + "@oxide/api-mocks": ["mock-api/index.ts"], "@oxide/ui": ["app/ui/index.ts"], "@oxide/util": ["libs/util/index.ts"], "@oxide/table": ["app/table/index.ts"] diff --git a/vite.config.ts b/vite.config.ts index 7ba6e343a..16ab25948 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -144,7 +144,7 @@ export default defineConfig(({ mode }) => ({ }, test: { environment: 'jsdom', - setupFiles: ['app/test/unit/setup.ts'], + setupFiles: ['test/unit/setup.ts'], includeSource: ['app/**/*.ts', 'libs/**/*.ts'], }, }))