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
2 changes: 1 addition & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default defineConfig({
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
workers: 4,
reporter: 'html',
use: {
baseURL: process.env.WP_BASE_URL,
Expand Down
102 changes: 64 additions & 38 deletions tests/e2e/feature-flags.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { test, expect } from '@wordpress/e2e-test-utils-playwright';
import { ERROR_FLAG_EXISTS, ERROR_FLAG_INVALID } from '../../src/constants';
import {
AddNewFlag,
AddNewFlagAndFill,
CloseSdkModal,
DisableFlag,
OpenSdkModal,
SaveFlags,
deleteLastFlag,
} from './helper';

// eslint-disable-next-line
test.use({ storageState: process.env.WP_AUTH_STORAGE });
Expand All @@ -17,22 +26,29 @@ test.describe('Feature flags', () => {
).toBeVisible();
});

test('Create and delete flags e2e scenarios', async ({ page }) => {
//Create new flag
await page.getByRole('button', { name: 'Add Flag' }).click();
await page.getByRole('textbox').last().fill('test');
await page.getByRole('button', { name: 'Save' }).click();
//Confirm save success
test.afterEach(async ({ page }) => {
await deleteLastFlag(page);
});

test('Create and save new flag successfully', async ({ page }) => {
await AddNewFlagAndFill(page, 'hello_test');
await SaveFlags(page);

expect(
await page.getByLabel('Dismiss this notice').innerText()
).toMatch(/Saved successfully!/);
});

test('Create new flag and disable it successfully', async ({ page }) => {
await AddNewFlagAndFill(page, 'test123');
await SaveFlags(page);

expect(
await page.getByLabel('Dismiss this notice').innerText()
).toMatch(/Saved successfully!/);

await DisableFlag(page, true);

//Toggle feature flag
await page
.locator('id=mr-feature-flag-item')
.last()
.getByLabel('Flag enabled')
.click();
expect(
await page.getByLabel('Dismiss this notice').innerText()
).toMatch(/Saved successfully!/);
Expand All @@ -42,60 +58,70 @@ test.describe('Feature flags', () => {
.last()
.getByLabel('Flag disabled')
).toBeVisible();
});

test('Check duplicate and invalid flag', async ({ page }) => {
//Create new flag
await AddNewFlagAndFill(page, 'testDuplicate');
await SaveFlags(page);

//Create another flag with same name
await page.getByRole('button', { name: 'Add Flag' }).click();
await page.getByRole('textbox').last().fill('test');
//Confirm save success
expect(
await page.getByLabel('Dismiss this notice').innerText()
).toMatch(/Saved successfully!/);

//Create another flag with same name should show error
await AddNewFlagAndFill(page, 'testDuplicate');
expect(page.getByText(ERROR_FLAG_EXISTS)).toBeVisible();
expect(page.getByRole('button', { name: 'Save' })).toBeDisabled();

//update flag name to be unique and check text validation.
await page.getByRole('textbox').last().fill('test 2');
//update flag name to be unique but still invalid
await AddNewFlag(page, 'test duplicate');
expect(page.getByText(ERROR_FLAG_INVALID)).toBeVisible();
expect(page.getByRole('button', { name: 'Save' })).toBeDisabled();

//Delete the flag
await page
.locator('id=mr-feature-flag-item')
.last()
.getByLabel('Delete Flag')
.click();
await page.getByRole('button', { name: 'Yes' }).click();
//Confirm delete success
await deleteLastFlag(page);

expect(
await page.getByLabel('Dismiss this notice').innerText()
).toMatch(/Saved successfully!/);
});

test('Open SDK modal and test the clipboard', async ({ page }) => {
const flagName = 'testWidget';
await AddNewFlagAndFill(page, flagName);
await SaveFlags(page);

expect(
await page.getByLabel('Dismiss this notice').innerText()
).toMatch(/Saved successfully!/);

//Check SDK modal details.
await page.getByLabel('Click to see SDK setting').last().click();
await OpenSdkModal(page);

expect(
page.getByRole('heading', { name: 'SDK for feature flag: test' })
page.getByRole('heading', {
name: `SDK for feature flag: ${flagName}`,
})
).toBeVisible();

// Check PHP Snippet clipboard details
await page.getByLabel('Copy to clipboard').first().click();
const phpClipboardText = await page.evaluate(
'navigator.clipboard.readText()'
);
expect(phpClipboardText).toContain("Flag::is_enabled( 'test' )");
expect(phpClipboardText).toContain(`Flag::is_enabled( '${flagName}' )`);

// Check JS Snippet clipboard details
await page.getByLabel('Copy to clipboard').nth(1).click();
const jsClipboardText: string = await page.evaluate(
'navigator.clipboard.readText()'
);
expect(jsClipboardText).toContain(
"window.mrFeatureFlags.isEnabled('test')"
`window.mrFeatureFlags.isEnabled('${flagName}')`
);

//Close SDK modal
await page.locator('button[aria-label="Close"]').click();

//Delete the created flag
await page
.locator('id=mr-feature-flag-item')
.last()
.getByLabel('Delete Flag')
.click();
await page.getByRole('button', { name: 'Yes' }).click();
await CloseSdkModal(page);
});
});
83 changes: 83 additions & 0 deletions tests/e2e/helper/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { test } from '@wordpress/e2e-test-utils-playwright';
import { Page } from '@playwright/test';

export async function deleteLastFlag(page: Page) {
await test.step(
'Delete last flag',
async () => {
await page
.locator('id=mr-feature-flag-item')
.last()
.getByLabel('Delete Flag')
.click();
await page.getByRole('button', { name: 'Yes' }).click();
},
{ box: true }
);
}

export async function AddNewFlag(page: Page, text: string) {
await test.step(
'Add new flag',
async () => {
await page.getByRole('textbox').last().fill(text);
},
{ box: true }
);
}

export async function AddNewFlagAndFill(page: Page, text: string) {
await test.step(
'Add new flag and fill text',
async () => {
await page.getByRole('button', { name: 'Add Flag' }).click();
await page.getByRole('textbox').last().fill(text);
},
{ box: true }
);
}

export async function SaveFlags(page: Page) {
await test.step(
'Save flags',
async () => {
await page.getByRole('button', { name: 'Save' }).click();
},
{ box: true }
);
}

export async function DisableFlag(page: Page, isEnabled: boolean) {
await test.step(
'Toggle flag',
async () => {
const labelText = isEnabled ? 'Flag enabled' : 'Flag disabled';
await page
.locator('id=mr-feature-flag-item')
.last()
.getByLabel(labelText)
.click();
},
{ box: true }
);
}

export async function OpenSdkModal(page: Page) {
await test.step(
'Open sdk modal',
async () => {
await page.getByLabel('Click to see SDK setting').last().click();
},
{ box: true }
);
}

export async function CloseSdkModal(page: Page) {
await test.step(
'Close sdk modal',
async () => {
await page.locator('button[aria-label="Close"]').click();
},
{ box: true }
);
}