Skip to content

Commit

Permalink
Merge pull request #3146 from wp-graphql/feat/3142-settings-tab-link-…
Browse files Browse the repository at this point in the history
…tests

test: Add e2e test coverage for tabs in the settings page
  • Loading branch information
jasonbahl committed Jun 5, 2024
2 parents 30ee148 + c9208aa commit 2bbea1c
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 22 deletions.
5 changes: 4 additions & 1 deletion .wp-env.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"core": "WordPress/WordPress",
"plugins": [ "." ],
"plugins": [
"./tests/e2e/plugins/settings-page-spec/",
"."
],
"themes": [],
"port": 8888,
"config": {
Expand Down
3 changes: 3 additions & 0 deletions tests/e2e/plugins/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# WordPress Plugins

These are custom WordPress plugins specifically designed for end-to-end (e2e) testing of the WPGraphQL plugin. They are not intended for production use but serve to facilitate testing by adding mock functionalities and settings.
47 changes: 47 additions & 0 deletions tests/e2e/plugins/settings-page-spec/settings-page-spec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
/**
* Plugin Name: Settings Page Spec
* Description: This plugin is specifically used for end-to-end (e2e) testing of the WPGraphQL plugin. It registers settings sections and fields for testing purposes.
*/

// Register settings sections and fields for testing.
add_action(
'graphql_register_settings',
function() {
register_graphql_settings_section(
'graphql_section_a_settings',
array(
'title' => __( 'Section A Settings', 'settings-page-spec' ),
'desc' => __( 'Settings for section A', 'settings-page-spec' ),
)
);

register_graphql_settings_field(
'graphql_section_a_settings',
array(
'name' => 'graphql_section_a_checkbox',
'label' => __( 'Section A Checkbox Option', 'settings-page-spec' ),
'desc' => __( 'This is a checkbox option for section A', 'settings-page-spec' ),
'type' => 'checkbox',
)
);

register_graphql_settings_section(
'graphql_section_b_settings',
array(
'title' => __( 'Section B Settings', 'settings-page-spec' ),
'desc' => __( 'Settings for section B', 'settings-page-spec' ),
)
);

register_graphql_settings_field(
'graphql_section_b_settings',
array(
'name' => 'graphql_section_b_checkbox',
'label' => __( 'Section B Checkbox Option', 'settings-page-spec' ),
'desc' => __( 'This is a checkbox option for section B', 'settings-page-spec' ),
'type' => 'checkbox',
)
);
}
);
133 changes: 112 additions & 21 deletions tests/e2e/specs/settings-page.spec.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,125 @@
import { describe, test, expect, beforeEach } from '@playwright/test'
import { loginToWordPressAdmin, visitAdminFacingPage, wpAdminUrl } from '../utils'
import { describe, test, expect, beforeEach, afterEach } from '@playwright/test';
import { loginToWordPressAdmin, visitAdminFacingPage, wpAdminUrl } from '../utils';
import { activatePlugin, deactivatePlugin } from '../utils';

/**
* @file settings-page.spec.js
* @description End-to-end tests for the WPGraphQL settings page. This spec relies on a custom WordPress plugin
* located at `./tests/e2e/plugins/settings-page-spec/` that registers additional settings sections and fields
* for testing purposes.
*/

const selectors = {
graphiqlEnabledCheckbox: '#wpuf-graphql_general_settings\\[graphiql_enabled\\]',
}
navTabGeneral: '#graphql_general_settings-tab',
navTabA: '#graphql_section_a_settings-tab',
navTabB: '#graphql_section_b_settings-tab',
sectionA: '#graphql_section_a_settings',
sectionB: '#graphql_section_b_settings',
generalSettings: '#graphql_general_settings',
checkboxA: '#wpuf-graphql_section_a_settings\\[graphql_section_a_checkbox\\]',
checkboxB: '#wpuf-graphql_section_b_settings\\[graphql_section_b_checkbox\\]'
};

const pluginSlug = 'settings-page-spec';

