Skip to content

Commit

Permalink
[scout] enable eslint plugin playwright (#210666)
Browse files Browse the repository at this point in the history
## Summary

Closes #21030

It was a quick work to do while we don't have many tests yet. 

For reviewers: we most likely will review and update the rules to align
better with final test design for Scout before GA. I don't think we have
to deep dive into what rules are missing, but just to make sure I didn't
restrict something important from your perspective.

Rules are described in
https://github.com/playwright-community/eslint-plugin-playwright?tab=readme-ov-file#rules

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
dmlemeshko and kibanamachine authored Feb 14, 2025
1 parent 34baecb commit ddd0fdb
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 42 deletions.
48 changes: 48 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -1439,6 +1439,54 @@ module.exports = {
'mocha/no-skipped-tests': 'off',
},
},
{
files: [
'packages/kbn-scout/src/playwright/**/*.ts',
'x-pack/solutions/observability/packages/kbn-scout-oblt/src/playwright/**/*.ts',
'src/platform/plugins/**/ui_tests/**/*.ts',
'x-pack/platform/plugins/**/ui_tests/**/*.ts',
'x-pack/solutions/**/plugins/**/ui_tests/**/*.ts',
],
excludedFiles: ['packages/kbn-scout/src/playwright/**/*.test.ts'],
extends: ['plugin:playwright/recommended'],
plugins: ['playwright'],
settings: {
playwright: {
globalAliases: {
test: ['test', 'spaceTest'],
},
},
},
rules: {
'playwright/no-commented-out-tests': 'error',
'playwright/no-conditional-expect': 'error',
'playwright/no-conditional-in-test': 'warn',
'playwright/no-duplicate-hooks': 'error',
'playwright/no-focused-test': 'error',
'playwright/no-get-by-title': 'error',
'playwright/no-nth-methods': 'error',
'playwright/no-page-pause': 'error',
'playwright/no-restricted-matchers': 'error',
'playwright/no-slowed-test': 'error',
'playwright/no-standalone-expect': 'error',
'playwright/no-unsafe-references': 'error',
'playwright/no-wait-for-selector': 'warn',
'playwright/max-nested-describe': ['error', { max: 1 }],
'playwright/missing-playwright-await': 'error',
'playwright/prefer-comparison-matcher': 'error',
'playwright/prefer-equality-matcher': 'error',
'playwright/prefer-hooks-in-order': 'error',
'playwright/prefer-hooks-on-top': 'error',
'playwright/prefer-strict-equal': 'error',
'playwright/prefer-to-be': 'error',
'playwright/prefer-to-contain': 'error',
'playwright/prefer-to-have-count': 'error',
'playwright/prefer-to-have-length': 'error',
'playwright/prefer-web-first-assertions': 'error',
'playwright/require-to-throw-message': 'error',
'playwright/require-top-level-describe': 'error',
},
},
{
files: ['x-pack/solutions/security/plugins/lists/public/**/!(*.test).{js,mjs,ts,tsx}'],
plugins: ['react-perf'],
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1750,6 +1750,7 @@
"eslint-plugin-mocha": "^10.1.0",
"eslint-plugin-no-unsanitized": "^4.0.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-playwright": "^2.2.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ function extendPageWithTestSubject(page: Page): ScoutPage['testSubj'] {
await page.locator(testSubjSelector).click();
for (const char of text) {
await page.keyboard.insertText(char);
// it is important to delay characters input to avoid flakiness, default is 25 ms
// eslint-disable-next-line playwright/no-wait-for-timeout
await page.waitForTimeout(delay);
}
};
Expand Down
1 change: 1 addition & 0 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,7 @@
"eslint-plugin-mocha",
"eslint-plugin-no-unsanitized",
"eslint-plugin-node",
"eslint-plugin-playwright",
"eslint-plugin-react",
"eslint-plugin-react-hooks",
"eslint-plugin-react-perf",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ spaceTest.describe('Discover app - errors', { tag: tags.ESS_ONLY }, () => {
});
});

spaceTest.afterAll(async ({ scoutSpace }) => {
await scoutSpace.savedObjects.cleanStandardList();
});

spaceTest.beforeEach(async ({ browserAuth, pageObjects }) => {
await browserAuth.loginAsViewer();
await pageObjects.discover.goto();
});

spaceTest.afterAll(async ({ scoutSpace }) => {
await scoutSpace.savedObjects.cleanStandardList();
});

