-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Experiment: Add first e2e tests for Taxonomies #77828
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+193
−0
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,190 @@ | ||
| /** | ||
| * WordPress dependencies | ||
| */ | ||
| const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' ); | ||
|
|
||
| const SETTINGS_PAGE_PATH = 'options-general.php'; | ||
| const TAXONOMIES_PAGE_QUERY = 'page=taxonomies-wp-admin'; | ||
| const TAXONOMIES_REST_BASE = 'user-taxonomies'; | ||
|
|
||
| // TODO: once the user-taxonomies feature stabilizes, promote this seeding | ||
| // helper into packages/e2e-test-utils-playwright/src/request-utils/ alongside | ||
| // createPost / createPage so other specs can reuse it. | ||
| async function createUserTaxonomy( requestUtils, overrides = {} ) { | ||
| return requestUtils.rest( { | ||
| path: `/wp/v2/${ TAXONOMIES_REST_BASE }`, | ||
| method: 'POST', | ||
| data: { | ||
| title: 'Genres', | ||
| slug: 'genre', | ||
| status: 'publish', | ||
| object_type: [ 'post' ], | ||
| config: { | ||
| public: true, | ||
| hierarchical: false, | ||
| labels: { singular_name: 'Genre' }, | ||
| }, | ||
| ...overrides, | ||
| }, | ||
| } ); | ||
| } | ||
|
|
||
| async function visitTaxonomiesList( admin ) { | ||
| await admin.visitAdminPage( SETTINGS_PAGE_PATH, TAXONOMIES_PAGE_QUERY ); | ||
| } | ||
|
|
||
| async function visitTaxonomyEdit( admin, id ) { | ||
| await admin.visitAdminPage( | ||
| SETTINGS_PAGE_PATH, | ||
| `${ TAXONOMIES_PAGE_QUERY }&p=/edit/${ id }` | ||
| ); | ||
| } | ||
|
|
||
| test.describe( 'Taxonomies', () => { | ||
| test.beforeAll( async ( { requestUtils } ) => { | ||
| await requestUtils.setGutenbergExperiments( [ | ||
| 'gutenberg-content-types', | ||
| ] ); | ||
| } ); | ||
|
|
||
| test.afterEach( async ( { requestUtils } ) => { | ||
| await requestUtils.deleteAllPosts( TAXONOMIES_REST_BASE ); | ||
| } ); | ||
|
|
||
| test.afterAll( async ( { requestUtils } ) => { | ||
| await requestUtils.setGutenbergExperiments( [] ); | ||
| } ); | ||
|
|
||
| test( 'creates a taxonomy attached to posts and registers it', async ( { | ||
| admin, | ||
| page, | ||
| requestUtils, | ||
| } ) => { | ||
| await visitTaxonomiesList( admin ); | ||
|
|
||
| await page.getByRole( 'button', { name: 'Add taxonomy' } ).click(); | ||
|
|
||
| await page | ||
| .getByRole( 'textbox', { name: 'Plural label' } ) | ||
| .fill( 'Genres' ); | ||
| await page | ||
| .getByRole( 'textbox', { name: 'Singular label' } ) | ||
| .fill( 'Genre' ); | ||
| // The slug field runs an async uniqueness check; the form's | ||
| // `isValid` stays false while it's in flight, so wait for the | ||
| // REST call to settle before submitting. | ||
| await Promise.all( [ | ||
| page.waitForResponse( | ||
| ( resp ) => | ||
| resp.url().includes( `/${ TAXONOMIES_REST_BASE }?` ) && | ||
| resp.url().includes( 'slug=genre' ) | ||
| ), | ||
| page | ||
| .getByRole( 'textbox', { name: 'Taxonomy key' } ) | ||
| .fill( 'genre' ), | ||
| ] ); | ||
| await page.getByRole( 'combobox', { name: 'Post types' } ).click(); | ||
| await page.getByRole( 'option', { name: 'Posts' } ).click(); | ||
| await expect( | ||
| page.locator( '.components-form-token-field__token', { | ||
| hasText: 'Posts', | ||
| } ) | ||
| ).toBeVisible(); | ||
|
|
||
| await page.getByRole( 'button', { name: 'Create' } ).click(); | ||
|
|
||
| await expect( page.getByTestId( 'snackbar' ) ).toContainText( | ||
| '"Genres" taxonomy created.' | ||
| ); | ||
|
|
||
| // Relies on `show_in_rest: true`, which is the current default | ||
| // for user-defined taxonomies. | ||
| const registered = await requestUtils.rest( { | ||
| path: '/wp/v2/taxonomies/genre', | ||
| method: 'GET', | ||
| } ); | ||
| expect( registered.slug ).toBe( 'genre' ); | ||
| expect( registered.types ).toContain( 'post' ); | ||
| } ); | ||
|
|
||
| test( 'deactivating unregisters the taxonomy and activating re-registers it', async ( { | ||
| admin, | ||
| page, | ||
| requestUtils, | ||
| } ) => { | ||
| await createUserTaxonomy( requestUtils ); | ||
| await visitTaxonomiesList( admin ); | ||
|
|
||
| const row = page.getByRole( 'row', { name: /Genres/ } ); | ||
| await row.getByRole( 'button', { name: 'Actions' } ).click(); | ||
| await page.getByRole( 'menuitem', { name: 'Deactivate' } ).click(); | ||
|
|
||
| await expect( page.getByTestId( 'snackbar' ).last() ).toContainText( | ||
| 'Taxonomy deactivated.' | ||
| ); | ||
| await expect( row.getByText( 'Inactive' ) ).toBeVisible(); | ||
|
|
||
| // requestUtils.rest() throws on non-2xx — catch and inspect the | ||
| // error code instead of relying on a status assertion. | ||
| const deactivated = await requestUtils | ||
| .rest( { | ||
| path: '/wp/v2/taxonomies/genre', | ||
| method: 'GET', | ||
| } ) | ||
| .catch( ( error ) => error ); | ||
| expect( deactivated.code ).toBe( 'rest_taxonomy_invalid' ); | ||
|
|
||
| await row.getByRole( 'button', { name: 'Actions' } ).click(); | ||
| await page.getByRole( 'menuitem', { name: 'Activate' } ).click(); | ||
|
|
||
| await expect( page.getByTestId( 'snackbar' ).last() ).toContainText( | ||
| 'Taxonomy activated.' | ||
| ); | ||
| await expect( row.getByText( 'Active' ) ).toBeVisible(); | ||
|
|
||
| const reactivated = await requestUtils.rest( { | ||
| path: '/wp/v2/taxonomies/genre', | ||
| method: 'GET', | ||
| } ); | ||
| expect( reactivated.slug ).toBe( 'genre' ); | ||
| } ); | ||
|
|
||
| test.describe( 'Edit taxonomy', () => { | ||
| test.beforeEach( async ( { requestUtils, admin } ) => { | ||
| const created = await createUserTaxonomy( requestUtils ); | ||
| await visitTaxonomyEdit( admin, created.id ); | ||
| } ); | ||
|
|
||
| test( 'changing post types updates the saved taxonomy', async ( { | ||
| page, | ||
| requestUtils, | ||
| } ) => { | ||
| const postsToken = page.locator( | ||
| '.components-form-token-field__token', | ||
| { hasText: 'Posts' } | ||
| ); | ||
| await postsToken | ||
| .getByRole( 'button', { name: 'Remove item' } ) | ||
| .click(); | ||
| await page.getByRole( 'combobox', { name: 'Post types' } ).click(); | ||
| await page.getByRole( 'option', { name: 'Pages' } ).click(); | ||
| await expect( | ||
| page.locator( '.components-form-token-field__token', { | ||
| hasText: 'Pages', | ||
| } ) | ||
| ).toBeVisible(); | ||
|
|
||
| await page.getByRole( 'button', { name: 'Save' } ).click(); | ||
|
|
||
| await expect( page.getByTestId( 'snackbar' ) ).toContainText( | ||
|
ntsekouras marked this conversation as resolved.
Outdated
|
||
| '"Genres" taxonomy updated.' | ||
| ); | ||
|
|
||
| const registered = await requestUtils.rest( { | ||
| path: '/wp/v2/taxonomies/genre', | ||
| method: 'GET', | ||
| } ); | ||
| expect( registered.types ).toEqual( [ 'page' ] ); | ||
| } ); | ||
| } ); | ||
| } ); | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels a bit fragile; should we do something like this instead:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't do that because the button doesn't get disabled/busy based on the form's validity. I've added a todo though to explore that. I didn't do it for now because I had tried that recently in
quick editaction for posts and there were some nuances (especially with theslugfield). I'll explore though in this form separately, because we might not have similar nuances.