describe( 'Settings Page', () => {
describe('Settings Page', () => {

beforeEach( async ({ page }) => {
await loginToWordPressAdmin( page );
beforeEach(async ({ page }) => {
await loginToWordPressAdmin(page);
await page.evaluate(() => localStorage.clear());

// Activate the custom plugin for the test
await activatePlugin(page, pluginSlug);
});

test( 'GraphiQL IDE can be disabled', async ({ page }) => {
await visitAdminFacingPage( page, wpAdminUrl + '/admin.php?page=graphql-settings' );
// await page.goto('http://localhost:8888/wp-login.php?redirect_to=http%3A%2F%2Flocalhost%3A8888%2Fwp-admin%2F&reauth=1');
afterEach(async ({ page }) => {
// Deactivate the custom plugin after the test
await deactivatePlugin(page, pluginSlug);
});

await page.waitForTimeout( 500 );
await expect( page.locator(selectors.graphiqlEnabledCheckbox ) ).toBeChecked();
await page.locator(selectors.graphiqlEnabledCheckbox ).uncheck();
await page.getByRole('button', { name: 'Save Changes' }).click();
await page.waitForTimeout( 500 );
await expect(page.getByText('Settings saved.')).toBeVisible();
await expect( page.locator(selectors.graphiqlEnabledCheckbox ) ).not.toBeChecked();
await page.locator( selectors.graphiqlEnabledCheckbox ).check();
test('Verify custom plugin is active and tabs are present', async ({ page }) => {
await visitAdminFacingPage(page, wpAdminUrl + '/admin.php?page=graphql-settings');
await page.waitForTimeout(500);

await expect(page.locator(selectors.navTabGeneral)).toBeVisible();
await expect(page.locator(selectors.navTabA)).toBeVisible();
await expect(page.locator(selectors.navTabB)).toBeVisible();
});

test('Switch between tabs and verify visibility', async ({ page }) => {
await visitAdminFacingPage(page, wpAdminUrl + '/admin.php?page=graphql-settings');
await page.waitForTimeout(500);

// Verify General tab is active by default
await expect(page.locator(selectors.navTabGeneral)).toHaveClass(/nav-tab-active/);
await expect(page.locator(selectors.generalSettings)).toBeVisible();
await expect(page.locator(selectors.sectionA)).not.toBeVisible();
await expect(page.locator(selectors.sectionB)).not.toBeVisible();

// Switch to Section A tab
await page.locator(selectors.navTabA).click();
await page.waitForTimeout(500);
await expect(page.locator(selectors.navTabA)).toHaveClass(/nav-tab-active/);
await expect(page.locator(selectors.sectionA)).toBeVisible();
await expect(page.locator(selectors.generalSettings)).not.toBeVisible();
await expect(page.locator(selectors.sectionB)).not.toBeVisible();

// Switch to Section B tab
await page.locator(selectors.navTabB).click();
await page.waitForTimeout(500);
await expect(page.locator(selectors.navTabB)).toHaveClass(/nav-tab-active/);
await expect(page.locator(selectors.sectionB)).toBeVisible();
await expect(page.locator(selectors.generalSettings)).not.toBeVisible();
await expect(page.locator(selectors.sectionA)).not.toBeVisible();
});

test('Verify checkbox functionality in Section A and B', async ({ page }) => {
await visitAdminFacingPage(page, wpAdminUrl + '/admin.php?page=graphql-settings');
await page.waitForTimeout(500);

// Switch to Section A tab and check checkbox
await page.locator(selectors.navTabA).click();
await page.waitForTimeout(500);
await page.locator(selectors.checkboxA).check();
await page.getByRole('button', { name: 'Save Changes' }).click();
await page.waitForTimeout( 500 );
await expect(page.getByText('Settings saved.')).toBeVisible();
await expect( page.locator( selectors.graphiqlEnabledCheckbox ) ).toBeChecked();
await page.waitForTimeout(500);
await expect(page.locator(selectors.checkboxA)).toBeChecked();

// Switch to Section B tab and check checkbox
await page.locator(selectors.navTabB).click();
await page.waitForTimeout(500);
await page.locator(selectors.checkboxB).check();
await page.getByRole('button', { name: 'Save Changes' }).click();
await page.waitForTimeout(500);
await expect(page.locator(selectors.checkboxB)).toBeChecked();
});

test('Verify localStorage retains last active tab', async ({ page }) => {
await visitAdminFacingPage(page, wpAdminUrl + '/admin.php?page=graphql-settings');
await page.waitForTimeout(500);

// Switch to Section A tab
await page.locator(selectors.navTabA).click();
await page.waitForTimeout(500);
await expect(page.locator(selectors.navTabA)).toHaveClass(/nav-tab-active/);
await expect(page.locator(selectors.sectionA)).toBeVisible();

// Reload and check if Section A is still active
await page.reload();
await page.waitForTimeout(500);
await expect(page.locator(selectors.navTabA)).toHaveClass(/nav-tab-active/);
await expect(page.locator(selectors.sectionA)).toBeVisible();

// Switch to Section B tab
await page.locator(selectors.navTabB).click();
await page.waitForTimeout(500);
await expect(page.locator(selectors.navTabB)).toHaveClass(/nav-tab-active/);
await expect(page.locator(selectors.sectionB)).toBeVisible();

// Reload and check if Section B is still active
await page.reload();
await page.waitForTimeout(500);
await expect(page.locator(selectors.navTabB)).toHaveClass(/nav-tab-active/);
await expect(page.locator(selectors.sectionB)).toBeVisible();
});
});
32 changes: 32 additions & 0 deletions tests/e2e/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,35 @@ export async function loadGraphiQL( page, queryParams = { query: null, variables
} );

}

/**
* Activates the specified plugin in WordPress admin.
*
* @param {import('@playwright/test').Page} page - The Playwright page object.
* @param {string} slug - The slug of the plugin to activate.
* @returns {Promise<void>}
*/
export async function activatePlugin(page, slug) {
await visitAdminFacingPage(page, wpAdminUrl + '/plugins.php');
const pluginRow = page.locator(`tr[data-slug="${slug}"]`);
const isPluginActive = await pluginRow.locator('.deactivate').isVisible();
if (!isPluginActive) {
await pluginRow.locator('.activate a').click();
}
}

/**
* Deactivates the specified plugin in WordPress admin.
*
* @param {import('@playwright/test').Page} page - The Playwright page object.
* @param {string} slug - The slug of the plugin to deactivate.
* @returns {Promise<void>}
*/
export async function deactivatePlugin(page, slug) {
await visitAdminFacingPage(page, wpAdminUrl + '/plugins.php');
const pluginRow = page.locator(`tr[data-slug="${slug}"]`);
const isPluginActive = await pluginRow.locator('.deactivate').isVisible();
if (isPluginActive) {
await pluginRow.locator('.deactivate a').click();
}
}

0 comments on commit 2bbea1c

Please sign in to comment.