spaceTest('should render invalid scripted field error', async ({ page }) => {
await page.testSubj.locator('discoverErrorCalloutTitle').waitFor({ state: 'visible' });
await expect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ spaceTest.describe(
await scoutSpace.uiSettings.setDefaultTime({ from: START_TIME, to: END_TIME });
});

spaceTest.beforeEach(async ({ browserAuth }) => {
await browserAuth.loginAsPrivilegedUser();
});

spaceTest.afterAll(async ({ scoutSpace }) => {
await scoutSpace.uiSettings.unset('defaultIndex', 'timepicker:timeDefaults');
await scoutSpace.savedObjects.cleanStandardList();
});

spaceTest.beforeEach(async ({ browserAuth }) => {
await browserAuth.loginAsPrivilegedUser();
});

spaceTest('should customize time range on dashboards', async ({ pageObjects, page }) => {
await pageObjects.dashboard.goto();
await pageObjects.dashboard.openNewDashboard();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ spaceTest.describe(
});
});

spaceTest.afterAll(async ({ scoutSpace }) => {
await scoutSpace.uiSettings.unset('defaultIndex', 'timepicker:timeDefaults');
await scoutSpace.savedObjects.cleanStandardList();
});

spaceTest.beforeEach(async ({ browserAuth, pageObjects }) => {
await browserAuth.loginAsViewer();
await pageObjects.discover.goto();
});

spaceTest.afterAll(async ({ scoutSpace }) => {
await scoutSpace.uiSettings.unset('defaultIndex', 'timepicker:timeDefaults');
await scoutSpace.savedObjects.cleanStandardList();
});

