Skip to content

Commit

Permalink
Merge commit '2bbea1c0f8ceb7abc8c6f59782d1ef7dcc0a5dae' into release/…
Browse files Browse the repository at this point in the history
…v1.27.0
  • Loading branch information
jasonbahl committed Jun 5, 2024
2 parents 238b4d6 + 2bbea1c commit 203e0c0
Show file tree
Hide file tree
Showing 11 changed files with 263 additions and 51 deletions.
7 changes: 4 additions & 3 deletions .distignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ phpstan.neon.dist
phpunit.xml.dist
README.md
schema.graphql



webpack.config.js
phpcs.xml.dist
.wp-env.json
.codeclimate.yml
33 changes: 0 additions & 33 deletions .gitattributes

This file was deleted.

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
9 changes: 6 additions & 3 deletions access-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -813,21 +813,24 @@ static function ( \WPGraphQL\Admin\Settings\SettingsRegistry $registry ) use ( $
* @since 0.13.0
*/
function get_graphql_setting( string $option_name, $default_value = '', $section_name = 'graphql_general_settings' ) {
$section_fields = get_option( $section_name );
$section_fields = get_option( $section_name, [] );

/**
* Filter the section fields
*
* @param array<string,mixed> $section_fields The values of the fields stored for the section
* @param string $section_name The name of the section
* @param mixed $default_value The default value for the option being retrieved
*/
$section_fields = apply_filters( 'graphql_get_setting_section_fields', $section_fields, $section_name, $default_value );

// ensure the filtered sections fields are an array before proceeding
$section_fields = is_array( $section_fields ) ? $section_fields : [];

/**
* Get the value from the stored data, or return the default
*/
$value = isset( $section_fields[ $option_name ] ) ? $section_fields[ $option_name ] : $default_value;
$value = $section_fields[ $option_name ] ?? $default_value;

/**
* Filter the value before returning it
Expand Down
11 changes: 10 additions & 1 deletion src/Admin/GraphiQL/GraphiQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,16 @@ public function init() {
* @return void
*/
public function register_admin_bar_menu( WP_Admin_Bar $admin_bar ) {
if ( ! current_user_can( 'manage_options' ) || 'off' === get_graphql_setting( 'show_graphiql_link_in_admin_bar' ) ) {

if ( 'off' === get_graphql_setting( 'graphiql_enabled' ) ) {
return;
}

if ( ! current_user_can( 'manage_options' ) ) {
return;
}

if ( 'off' === get_graphql_setting( 'show_graphiql_link_in_admin_bar' ) ) {
return;
}

Expand Down
24 changes: 14 additions & 10 deletions src/Admin/Settings/SettingsRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ public function get_settings_fields() {
* @return void
*/
public function admin_enqueue_scripts( string $hook_suffix ) {
if ( 'graphql_page_graphql-settings' !== $hook_suffix ) {

// if the page is not the GraphQL Settings page, bail
if ( 'graphql_page_graphql-settings' !== $hook_suffix && 'toplevel_page_graphql-settings' !== $hook_suffix ) {
return;
}

Expand Down Expand Up @@ -677,37 +679,37 @@ public function show_forms() {
/**
* Tabbable JavaScript codes & Initiate Color Picker
*
* This code uses localstorage for displaying active tabs
* This code uses URL hash fragments and localStorage for displaying active tabs
*
* @return void
*/
public function script() {
?>
<script>
jQuery(document).ready(function ($) {
//Initiate Color Picker
// Initiate Color Picker
$('.wp-color-picker-field').wpColorPicker();

// Switches option sections
$('.group').hide();
var activetab = '';
if (typeof (localStorage) != 'undefined') {
activetab = localStorage.getItem("activetab");
}
var urlHash = window.location.hash;

//if url has section id as hash then set it as active or override the current local storage value
if (window.location.hash) {
activetab = window.location.hash;
if (urlHash) {
activetab = urlHash;
if (typeof (localStorage) != 'undefined') {
localStorage.setItem("activetab", activetab);
}
} else if (typeof (localStorage) != 'undefined') {
activetab = localStorage.getItem("activetab");
}

if (activetab != '' && $(activetab).length) {
$(activetab).fadeIn();
} else {
$('.group:first').fadeIn();
}

$('.group .collapsed').each(function () {
$(this).find('input:checked').parent().parent().parent().nextAll().each(
function () {
Expand All @@ -724,13 +726,15 @@ function () {
} else {
$('.nav-tab-wrapper a:first').addClass('nav-tab-active');
}

$('.nav-tab-wrapper a').click(function (evt) {
$('.nav-tab-wrapper a').removeClass('nav-tab-active');
$(this).addClass('nav-tab-active').blur();
var clicked_group = $(this).attr('href');
if (typeof (localStorage) != 'undefined') {
localStorage.setItem("activetab", $(this).attr('href'));
localStorage.setItem("activetab", clicked_group);
}
history.replaceState(null, '', clicked_group);
$('.group').hide();
$(clicked_group).fadeIn();
evt.preventDefault();
Expand Down
18 changes: 18 additions & 0 deletions src/WPGraphQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,24 @@ static function ( $interfaces, $config, $type ) {
10,
3
);

/**
* Prevent WPML from redirecting within WPGraphQL requests
*
* @see https://github.com/wp-graphql/wp-graphql/issues/1626#issue-769089073
* @since @todo
*/
add_filter(
'wpml_is_redirected',
static function ( bool $is_redirect ) {
if ( is_graphql_request() ) {
return false;
}
return $is_redirect;
},
10,
1
);
}

/**
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',
)
);
}
);
125 changes: 125 additions & 0 deletions tests/e2e/specs/settings-page.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
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 = {
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', () => {

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

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

afterEach(async ({ page }) => {
// Deactivate the custom plugin after the test
await deactivatePlugin(page, pluginSlug);
});

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.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();
});
});
Loading

0 comments on commit 203e0c0

Please sign in to comment.