diff --git a/.wp-env.json b/.wp-env.json index ab7b4d2bd8..404742f432 100644 --- a/.wp-env.json +++ b/.wp-env.json @@ -10,7 +10,8 @@ "https://downloads.wordpress.org/plugin/debug-bar.zip", "https://downloads.wordpress.org/plugin/debug-bar-elasticpress.zip", "https://downloads.wordpress.org/plugin/wordpress-importer.zip", - "https://downloads.wordpress.org/plugin/woocommerce.zip" + "https://downloads.wordpress.org/plugin/woocommerce.zip", + "10up/elasticpress-proxy#develop" ], "mappings": { "wp-content/mu-plugins/unique-index-name.php": "./tests/cypress/wordpress-files/test-mu-plugins/unique-index-name.php", diff --git a/assets/js/autosuggest.js b/assets/js/autosuggest.js index 463fcef3b1..067a6486c5 100644 --- a/assets/js/autosuggest.js +++ b/assets/js/autosuggest.js @@ -676,9 +676,10 @@ function init() { */ const prepareInputForAutosuggest = (input) => { /** - * Skip facet widget search fields. + * Skip facet widget search fields and instant results. */ - if (input.classList.contains('facet-search')) { + const ignoredClasses = ['facet-search', 'ep-search-input']; + if (ignoredClasses.some((className) => input.classList.contains(className))) { return; } diff --git a/bin/setup-cypress-env.sh b/bin/setup-cypress-env.sh index 600426cc60..7d056655ab 100755 --- a/bin/setup-cypress-env.sh +++ b/bin/setup-cypress-env.sh @@ -75,7 +75,7 @@ fi ./bin/wp-env-cli tests-wordpress "wp --allow-root import /var/www/html/wp-content/uploads/content-example.xml --authors=create" -./bin/wp-env-cli tests-wordpress "wp --allow-root plugin deactivate woocommerce" +./bin/wp-env-cli tests-wordpress "wp --allow-root plugin deactivate woocommerce elasticpress-proxy" ./bin/wp-env-cli tests-wordpress "wp --allow-root plugin activate debug-bar debug-bar-elasticpress wordpress-importer --network" @@ -87,7 +87,5 @@ fi ./bin/wp-env-cli tests-wordpress "wp --allow-root user meta update admin edit_post_per_page 5" # Generate a SQL file that can be imported later to make things faster -SQL_FILENAME=./bin/$(date +'%F-%H-%M').sql -./bin/wp-env-cli tests-wordpress "wp --allow-root db export -" > $SQL_FILENAME - -exit 0 +# SQL_FILENAME=./bin/$(date +'%F-%H-%M').sql +# npm --silent run env run tests-cli "wp db export -" > $SQL_FILENAME diff --git a/tests/cypress/integration/features/instant-results.spec.js b/tests/cypress/integration/features/instant-results.spec.js new file mode 100644 index 0000000000..841e9b64c0 --- /dev/null +++ b/tests/cypress/integration/features/instant-results.spec.js @@ -0,0 +1,144 @@ +/* global isEpIo */ + +describe('Instant Results Feature', () => { + /** + * Create a Search widget. + * + * As tests for facets will remove all widgets, we recreate it here. + */ + function createSearchWidget() { + cy.openWidgetsPage(); + cy.openBlockInserter(); + cy.getBlocksList().should('contain.text', 'Search'); // Checking if it exists give JS time to process the full list. + cy.insertBlock('Search'); + cy.intercept('/wp-json/wp/v2/sidebars/*').as('sidebarsRest'); + cy.get('.edit-widgets-header__actions button').contains('Update').click(); + cy.wait('@sidebarsRest'); + } + + function maybeEnableProxy() { + if (!isEpIo) { + cy.activatePlugin('elasticpress-proxy'); + } + } + + before(() => { + createSearchWidget(); + + // Create some sample posts + cy.publishPost({ + title: 'Blog post', + content: 'This is a sample Blog post.', + }); + cy.publishPost({ + title: 'Test Post', + content: 'This is a sample test post.', + }); + }); + + after(() => { + cy.deactivatePlugin('elasticpress-proxy'); + }); + + /** + * Test that the feature cannot be activated when not in ElasticPress.io nor using a custom PHP proxy. + */ + it("Can't activate the feature if not in ElasticPress.io nor using a custom PHP proxy", () => { + if (isEpIo) { + return; + } + + cy.login(); + cy.deactivatePlugin('elasticpress-proxy'); + cy.visitAdminPage('admin.php?page=elasticpress'); + cy.get('.ep-feature-instant-results .settings-button').click(); + cy.get('.requirements-status-notice').should( + 'contain.text', + 'To use this feature you need to be an ElasticPress.io customer or implement a custom proxy', + ); + cy.get('.ep-feature-instant-results .input-wrap').should('have.class', 'disabled'); + }); + + /** + * Test that the feature can be activated and it can sync automatically. + * Also, it can show a warning when using a custom PHP proxy + */ + it('Can activate the feature and sync automatically', () => { + cy.login(); + + // Can see the warning if using custom proxy + maybeEnableProxy(); + cy.visitAdminPage('admin.php?page=elasticpress'); + cy.get('.ep-feature-instant-results .settings-button').click(); + + cy.get('.ep-feature-instant-results .input-wrap').should('not.have.class', 'disabled'); + cy.get('.requirements-status-notice').should( + isEpIo ? 'not.contain.text' : 'contain.text', + 'You are using a custom proxy. Make sure you implement all security measures needed', + ); + + cy.get('.ep-feature-instant-results [name="settings[active]"][value="1"]').click(); + cy.get('.ep-feature-instant-results .button-primary').click(); + cy.on('window:confirm', () => { + return true; + }); + + cy.get('.ep-sync-progress strong', { + timeout: Cypress.config('elasticPressIndexTimeout'), + }).should('contain.text', 'Sync complete'); + + cy.wpCli('elasticpress list-features').its('stdout').should('contain', 'instant-results'); + }); + + /** + * Test that the instant results list is visible + * It can display the number of test results + * It can show the modal in the same state after a reload + * Can change the URL when search term is changed + */ + it('Can see instant results elements, URL changes, reload, and update after changing search term', () => { + cy.login(); + cy.maybeEnableFeature('instant-results'); + maybeEnableProxy(); + + cy.intercept('*search=blog*').as('apiRequest'); + + cy.visit('/'); + + cy.get('.wp-block-search').last().as('searchBlock'); + + cy.get('@searchBlock').find('.wp-block-search__input').type('blog'); + cy.get('@searchBlock').find('.wp-block-search__button').click(); + cy.get('.ep-search-modal').as('searchModal').should('be.visible'); // Should be visible immediatly + cy.url().should('include', 'search=blog'); + + cy.wait('@apiRequest'); + cy.get('@searchModal').should('contain.text', 'blog'); + // Show the number of results + cy.get('@searchModal').find('.ep-search-results__title').contains(/\d+/); + + cy.get('.ep-search-sidebar #ep-search-post-type-post') + .click() + .then(() => { + cy.url().should('include', 'ep-post_type=post'); + }); + + // Show the modal in the same state after a reload + cy.reload(); + cy.wait('@apiRequest'); + cy.get('@searchModal').should('be.visible').should('contain.text', 'blog'); + + // Update the results when search term is changed + cy.get('@searchModal') + .find('.ep-search-input') + .clearThenType('test') + .then(() => { + cy.wait('@apiRequest'); + cy.get('@searchModal').should('be.visible').should('contain.text', 'test'); + cy.url().should('include', 'search=test'); + }); + + cy.get('#wpadminbar li#wp-admin-bar-debug-bar').click(); + cy.get('#querylist').should('be.visible'); + }); +}); diff --git a/tests/cypress/support/global-hooks.js b/tests/cypress/support/global-hooks.js index f52f467b95..33ba9426f9 100644 --- a/tests/cypress/support/global-hooks.js +++ b/tests/cypress/support/global-hooks.js @@ -1,4 +1,5 @@ window.indexNames = null; +window.isEpIo = false; before(() => { cy.wpCliEval( @@ -24,6 +25,10 @@ before(() => { ).then((wpCliResponse) => { window.indexNames = JSON.parse(wpCliResponse.stdout); }); + + cy.wpCli('eval "echo (int) \\ElasticPress\\Utils\\is_epio();"').then((response) => { + window.isEpIo = response.stdout === '1'; + }); }); afterEach(() => {