Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 50 additions & 8 deletions src/platform/packages/shared/kbn-scout/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,20 +211,17 @@ Install dependencies by running the following commands:

Move to the `src/platform/packages/shared/kbn-scout` directory to begin development.

#### Adding or Modifying Features
### Adding or Modifying Components

Contributions to sharable fixtures and page objects are highly encouraged to promote reusability, stability, and ease of adoption. Follow these steps:

Create a New Page Object: Add your Page Object to the `src/playwright/page_objects` directory. For instance:
Contributions to sharable `Fixtures`, `API services` and `Page Objects` are highly encouraged to promote reusability, stability, and ease of adoption. Follow these steps:

#### Adding Page Objects

1. **Create a New Page Object:** Add your Page Object to the src/playwright/page_objects directory. For instance:
1. **Create a New Page Object:** Add a new file to the `src/playwright/page_objects` directory. For instance:

```ts
export class NewPage {
constructor(private readonly page: ScoutPage) {}

// implementation
}
```
Expand All @@ -237,7 +234,48 @@ export function createCorePageObjects(page: ScoutPage): PageObjects {
};
}
```
#### Adding Fixtures
#### Adding API service

1. **Create a New API service:** Add your service to the `src/playwright/fixtures/worker/apis` directory. For instance:

```ts
export interface FleetApiService {
integration: {
install: (name: string) => Promise<void>;
delete: (name: string) => Promise<void>;
};
}

