diff --git a/.github/workflows/tugboat.yml b/.github/workflows/tugboat.yml
index fdb2e1ddc4..6528e994c5 100644
--- a/.github/workflows/tugboat.yml
+++ b/.github/workflows/tugboat.yml
@@ -48,10 +48,42 @@ jobs:
target_url: "https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}"
});
- - uses: actions/checkout@v1
+ - uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: '14'
+ - name: fetch branch master
+ run: git fetch origin master
+
+ # Cache every node_modules folder inside the monorepo
+ - name: cache all node_modules
+ id: cache-modules
+ uses: actions/cache@v2
+ with:
+ path: '**/node_modules'
+ # We use both yarn.lock and package.json as cache keys to ensure that
+ # changes to local monorepo packages bust the cache.
+ key: ${{ runner.os }}-v${{ matrix.node-version }}-node_modules-${{ hashFiles('yarn.lock', '**/package.json') }}
+
+ # If we get a cache hit for node_modules, there's no need to bring in the global
+ # yarn cache or run yarn install, as all dependencies will be installed already.
+ - name: find location of global yarn cache
+ id: yarn-cache
+ if: steps.cache-modules.outputs.cache-hit != 'true'
+ run: echo "::set-output name=dir::$(yarn cache dir)"
+
+ - name: cache global yarn cache
+ uses: actions/cache@v2
+ if: steps.cache-modules.outputs.cache-hit != 'true'
+ with:
+ path: ${{ steps.yarn-cache.outputs.dir }}
+ key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-yarn-
+
+ - name: yarn install
+ if: steps.cache-modules.outputs.cache-hit != 'true'
+ run: yarn install --frozen-lockfile
# This is required because the environment_url param that Tugboat uses
# to tell us where the preview is located isn't supported unless you
@@ -77,9 +109,12 @@ jobs:
});
console.log(result);
return result.data.environment_url;
+
- name: echo tugboat preview url
- run: |
- curl ${{steps.get-status-env.outputs.result}}
+ env:
+ BACKSTAGE_TEST_URL: ${{steps.get-status-env.outputs.result}}
+ run: yarn e2e-test cypress
+
- name: set status
if: ${{ failure() }}
uses: actions/github-script@v3
@@ -94,6 +129,7 @@ jobs:
context: 'Backstage Tugboat E2E Tests',
target_url: "https://github.com/${{github.repository}}/actions/runs/${{github.run_id}}"
});
+
- name: set status
if: ${{ success() }}
uses: actions/github-script@v3
diff --git a/packages/e2e-test/cypress/plugins/index.js b/packages/e2e-test/cypress/plugins/index.js
new file mode 100644
index 0000000000..aa9918d215
--- /dev/null
+++ b/packages/e2e-test/cypress/plugins/index.js
@@ -0,0 +1,21 @@
+///
+// ***********************************************************
+// This example plugins/index.js can be used to load plugins
+//
+// You can change the location of this file or turn off loading
+// the plugins file with the 'pluginsFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/plugins-guide
+// ***********************************************************
+
+// This function is called when a project is opened or re-opened (e.g. due to
+// the project's config changing)
+
+/**
+ * @type {Cypress.PluginConfig}
+ */
+module.exports = (on, config) => {
+ // `on` is used to hook into various events Cypress emits
+ // `config` is the resolved Cypress config
+}
diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json
index 4327d7161c..828788d7a4 100644
--- a/packages/e2e-test/package.json
+++ b/packages/e2e-test/package.json
@@ -41,5 +41,9 @@
"watch": "./src",
"exec": "bin/e2e-test",
"ext": "ts"
+ },
+ "dependencies": {
+ "@types/cypress": "^1.1.3",
+ "cypress": "^6.4.0"
}
}
diff --git a/packages/e2e-test/src/commands/cypress.ts b/packages/e2e-test/src/commands/cypress.ts
new file mode 100644
index 0000000000..c1aa4d2b6b
--- /dev/null
+++ b/packages/e2e-test/src/commands/cypress.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import cypress from 'cypress';
+import path from 'path';
+
+export async function run() {
+ await cypress.run({
+ reporter: 'junit',
+ browser: 'chrome',
+ config: {
+ watchForFileChanges: true,
+ baseUrl: process.env.BACKSTAGE_TEST_URL || 'http://localhost:7000',
+ integrationFolder: path.resolve(__dirname, '../cypress/integration'),
+ supportFile: path.resolve(__dirname, '../cypress/support'),
+ fixturesFolder: false,
+ defaultCommandTimeout: 10000,
+ },
+ configFile: false,
+ });
+}
diff --git a/packages/e2e-test/src/commands/index.ts b/packages/e2e-test/src/commands/index.ts
index 78ff3343f1..aad051e603 100644
--- a/packages/e2e-test/src/commands/index.ts
+++ b/packages/e2e-test/src/commands/index.ts
@@ -16,7 +16,12 @@
import { CommanderStatic } from 'commander';
import { run } from './run';
+import { run as cypress } from './cypress';
export function registerCommands(program: CommanderStatic) {
program.command('run').description('Run e2e tests').action(run);
+ program
+ .command('cypress')
+ .description('Run cypress e2e tests')
+ .action(cypress);
}
diff --git a/packages/e2e-test/src/cypress/support/index.d.ts b/packages/e2e-test/src/cypress/support/index.d.ts
new file mode 100644
index 0000000000..c9e765f23e
--- /dev/null
+++ b/packages/e2e-test/src/cypress/support/index.d.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// in cypress/support/index.d.ts
+// load type definitions that come with Cypress module
+///
+
+declare namespace Cypress {
+ interface Chainable {
+ /**
+ * Login as guest
+ * @example cy.loginAsGuests
+ */
+ loginAsGuest(value: string): Chainable;
+ }
+}
diff --git a/packages/e2e-test/src/cypress/support/index.ts b/packages/e2e-test/src/cypress/support/index.ts
new file mode 100644
index 0000000000..e17081831e
--- /dev/null
+++ b/packages/e2e-test/src/cypress/support/index.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2021 Spotify AB
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///
+
+Cypress.Commands.add('loginAsGuest', () => {
+ cy.visit('/', {
+ onLoad: (win: Window) =>
+ win.localStorage.setItem('@backstage/core:SignInPage:provider', 'guest'),
+ });
+});
+
+export {};
diff --git a/yarn.lock b/yarn.lock
index 206d1f2705..6fdde6c0f9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6618,6 +6618,13 @@
dependencies:
postcss "5 - 7"
+"@types/cypress@^1.1.3":
+ version "1.1.3"
+ resolved "https://registry.npmjs.org/@types/cypress/-/cypress-1.1.3.tgz#0a700c040d53e9e12b5af98e41d4a88c39f39b6a"
+ integrity sha512-OXe0Gw8LeCflkG1oPgFpyrYWJmEKqYncBsD/J0r17r0ETx/TnIGDNLwXt/pFYSYuYTpzcq1q3g62M9DrfsBL4g==
+ dependencies:
+ cypress "*"
+
"@types/d3-color@*":
version "2.0.0"
resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.0.tgz#febdfadade56e215a4c3f612fe3000d92999f5d5"
@@ -9467,6 +9474,11 @@ bl@^4.0.3:
inherits "^2.0.4"
readable-stream "^3.4.0"
+blob-util@2.0.2:
+ version "2.0.2"
+ resolved "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb"
+ integrity sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==
+
block-stream@*:
version "0.0.9"
resolved "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
@@ -10326,7 +10338,7 @@ cli-spinners@^2.2.0:
resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77"
integrity sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==
-cli-table3@0.6.0:
+cli-table3@0.6.0, cli-table3@~0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee"
integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==
@@ -11511,6 +11523,51 @@ cyclist@^1.0.1:
resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
+cypress@*, cypress@^6.4.0:
+ version "6.4.0"
+ resolved "https://registry.npmjs.org/cypress/-/cypress-6.4.0.tgz#432c516bf4f1a0f042a6aa1f2c3a4278fa35a8b2"
+ integrity sha512-SrsPsZ4IBterudkoFYBvkQmXOVxclh1/+ytbzpV8AH/D2FA+s2Qy5ISsaRzOFsbQa4KZWoi3AKwREmF1HucYkg==
+ dependencies:
+ "@cypress/listr-verbose-renderer" "^0.4.1"
+ "@cypress/request" "^2.88.5"
+ "@cypress/xvfb" "^1.2.4"
+ "@types/sinonjs__fake-timers" "^6.0.1"
+ "@types/sizzle" "^2.3.2"
+ arch "^2.1.2"
+ blob-util "2.0.2"
+ bluebird "^3.7.2"
+ cachedir "^2.3.0"
+ chalk "^4.1.0"
+ check-more-types "^2.24.0"
+ cli-table3 "~0.6.0"
+ commander "^5.1.0"
+ common-tags "^1.8.0"
+ dayjs "^1.9.3"
+ debug "^4.1.1"
+ eventemitter2 "^6.4.2"
+ execa "^4.0.2"
+ executable "^4.1.1"
+ extract-zip "^1.7.0"
+ fs-extra "^9.0.1"
+ getos "^3.2.1"
+ is-ci "^2.0.0"
+ is-installed-globally "^0.3.2"
+ lazy-ass "^1.6.0"
+ listr "^0.14.3"
+ lodash "^4.17.19"
+ log-symbols "^4.0.0"
+ minimist "^1.2.5"
+ moment "^2.29.1"
+ ospath "^1.2.2"
+ pretty-bytes "^5.4.1"
+ ramda "~0.26.1"
+ request-progress "^3.0.0"
+ supports-color "^7.2.0"
+ tmp "~0.2.1"
+ untildify "^4.0.0"
+ url "^0.11.0"
+ yauzl "^2.10.0"
+
cypress@^4.2.0:
version "4.12.1"
resolved "https://registry.npmjs.org/cypress/-/cypress-4.12.1.tgz#0ead1b9f4c0917d69d8b57f996b6e01fe693b6ec"
@@ -11788,6 +11845,11 @@ dateformat@^3.0.0:
resolved "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
+dayjs@^1.9.3:
+ version "1.10.4"
+ resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz#8e544a9b8683f61783f570980a8a80eaf54ab1e2"
+ integrity sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==
+
dayjs@^1.9.4:
version "1.9.4"
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.9.4.tgz#fcde984e227f4296f04e7b05720adad2e1071f1b"
@@ -13286,6 +13348,21 @@ execa@^4.0.0, execa@^4.0.1:
signal-exit "^3.0.2"
strip-final-newline "^2.0.0"
+execa@^4.0.2:
+ version "4.1.0"
+ resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a"
+ integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==
+ dependencies:
+ cross-spawn "^7.0.0"
+ get-stream "^5.0.0"
+ human-signals "^1.1.1"
+ is-stream "^2.0.0"
+ merge-stream "^2.0.0"
+ npm-run-path "^4.0.0"
+ onetime "^5.1.0"
+ signal-exit "^3.0.2"
+ strip-final-newline "^2.0.0"
+
executable@^4.1.1:
version "4.1.1"
resolved "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c"
@@ -18954,7 +19031,7 @@ modify-values@^1.0.0:
resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
-moment@^2.19.3, moment@^2.25.3, moment@^2.26.0, moment@^2.27.0:
+moment@^2.19.3, moment@^2.25.3, moment@^2.26.0, moment@^2.27.0, moment@^2.29.1:
version "2.29.1"
resolved "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
@@ -21329,6 +21406,11 @@ pretty-bytes@^5.3.0:
resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2"
integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==
+pretty-bytes@^5.4.1:
+ version "5.5.0"
+ resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.5.0.tgz#0cecda50a74a941589498011cf23275aa82b339e"
+ integrity sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA==
+
pretty-error@^2.1.1:
version "2.1.1"
resolved "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3"
@@ -24626,6 +24708,13 @@ supports-color@^7.0.0, supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
+supports-color@^7.2.0:
+ version "7.2.0"
+ resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
+ integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
+ dependencies:
+ has-flag "^4.0.0"
+
supports-hyperlinks@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz#f663df252af5f37c5d49bbd7eeefa9e0b9e59e47"
@@ -25099,7 +25188,7 @@ tmp@^0.0.33:
dependencies:
os-tmpdir "~1.0.2"
-tmp@^0.2.0:
+tmp@^0.2.0, tmp@~0.2.1:
version "0.2.1"
resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==