From 824a34d4183986b991070fa63e983462ad00360b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20Sol=C3=A1r?= Date: Fri, 12 Jun 2026 09:48:20 +0000 Subject: [PATCH] fix(js-cypress): stop tests depending on the apify.com marketing site MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The js-cypress template's example specs hit the live apify.com marketing site: first-spec visited `/` and second-spec visited `/store`, clicked `.ActorStoreItem-title` and asserted a redirect. This made the template's CI hostage to the marketing site — React hydration errors (e.g. minified #418), CSS class renames, and slow Windows-runner renders all broke the Node template matrix even though the template itself was unchanged (see run 27280506506). Repoint the demo at https://example.com (IANA/RFC-2606 reserved for documentation — stable markup, no app JS), and harden the specs: - first-spec: assert the stable `Example Domain` heading. - second-spec: select the outbound link by `href*="iana.org"` instead of by visible text (robust to copy changes) and assert visibility, avoiding a cross-origin click. - support/e2e.js: swallow page-level uncaught exceptions so a broken JS handler on the visited page can't auto-fail the demo (documented, with a link to the React error docs). - Update baseUrl default/prefill in cypress.config.js, src/main.js and input_schema.json, and document the new target + how to override it via the `baseUrl` input in the README. The template still demonstrates Cypress + Apify SDK wiring end to end. Co-Authored-By: Claude Opus 4.8 (1M context) --- templates/js-cypress/.actor/input_schema.json | 2 +- templates/js-cypress/README.md | 2 ++ templates/js-cypress/cypress.config.js | 3 ++- templates/js-cypress/cypress/e2e/first-spec.cy.js | 8 +++++--- templates/js-cypress/cypress/e2e/second-spec.cy.js | 14 ++++++++------ templates/js-cypress/cypress/support/e2e.js | 8 ++++++++ templates/js-cypress/src/main.js | 2 +- 7 files changed, 27 insertions(+), 12 deletions(-) diff --git a/templates/js-cypress/.actor/input_schema.json b/templates/js-cypress/.actor/input_schema.json index c989b5455..984efb9c2 100644 --- a/templates/js-cypress/.actor/input_schema.json +++ b/templates/js-cypress/.actor/input_schema.json @@ -10,7 +10,7 @@ "type": "string", "description": "Base url for the tests.", "editor": "textfield", - "prefill": "https://apify.com" + "prefill": "https://example.com" }, "viewportWidth": { "title": "Viewport width", diff --git a/templates/js-cypress/README.md b/templates/js-cypress/README.md index e15093cf1..bd38edb43 100644 --- a/templates/js-cypress/README.md +++ b/templates/js-cypress/README.md @@ -15,6 +15,8 @@ Run your [Cypress tests](https://www.cypress.io/) on the Apify Platform effectiv You can easily run your tests on the Apify Platform, just copy-paste your test files into `cypress/e2e` folder. The tests' names need to end with `-spec.cy.js`. +The bundled example specs visit [`https://example.com`](https://example.com) — a stable site reserved for documentation — so the demo passes reliably out of the box. Point the tests at your own site by setting the `baseUrl` input (or editing `baseUrl` in `cypress.config.js`); `cy.visit('/')` then resolves against it. + You can also customize the test run by specifying other options in the input, e.g. the screen size, video recording, or the default command timeout. After running the tests, the Apify platform stores the results in a comprehensive way - datasets for JSON results, and key-value store for videos. You can view the results directly on the platform or download them to your local machine using a REST API. diff --git a/templates/js-cypress/cypress.config.js b/templates/js-cypress/cypress.config.js index d6dbdb833..26e361a0d 100644 --- a/templates/js-cypress/cypress.config.js +++ b/templates/js-cypress/cypress.config.js @@ -4,6 +4,7 @@ import { defineConfig } from 'cypress'; export default defineConfig({ e2e: { // to be able to run the tests locally for Apify CLI versions 17.0.0 and older - baseUrl: 'https://apify.com', + // Defaults to a stable demo site; override it via the Actor `baseUrl` input. + baseUrl: 'https://example.com', }, }); diff --git a/templates/js-cypress/cypress/e2e/first-spec.cy.js b/templates/js-cypress/cypress/e2e/first-spec.cy.js index da866b5fb..bae5bded5 100644 --- a/templates/js-cypress/cypress/e2e/first-spec.cy.js +++ b/templates/js-cypress/cypress/e2e/first-spec.cy.js @@ -1,7 +1,9 @@ describe('first tests suite', () => { - it('visit Apify main page', () => { + it('visits the homepage', () => { + // `baseUrl` is configured in cypress.config.js (and overridable from the + // Actor input), so cy.visit('/') hits whatever site you point it at. cy.visit('/'); - cy.log('Visiting Apify main page'); - cy.contains('div', 'Apify').should('exist'); + cy.log('Visiting the homepage'); + cy.contains('h1', 'Example Domain').should('be.visible'); }); }); diff --git a/templates/js-cypress/cypress/e2e/second-spec.cy.js b/templates/js-cypress/cypress/e2e/second-spec.cy.js index cd27f82ed..8f4f2559c 100644 --- a/templates/js-cypress/cypress/e2e/second-spec.cy.js +++ b/templates/js-cypress/cypress/e2e/second-spec.cy.js @@ -1,9 +1,11 @@ describe('second tests suite', () => { - it('visit apify store', () => { - cy.visit('/store'); - cy.log('Visiting Apify Store, clicking on Actor'); - cy.contains('.ActorStoreItem-title', 'Web Scraper').should('be.visible').click(); - cy.log('Asserting store Actor redirect'); - cy.url().should('eq', 'https://apify.com/apify/web-scraper'); + it('finds the outbound link', () => { + cy.visit('/'); + cy.log('Locating the outbound link by its target'); + // Select the link by its href attribute rather than its text. This is + // robust to copy changes on the page (the visible label may differ) and + // demonstrates asserting on an attribute instead of clicking through to + // another domain, which Cypress restricts across origins. + cy.get('a[href*="iana.org"]').should('be.visible'); }); }); diff --git a/templates/js-cypress/cypress/support/e2e.js b/templates/js-cypress/cypress/support/e2e.js index 17caa83ad..4a014e0b6 100644 --- a/templates/js-cypress/cypress/support/e2e.js +++ b/templates/js-cypress/cypress/support/e2e.js @@ -12,3 +12,11 @@ // You can read more here: // https://on.cypress.io/guides/configuration#section-global // *********************************************************** + +// By default Cypress fails the test if the visited page throws an uncaught +// exception (e.g. a minified React hydration error like #418: +// https://react.dev/errors/418). For an end-to-end demo we only care that the +// page loads and our assertions pass, not that the site's own JavaScript is +// bug-free, so we swallow page-level exceptions and let the test continue. +// Remove this if you want your own tests to fail on the visited site's errors. +Cypress.on('uncaught:exception', () => false); diff --git a/templates/js-cypress/src/main.js b/templates/js-cypress/src/main.js index 7e266f967..3adf9f76f 100644 --- a/templates/js-cypress/src/main.js +++ b/templates/js-cypress/src/main.js @@ -18,7 +18,7 @@ import { globby } from 'globby'; await Actor.init(); // Define the configuration to start the cypress test with - get it from the input of the Actor or use a default config. -const input = (await Actor.getInput()) || { baseUrl: 'https://apify.com', video: true }; +const input = (await Actor.getInput()) || { baseUrl: 'https://example.com', video: true }; log.info(`Running tests with following input: ${JSON.stringify(input)}`); // Helper function to run tests from specific test file with given configuration from INPUT.json