export const getFleetApiHelper = (log: ScoutLogger, kbnClient: KbnClient): FleetApiService => {
return {
integration: {
install: async (name: string) => {
// implementation
},
delete: async (name: string) => {
// implementation
},
},
};
};
```
2. **Register the API service:** Update the index file to include the new service:
```ts
export const apiServicesFixture = coreWorkerFixtures.extend<
{},
{ apiServices: ApiServicesFixture }
>({
apiServices: [
async ({ kbnClient, log }, use) => {
const services = {
// add new service
fleet: getFleetApiHelper(log, kbnClient),
};
...
],
});
```
#### Adding Fixture
1. **Determine Fixture Scope:** Decide if your fixture should apply to the `test` (per-test) or `worker` (per-worker) scope.

2. **Implement the Fixture:** Add the implementation to `src/playwright/fixtures/test` or `src/playwright/fixtures/worker`.
Expand All @@ -260,7 +298,11 @@ export const scoutTestFixtures = mergeTests(
```

#### Best Practices
- **Reusable Code:** When creating Page Objects or Fixtures that apply to more than one plugin, ensure they are added to the kbn-scout package.
- **Reusable Code:** When creating Page Objects, API services or Fixtures that apply to more than one plugin, ensure they are added to the `kbn-scout` package.
- **Adhere to Existing Structure:** Maintain consistency with the project's architecture.
- **Keep the Scope of Components Clear** When designing test components, keep in naming conventions, scope, maintainability and performance.
- `Page Objects` should focus exclusively on UI interactions (clicking buttons, filling forms, navigating page). They should not make API calls directly.
- `API Services` should handle server interactions, such as sending API requests and processing responses.
- `Fixtures` can combine browser interactions with API requests, but they should be used wisely, especially with the `test` scope: a new instance of the fixture is created for **every test block**. If a fixture performs expensive operations (API setup, data ingestion), excessive usage can **slow down** the test suite runtime. Consider using `worker` scope when appropriate to reuse instances across tests within a worker.
- **Add Unit Tests:** Include tests for new logic where applicable, ensuring it works as expected.
- **Playwright documentation:** [Official best practices](https://playwright.dev/docs/best-practices)
1 change: 1 addition & 0 deletions src/platform/packages/shared/kbn-scout/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type {
ScoutTestOptions,
ScoutPage,
PageObjects,
ApiServicesFixture,
ScoutTestFixtures,
ScoutWorkerFixtures,
ScoutParallelTestFixtures,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@

import { mergeTests } from 'playwright/test';
import {
apiFixtures,
apiServicesFixture,
coreWorkerFixtures,
esArchiverFixture,
scoutSpaceParallelFixture,
synthtraceFixture,
} from './worker';
import type {
ApiParallelWorkerFixtures,
ApiServicesFixture,
EsClient,
KbnClient,
KibanaUrl,
Expand All @@ -36,7 +36,7 @@ export const scoutParallelFixtures = mergeTests(
// worker scope fixtures
coreWorkerFixtures,
scoutSpaceParallelFixture,
apiFixtures,
apiServicesFixture,
// test scope fixtures
browserAuthFixture,
scoutPageParallelFixture,
Expand All @@ -50,18 +50,19 @@ export interface ScoutParallelTestFixtures {
pageObjects: PageObjects;
}

export interface ScoutParallelWorkerFixtures extends ApiParallelWorkerFixtures {
export interface ScoutParallelWorkerFixtures {
log: ScoutLogger;
config: ScoutTestConfig;
kbnUrl: KibanaUrl;
kbnClient: KbnClient;
esClient: EsClient;
scoutSpace: ScoutSpaceParallelFixture;
apiServices: ApiServicesFixture;
}

export const globalSetup = mergeTests(
coreWorkerFixtures,
esArchiverFixture,
synthtraceFixture,
apiFixtures
apiServicesFixture
);
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@

import { mergeTests } from 'playwright/test';
import {
ApiFixtures,
apiFixtures,
apiServicesFixture,
coreWorkerFixtures,
esArchiverFixture,
uiSettingsFixture,
synthtraceFixture,
lighthouseFixture,
} from './worker';
import type {
ApiServicesFixture,
EsArchiverFixture,
EsClient,
KbnClient,
Expand All @@ -37,7 +37,7 @@ import {
} from './test';
import type { BrowserAuthFixture, ScoutPage, PageObjects, PerfTrackerFixture } from './test';
export type { ScoutPage, PageObjects } from './test';
export type { LighthouseAuditOptions } from './worker';
export type { ApiServicesFixture, LighthouseAuditOptions } from './worker';

export const scoutFixtures = mergeTests(
// worker scope fixtures
Expand All @@ -46,7 +46,7 @@ export const scoutFixtures = mergeTests(
uiSettingsFixture,
synthtraceFixture,
// api fixtures
apiFixtures,
apiServicesFixture,
// test scope fixtures
browserAuthFixture,
scoutPageFixture,
Expand All @@ -63,14 +63,15 @@ export interface ScoutTestFixtures {
perfTracker: PerfTrackerFixture;
}

export interface ScoutWorkerFixtures extends ApiFixtures {
export interface ScoutWorkerFixtures extends ApiServicesFixture {
log: ScoutLogger;
config: ScoutTestConfig;
kbnUrl: KibanaUrl;
kbnClient: KbnClient;
esClient: EsClient;
esArchiver: EsArchiverFixture;
uiSettings: UiSettingsFixture;
apiServices: ApiServicesFixture;
apmSynthtraceEsClient: SynthtraceFixture['apmSynthtraceEsClient'];
infraSynthtraceEsClient: SynthtraceFixture['infraSynthtraceEsClient'];
otelSynthtraceEsClient: SynthtraceFixture['otelSynthtraceEsClient'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,45 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { measurePerformanceAsync } from '../../../../../common';
import { coreWorkerFixtures } from '../../core_fixtures';
import { KbnClient, ScoutLogger, measurePerformanceAsync } from '../../../../../common';

export interface FleetApiFixture {
export interface FleetApiService {
integration: {
install: (name: string) => Promise<void>;
delete: (name: string) => Promise<void>;
};
}

/**
* This fixture provides a helper to interact with the Fleet API.
*/
export const fleetApiFixture = coreWorkerFixtures.extend<{}, { fleetApi: FleetApiFixture }>({
fleetApi: [
async ({ kbnClient, log }, use) => {
const fleetApiHelper = {
integration: {
install: async (name: string) => {
await measurePerformanceAsync(
log,
`fleetApi.integration.install [${name}]`,
async () => {
await kbnClient.request({
method: 'POST',
path: `/api/fleet/epm/custom_integrations`,
body: {
force: true,
integrationName: name,
datasets: [
{ name: `${name}.access`, type: 'logs' },
{ name: `${name}.error`, type: 'metrics' },
{ name: `${name}.warning`, type: 'logs' },
],
},
});
}
);
},

delete: async (name: string) => {
await measurePerformanceAsync(
log,
`fleetApi.integration.delete [${name}]`,
async () => {
await kbnClient.request({
method: 'DELETE',
path: `/api/fleet/epm/packages/${name}`,
ignoreErrors: [400],
});
}
);
},
},
};
export const getFleetApiHelper = (log: ScoutLogger, kbnClient: KbnClient): FleetApiService => {
return {
integration: {
install: async (name: string) => {
await measurePerformanceAsync(log, `fleetApi.integration.install [${name}]`, async () => {
await kbnClient.request({
method: 'POST',
path: `/api/fleet/epm/custom_integrations`,
body: {
force: true,
integrationName: name,
datasets: [
{ name: `${name}.access`, type: 'logs' },
{ name: `${name}.error`, type: 'metrics' },
{ name: `${name}.warning`, type: 'logs' },
],
},
});
});
},

log.serviceLoaded('fleetApi');
await use(fleetApiHelper);
delete: async (name: string) => {
await measurePerformanceAsync(log, `fleetApi.integration.delete [${name}]`, async () => {
await kbnClient.request({
method: 'DELETE',
path: `/api/fleet/epm/packages/${name}`,
ignoreErrors: [400],
});
});
},
},
{ scope: 'worker' },
],
});
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,30 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import { mergeTests } from 'playwright/test';
import { FleetApiFixture, fleetApiFixture } from './fleet';
import { coreWorkerFixtures } from '../core_fixtures';
import { FleetApiService, getFleetApiHelper } from './fleet';

export const apiFixtures = mergeTests(fleetApiFixture);

export interface ApiFixtures {
fleetApi: FleetApiFixture;
export interface ApiServicesFixture {
fleet: FleetApiService;
// add more services here
}

export interface ApiParallelWorkerFixtures {
fleetApi: FleetApiFixture;
}
/**
* This fixture provides a helper to interact with the Kibana APIs like Fleet, Spaces, Alerting, etc.
*/
export const apiServicesFixture = coreWorkerFixtures.extend<
{},
{ apiServices: ApiServicesFixture }
>({
apiServices: [
async ({ kbnClient, log }, use) => {
const services = {
fleet: getFleetApiHelper(log, kbnClient),
};

log.serviceLoaded('apiServices');
await use(services);
},
{ scope: 'worker' },
],
});
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ export type { UiSettingsFixture } from './ui_settings';
export { scoutSpaceParallelFixture } from './scout_space';
export type { ScoutSpaceParallelFixture } from './scout_space';

export { apiFixtures } from './apis';
export type { ApiFixtures, ApiParallelWorkerFixtures } from './apis';
export { apiServicesFixture } from './apis';
export type { ApiServicesFixture } from './apis';

export { synthtraceFixture } from './synthtrace';
export type { SynthtraceFixture } from './synthtrace';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ export { expect } from './expect';

export type { ScoutPlaywrightOptions, ScoutTestOptions } from './types';
export type {
ScoutPage,
// can be extended with solution specific fixtures
ScoutTestFixtures,
ScoutWorkerFixtures,
ScoutParallelTestFixtures,
ScoutParallelWorkerFixtures,
ScoutPage,
// can be extended with solution specific API services
ApiServicesFixture,
// can be extended with solution specific Page Objects
PageObjects,
} from './fixtures';

// use to tag tests
export { tags } from './tags';

export { ingestTestDataHook, ingestSynthtraceDataHook } from './global_hooks';
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

export { test, spaceTest } from './src/playwright';
export type {
ObltApiServicesFixture,
ObltPageObjects,
ObltTestFixtures,
ObltWorkerFixtures,
Expand Down
Loading