spaceTest('dont show up if outside of range', async ({ page, pageObjects }) => {
await pageObjects.datePicker.setAbsoluteRange(testData.LOGSTASH_OUT_OF_RANGE_DATES);
await page.testSubj.fill('queryInput', 'extension.raw : ');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ spaceTest.describe(
await scoutSpace.uiSettings.setDefaultIndex(testData.DATA_VIEW_NAME.NO_TIME_FIELD);
});

spaceTest.afterAll(async ({ scoutSpace }) => {
await scoutSpace.uiSettings.unset('defaultIndex');
await scoutSpace.savedObjects.cleanStandardList();
});

spaceTest.beforeEach(async ({ browserAuth, pageObjects }) => {
await browserAuth.loginAsViewer();
await pageObjects.discover.goto();
});

spaceTest.afterAll(async ({ scoutSpace }) => {
await scoutSpace.uiSettings.unset('defaultIndex');
await scoutSpace.savedObjects.cleanStandardList();
});

spaceTest(
'shows all auto-suggest options for a filter in discover context app',
async ({ page }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ spaceTest.describe(
await scoutSpace.uiSettings.set({ 'autocomplete:useTimeRange': false });
});

spaceTest.beforeEach(async ({ browserAuth, pageObjects }) => {
await browserAuth.loginAsViewer();
await pageObjects.discover.goto();
});

spaceTest.afterAll(async ({ scoutSpace }) => {
await scoutSpace.uiSettings.unset('defaultIndex', 'timepicker:timeDefaults');
await scoutSpace.uiSettings.set({ 'autocomplete:useTimeRange': true });
await scoutSpace.savedObjects.cleanStandardList();
});

spaceTest.beforeEach(async ({ browserAuth, pageObjects }) => {
await browserAuth.loginAsViewer();
await pageObjects.discover.goto();
});

spaceTest('show up if outside of range', async ({ page, pageObjects }) => {
await pageObjects.datePicker.setAbsoluteRange(testData.LOGSTASH_OUT_OF_RANGE_DATES);
await page.testSubj.fill('queryInput', 'extension.raw : ');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const createSavedSearch = async (
test.describe('Discover app - saved search embeddable', { tag: tags.DEPLOYMENT_AGNOSTIC }, () => {
const SAVED_SEARCH_TITLE = 'TempSearch';
const SAVED_SEARCH_ID = '90943e30-9a47-11e8-b64d-95841ca0b247';

test.beforeAll(async ({ esArchiver, kbnClient, uiSettings }) => {
await esArchiver.loadIfNeeded(testData.ES_ARCHIVES.LOGSTASH);
await kbnClient.importExport.load(testData.KBN_ARCHIVES.DASHBOARD_DRILLDOWNS);
Expand All @@ -49,16 +50,16 @@ test.describe('Discover app - saved search embeddable', { tag: tags.DEPLOYMENT_A
});
});

test.afterAll(async ({ kbnClient, uiSettings }) => {
await uiSettings.unset('defaultIndex', 'timepicker:timeDefaults');
await kbnClient.savedObjects.cleanStandardList();
});

test.beforeEach(async ({ browserAuth, pageObjects }) => {
await browserAuth.loginAsPrivilegedUser();
await pageObjects.dashboard.goto();
});

test.afterAll(async ({ kbnClient, uiSettings }) => {
await uiSettings.unset('defaultIndex', 'timepicker:timeDefaults');
await kbnClient.savedObjects.cleanStandardList();
});

test('should allow removing the dashboard panel after the underlying saved search has been deleted', async ({
kbnClient,
page,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,16 @@ test.describe(
const baseMapBtn = page.getByRole('button', { name: 'Basemap' });

await expect(fullScreenBtn).toBeVisible();
await expect(exitFullScreenBtn).not.toBeVisible();
await expect(exitFullScreenBtn).toBeHidden();
await expect(visibleChrome).toBeVisible();
await expect(hiddenChrome).not.toBeVisible();
await expect(hiddenChrome).toBeHidden();
await expect(baseMapBtn).toBeVisible();

await fullScreenBtn.click();

await expect(fullScreenBtn).not.toBeVisible();
await expect(fullScreenBtn).toBeHidden();
await expect(exitFullScreenBtn).toBeVisible();
await expect(visibleChrome).not.toBeVisible();
await expect(visibleChrome).toBeHidden();
await expect(hiddenChrome).toBeVisible();
await expect(baseMapBtn).toBeVisible();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ export class CustomLogsPage {
async clickAdvancedSettingsButton() {
return this.page.testSubj
.locator('obltOnboardingCustomLogsAdvancedSettings')
.getByRole('button')
.first()
.locator('button.euiAccordion__button')
.click();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ test.describe(
await customLogs.selectPlatform('windows');
await expect(customLogs.autoDownloadConfigurationToggle).toBeDisabled();
await expect(customLogs.windowsInstallElasticAgentDocLink).toBeVisible();
await expect(customLogs.installCodeSnippet).not.toBeVisible();
await expect(customLogs.installCodeSnippet).toBeHidden();
await expect(
customLogs.configureElasticAgentStep.getByText('Step 2 is disabled')
).toBeVisible();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ test.describe(

test(`should allow updating Advanced Settings`, async ({ pageObjects: { customLogs } }) => {
await customLogs.getLogFilePathInputField(0).fill(logsFilePath);
await expect(customLogs.advancedSettingsContent).not.toBeVisible();
await expect(customLogs.advancedSettingsContent).toBeHidden();
await customLogs.clickAdvancedSettingsButton();
await expect(
customLogs.advancedSettingsContent,
Expand All @@ -63,13 +63,13 @@ test.describe(

await customLogs.namespaceInput.fill('default');
await expect(customLogs.customConfigInput).toHaveValue('');
await expect(customLogs.continueButton).not.toBeDisabled();
await expect(customLogs.continueButton).toBeEnabled();

await customLogs.clickAdvancedSettingsButton();
await expect(
customLogs.advancedSettingsContent,
'Advanced Settings should be closed'
).not.toBeVisible();
).toBeHidden();
});

test('should validate Integration Name field', async ({
Expand Down
15 changes: 11 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -18628,6 +18628,13 @@ eslint-plugin-node@^11.1.0:
resolve "^1.10.1"
semver "^6.1.0"

eslint-plugin-playwright@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-playwright/-/eslint-plugin-playwright-2.2.0.tgz#d7eda21e670274fc0c006e11ba5cc2c8417b2a6e"
integrity sha512-qSQpAw7RcSzE3zPp8FMGkthaCWovHZ/BsXtpmnGax9vQLIovlh1bsZHEa2+j2lv9DWhnyeLM/qZmp7ffQZfQvg==
dependencies:
globals "^13.23.0"

eslint-plugin-prettier@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b"
Expand Down Expand Up @@ -20289,10 +20296,10 @@ globals@^11.1.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==

globals@^13.19.0, globals@^13.20.0:
version "13.20.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82"
integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==
globals@^13.19.0, globals@^13.20.0, globals@^13.23.0:
version "13.24.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171"
integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==
dependencies:
type-fest "^0.20.2"

Expand Down

0 comments on commit ddd0fdb

Please sign in to comment.