diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index ed1f8058..f159e3be 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -18,7 +18,7 @@ jobs:
with:
build: npm run build --workspaces --if-present
start: npm run start-test-env
- wait-on: http://localhost:8888
+ wait-on: 'http://localhost:8888/wp-admin/index.php, http://localhost:8889'
wait-on-timeout: 220
browser: chrome
record: true
diff --git a/cypress/e2e/ColorSettings.spec.js b/cypress/e2e/ColorSettings.spec.js
new file mode 100644
index 00000000..ba62ca89
--- /dev/null
+++ b/cypress/e2e/ColorSettings.spec.js
@@ -0,0 +1,55 @@
+///
+
+context('ColorSettings', () => {
+
+ beforeEach(() => {
+ cy.loginToWordPress();
+ cy.createPost({title: 'Color Settings Component Example'});
+ cy.insertBlock('Color Settings Component Example');
+ });
+
+ it('Allows the user to pick the block and displays it', () => {
+ cy.get('.wp-block-example-color-settings-example').should('be.visible');
+
+ cy.savePost();
+ })
+
+ it('Allows the user to use a custom color and displays it', () => {
+ cy.get('.components-color-palette__custom-color-button').first().click();
+ cy.get('.components-input-control__input').focus().clear().type('ff9400');
+ cy.get('.components-color-palette__custom-color-name').first().should('have.text', 'Custom');
+ cy.get('.components-color-palette__custom-color-value').first().should('have.text', '#ff9400');
+ })
+
+ it('Allows the user to clear the color', () => {
+ cy.get('.components-color-palette__custom-color-button').first().click();
+ cy.get('.components-input-control__input').focus().clear().type('ff9400');
+ cy.get('.components-color-palette__custom-color-name').first().should('have.text', 'Custom');
+ cy.get('.components-color-palette__custom-color-value').first().should('have.text', '#ff9400');
+
+ cy.get('.components-circular-option-picker__clear').first().click();
+ cy.get('.components-color-palette__custom-color-name').first().should('have.text', 'No color selected');
+ cy.get('.components-color-palette__custom-color-value').first().should('have.text', '');
+ })
+
+ it('Allows the user to add custom label and help text', () => {
+ cy.get('.wp-block-example-color-settings-example').should('be.visible');
+
+ cy.get('.wp-block-example-color-settings-example .components-base-control__label').first().should('have.text', 'Color Setting - Label');
+ cy.get('.wp-block-example-color-settings-example .components-base-control__help').first().should('have.text', 'Color Setting - Help Text');
+ })
+
+ it('Allows the user to pick from predefined colors', () => {
+ cy.get('.components-circular-option-picker__option').first().click();
+ cy.get('.components-color-palette__custom-color-name').first().should('have.text', 'red');
+ cy.get('.components-color-palette__custom-color-value').first().should('have.text', '#f00');
+
+ cy.get('.components-circular-option-picker__option').eq(1).click();
+ cy.get('.components-color-palette__custom-color-name').first().should('have.text', 'white');
+ cy.get('.components-color-palette__custom-color-value').first().should('have.text', '#fff');
+
+ cy.get('.components-circular-option-picker__option').eq(2).click();
+ cy.get('.components-color-palette__custom-color-name').first().should('have.text', 'blue');
+ cy.get('.components-color-palette__custom-color-value').first().should('have.text', '#00f');
+ });
+})
diff --git a/cypress/e2e/Counter.spec.js b/cypress/e2e/Counter.spec.js
new file mode 100644
index 00000000..ca84b9db
--- /dev/null
+++ b/cypress/e2e/Counter.spec.js
@@ -0,0 +1,56 @@
+///
+
+context('Counter', () => {
+
+ beforeEach(() => {
+ cy.loginToWordPress();
+ cy.createPost({title: 'Counter Example'});
+ cy.insertBlock('Counter Example');
+ });
+
+ it('Allows the user to pick the block and displays it', () => {
+ cy.get('.wp-block-example-counter').should('exist');
+ cy.get('.wp-block-example-counter').should('be.visible');
+
+ cy.savePost();
+ })
+
+ it('Has the counter component in the block', () => {
+ cy.get('.wp-block-example-counter').should('exist');
+ cy.get('.wp-block-example-counter').should('be.visible');
+
+ cy.get('.wp-block-example-counter .tenup--block-components__character-count').should('exist');
+ })
+
+ it('Has the correct starting value', () => {
+ cy.get('.wp-block-example-counter .tenup--block-components__character-count__count').should('exist');
+ cy.get('.wp-block-example-counter .tenup--block-components__character-count__count').should('have.text', '0');
+
+ cy.get('.wp-block-example-counter .tenup--block-components__character-count__limit').should('exist');
+ cy.get('.wp-block-example-counter .tenup--block-components__character-count__limit').should('have.text', '20');
+ })
+
+ it('Updates the count appropriately', () => {
+ cy.get('.wp-block-example-counter .components-text-control__input').focus().clear().type('0123456789');
+
+ cy.get('.wp-block-example-counter .tenup--block-components__character-count__count').should('exist');
+ cy.get('.wp-block-example-counter .tenup--block-components__character-count__count').should('have.text', '10');
+
+ cy.get('.wp-block-example-counter .tenup--block-components__character-count__limit').should('exist');
+ cy.get('.wp-block-example-counter .tenup--block-components__character-count__limit').should('have.text', '20');
+ })
+
+ it('Updates to the approaching limit state appropriately', () => {
+
+ cy.get('.wp-block-example-counter .components-text-control__input').focus().clear().type('01234567891234567');
+
+ cy.get('.wp-block-example-counter .tenup--block-components__circular-progress').should('have.class', 'is-approaching-limit');
+ })
+
+ it('Updates to the is over limit state appropriately', () => {
+
+ cy.get('.wp-block-example-counter .components-text-control__input').focus().clear().type('01234567891234567890');
+
+ cy.get('.wp-block-example-counter .tenup--block-components__circular-progress').should('have.class', 'is-over-limit');
+ })
+})
\ No newline at end of file
diff --git a/cypress/e2e/PostFeaturedImage.spec.js b/cypress/e2e/PostFeaturedImage.spec.js
new file mode 100644
index 00000000..e635c334
--- /dev/null
+++ b/cypress/e2e/PostFeaturedImage.spec.js
@@ -0,0 +1,71 @@
+///
+
+context('PostFeaturedImage', () => {
+
+ beforeEach(() => {
+ cy.loginToWordPress();
+ cy.createPost({title: 'Custom Post Featured Image'});
+ cy.insertBlock('Custom Post Featured Image');
+ });
+
+ it('Allows the user to pick the block and displays it', () => {
+ cy.get('.wp-block-example-custom-post-featured-image').should('exist');
+ cy.get('.wp-block-example-custom-post-featured-image').should('be.visible');
+
+ cy.savePost();
+ })
+
+ it('Allows the user to pick an image from the media library and displays it inline', () => {
+ cy.get('.wp-block-example-custom-post-featured-image button').contains('Media Library').click();
+ cy.get('#menu-item-browse').click();
+ cy.get('.attachment-preview').first().click();
+ cy.get('#attachment-details-alt-text').type('Test Alt Text');
+ cy.get('.media-button-select').contains('Select').click();
+
+ cy.get('.wp-block-example-custom-post-featured-image img').scrollIntoView({offset: -50})
+ cy.get('.wp-block-example-custom-post-featured-image img').should('be.visible');
+
+ cy.get('.wp-block-example-custom-post-featured-image img')
+ .should('have.attr', 'alt');
+
+ cy.get('.wp-block-example-custom-post-featured-image img')
+ .should('have.attr', 'src');
+ })
+
+ it('Syncs with the post featured image', () => {
+ cy.get('.wp-block-example-custom-post-featured-image button').contains('Media Library').click();
+ cy.get('#menu-item-browse').click();
+ cy.get('.attachment-preview').first().click();
+ cy.get('#attachment-details-alt-text').type('Test Alt Text');
+ cy.get('.media-button-select').contains('Select').click();
+
+ cy.get('.wp-block-example-custom-post-featured-image img').scrollIntoView({offset: -50})
+ cy.get('.wp-block-example-custom-post-featured-image img').should('be.visible');
+
+ cy.get('[data-tab-id="edit-post/document"]').click();
+
+ cy.get('.components-button.components-panel__body-toggle').contains('Featured image').then($button => {
+ if ($button.attr('aria-expanded') === 'false') {
+ cy.get('.components-button.components-panel__body-toggle').contains('Featured image').click();
+ }
+ })
+
+ cy.get('.editor-post-featured-image img').should('exist').then(($a) => {
+ const src1 = $a.attr('src');
+ const cleanedSrc1 = src1.replace(/-\d+x\d+(?=\.\w+$)/, '');
+
+ cy.get('.wp-block-example-custom-post-featured-image__image').should('exist');
+ cy.get('.wp-block-example-custom-post-featured-image__image').should('have.attr', 'src');
+ cy.get('.wp-block-example-custom-post-featured-image__image').then(($b) => {
+ console.log($b);
+ const src2 = $b.attr('src');
+ const cleanedSrc2 = src2.replace(/-\d+x\d+(?=\.\w+$)/, '');
+
+ expect(cleanedSrc1).to.equal(cleanedSrc2);
+ });
+ });
+
+ cy.get('.components-button.editor-post-featured-image__action').contains('Remove').click();
+ cy.get('.wp-block-example-custom-post-featured-image__image').should('not.exist');
+ })
+})
diff --git a/cypress/e2e/PostMeta.spec.js b/cypress/e2e/PostMeta.spec.js
new file mode 100644
index 00000000..99595742
--- /dev/null
+++ b/cypress/e2e/PostMeta.spec.js
@@ -0,0 +1,125 @@
+///
+
+context('Post Meta', () => {
+
+ beforeEach(() => {
+ cy.loginToWordPress();
+ cy.createPost({title: 'Post Meta', postType: 'book' });
+ cy.insertBlock('Post Meta');
+ });
+
+ it('Allows the user to pick the block and displays it', () => {
+ cy.get('.wp-block-example-post-meta').should('exist');
+ cy.get('.wp-block-example-post-meta').should('be.visible');
+
+ cy.savePost();
+ })
+
+ it('Allows the user to pick a variation', () => {
+
+ cy.get('.wp-block-example-post-meta .block-editor-block-variation-picker__variation').its('length').should('be.gt', 0);
+ cy.get('.wp-block-example-post-meta .block-editor-block-variation-picker__variation').first().click();
+ })
+
+ it('Allows text to be entered into the post meta field', () => {
+ // Author
+ cy.get('.wp-block-example-post-meta .block-editor-block-variation-picker__variation').first().click();
+
+ cy.get('.wp-block-example-post-meta .block-editor-rich-text__editable[metakey="author"]').focus().clear().type('This is a test');
+ cy.get('.wp-block-example-post-meta .block-editor-rich-text__editable[metakey="author"]').should('have.text', 'This is a test');
+ })
+
+ it('Allows a number to be entered into the post meta field', () => {
+ // Price
+ cy.get('.wp-block-example-post-meta .block-editor-block-variation-picker__variation').eq(2).click();
+
+ cy.get('.wp-block-example-post-meta .components-input-control__input').focus().clear().type('10');
+ cy.get('.wp-block-example-post-meta .components-input-control__input').should('have.value', '10');
+ })
+
+ it('Allows a boolean to change the post meta field', () => {
+ // Is featured
+ cy.get('.wp-block-example-post-meta .block-editor-block-variation-picker__variation').eq(3).click();
+
+ cy.get('.wp-block-example-post-meta .components-form-toggle__input').check();
+ cy.get('.wp-block-example-post-meta .components-form-toggle__input').should('be.checked');
+ cy.get('.wp-block-example-post-meta .components-form-toggle').should('have.class', 'is-checked');
+ })
+
+ it('Saves the data into post meta', () => {
+ // Author
+ cy.get('.wp-block-example-post-meta .block-editor-block-variation-picker__variation').first().click();
+ cy.get('.wp-block-example-post-meta .block-editor-rich-text__editable[metakey="author"]').focus().clear().type('This is a test');
+
+ // Reset
+ cy.get('.block-editor-block-breadcrumb__button').contains('Book').click();
+
+ // Price
+ cy.insertBlock('Post Meta');
+ cy.get('.wp-block-example-post-meta .block-editor-block-variation-picker__variation').eq(2).click();
+ cy.get('.wp-block-example-post-meta .components-input-control__input').focus().clear().type('10');
+
+ // Reset
+ cy.get('.block-editor-block-breadcrumb__button').contains('Book').click();
+
+ // Is featured
+ cy.insertBlock('Post Meta');
+ cy.get('.wp-block-example-post-meta .block-editor-block-variation-picker__variation').eq(3).click();
+ cy.get('.wp-block-example-post-meta .components-form-toggle__input').check();
+
+ // Reset
+ cy.get('.block-editor-block-breadcrumb__button').contains('Book').click();
+
+ // Intercept the network request related to publishing the post
+ cy.intercept({
+ method: 'POST',
+ url: '/index.php?rest_route=%2Fwp%2Fv2%2Fbooks%2F*',
+ }).as('publishPost');
+
+ cy.savePost();
+
+ // Wait for the intercepted request to complete
+ cy.wait('@publishPost');
+
+ cy.reload();
+
+ cy.get('.components-dropdown-menu__toggle[aria-label="Options"]').click();
+ cy.get('.components-menu-item__button').contains('Preferences').click();
+ cy.get('.components-toggle-control__label').contains('Custom fields').then(($label) => {
+ const attrFor = $label.attr('for');
+
+ cy.get(`#${attrFor}`).then($input => {
+ if (!$input.is(':checked')) {
+ cy.get(`#${attrFor}`).check();
+ cy.get('.edit-post-preferences-modal__custom-fields-confirmation-button').contains('Show & Reload Page').click();
+ } else {
+ cy.get('.components-button[aria-label="Close"]').click();
+ }
+ })
+
+ cy.get('button').contains('Toggle panel: Custom Fields').then($button => {
+ if ($button.attr('aria-expanded') === 'false') {
+ cy.get('button').contains('Toggle panel: Custom Fields').click();
+ }
+ })
+
+ cy.get('input[value="author"]').should('exist').then($input => {
+ const id = $input.attr('id');
+
+ cy.get(`#${id.replace('key','value')}`).should('have.value', 'This is a test');
+ })
+
+ cy.get('input[value="is_featured"]').should('exist').then($input => {
+ const id = $input.attr('id');
+
+ cy.get(`#${id.replace('key','value')}`).should('have.value', '1');
+ })
+
+ cy.get('input[value="price"]').should('exist').then($input => {
+ const id = $input.attr('id');
+
+ cy.get(`#${id.replace('key','value')}`).should('have.value', '10');
+ })
+ })
+ })
+})
diff --git a/cypress/e2e/PostTitle.spec.js b/cypress/e2e/PostTitle.spec.js
new file mode 100644
index 00000000..06c3c975
--- /dev/null
+++ b/cypress/e2e/PostTitle.spec.js
@@ -0,0 +1,29 @@
+///
+
+context('PostTitle', () => {
+
+ beforeEach(() => {
+ cy.loginToWordPress();
+ cy.createPost({title: 'Custom Post Title'});
+ cy.insertBlock('Custom Post Title');
+ });
+
+ it('Allows the user to pick the block and displays it', () => {
+ cy.get('.wp-block-example-custom-post-title').should('exist');
+ cy.get('.wp-block-example-custom-post-title').should('be.visible');
+
+ cy.savePost();
+ })
+
+ it('Allows text to be entered', () => {
+ cy.get('.wp-block-example-custom-post-title .block-editor-rich-text__editable').focus().clear().type('This is a test');
+ cy.get('.wp-block-example-custom-post-title .block-editor-rich-text__editable').should('have.text', 'This is a test');
+ })
+
+ it('Should sync the text entered in the block with the post title', () => {
+ cy.get('.wp-block-example-custom-post-title .block-editor-rich-text__editable').focus().clear().type('This is a test');
+ cy.get('.wp-block-example-custom-post-title .block-editor-rich-text__editable').should('have.text', 'This is a test');
+
+ cy.get('.wp-block-post-title').should('have.text', 'This is a test');
+ })
+})
diff --git a/cypress/e2e/RichTextCharacterLimit.spec.js b/cypress/e2e/RichTextCharacterLimit.spec.js
new file mode 100644
index 00000000..23089aa0
--- /dev/null
+++ b/cypress/e2e/RichTextCharacterLimit.spec.js
@@ -0,0 +1,63 @@
+///
+
+context('RichTextCharacterLimit', () => {
+
+ beforeEach(() => {
+ cy.loginToWordPress();
+ cy.createPost({title: 'Rich Text Character Limit'});
+ cy.insertBlock('Rich Text Character Limit');
+ });
+
+ it('Allows the user to pick the block and displays it', () => {
+ cy.get('.wp-block-example-rich-text-character-limit').should('exist');
+ cy.get('.wp-block-example-rich-text-character-limit').should('be.visible');
+
+ cy.savePost();
+ })
+
+ it('Allows text to be entered', () => {
+ cy.get('.wp-block-example-rich-text-character-limit .block-editor-rich-text__editable').focus().clear().type('This is a test');
+ cy.get('.wp-block-example-rich-text-character-limit .block-editor-rich-text__editable').should('have.text', 'This is a test');
+ })
+
+ it('Has the correct starting value', () => {
+ cy.get('.wp-block-example-rich-text-character-limit .tenup--block-components__character-count__count').should('exist');
+ cy.get('.wp-block-example-rich-text-character-limit .tenup--block-components__character-count__count').should('have.text', '0');
+
+ cy.get('.wp-block-example-rich-text-character-limit .tenup--block-components__character-count__limit').should('exist');
+ cy.get('.wp-block-example-rich-text-character-limit .tenup--block-components__character-count__limit').should('have.text', '30');
+ })
+
+ it('Updates the count appropriately', () => {
+ cy.get('.wp-block-example-rich-text-character-limit .block-editor-rich-text__editable').focus().clear().type('This is a test');
+ cy.get('.wp-block-example-rich-text-character-limit .tenup--block-components__character-count__count').should('have.text', '14');
+
+ cy.get('.wp-block-example-rich-text-character-limit .tenup--block-components__character-count__limit').should('exist');
+ cy.get('.wp-block-example-rich-text-character-limit .tenup--block-components__character-count__limit').should('have.text', '30');
+ })
+
+ it('Updates to the approaching limit state appropriately', () => {
+
+ cy.get('.wp-block-example-rich-text-character-limit .block-editor-rich-text__editable').focus().clear().type('0123456789012345678901234');
+
+ cy.get('.wp-block-example-rich-text-character-limit .tenup--block-components__circular-progress').should('have.class', 'is-approaching-limit');
+ })
+
+ it('Updates to the is over limit state appropriately', () => {
+
+ cy.get('.wp-block-example-rich-text-character-limit .block-editor-rich-text__editable').focus().clear().type('012345678901234567890123456789');
+
+ cy.get('.wp-block-example-rich-text-character-limit .tenup--block-components__circular-progress').should('have.class', 'is-over-limit');
+ })
+
+ it('Shows the toolbar controls appropriately', () => {
+
+ cy.get('.wp-block-example-rich-text-character-limit .block-editor-rich-text__editable').focus()
+
+ cy.get('.components-toolbar-button[aria-label="Bold"]').should('exist');
+ cy.get('.components-toolbar-button[aria-label="Bold"]').should('be.visible');
+
+ cy.get('.components-toolbar-button[aria-label="Link"]').should('exist');
+ cy.get('.components-toolbar-button[aria-label="Link"]').should('be.visible');
+ });
+})
diff --git a/package.json b/package.json
index 9bc79ce8..c4e3478a 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,9 @@
"build-test-env": "npm run build --workspaces --if-present",
"start-test-env": "npm run start-env -w example/ && npm run import-media -w example/",
"test:e2e": "cypress open",
- "prepublishOnly": "npm run build"
+ "prepublishOnly": "npm run build",
+ "cypress:open": "cypress open --config-file ./cypress.config.js --e2e --browser chrome",
+ "cypress:run": "cypress run --config-file ./cypress.config.js"
},
"repository": {
"type": "git",