Skip to content
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

WIP - not ready - e2e cypress run in CI #2580

Open
wants to merge 19 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/e2e.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: e2e
on:
workflow_call:
jobs:
e2e-tests:
env:
CI: true
CONNECT_LICENSE: ${{ secrets.CONNECT_LICENSE }}
strategy:
fail-fast: false
matrix:
runs-on: [ubuntu-latest]
runs-on: ${{ matrix.runs-on }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: ./.github/actions/setup
- uses: extractions/setup-just@v2
- uses: actions/download-artifact@v4
with:
name: dist
path: dist

- name: Extract dist
run: unzip dist/*-linux-amd64.vsix -d dist/

- run: just test/e2e/build-images
- run: just test/e2e/cypress-run
11 changes: 3 additions & 8 deletions .github/workflows/pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,10 @@ jobs:
uses: ./.github/workflows/upload.yaml
secrets: inherit

# Integration Tests
# bats:
# needs: build
# secrets: inherit
# uses: ./.github/workflows/bats.yaml

vscode-ui:
# E2E Tests
e2e:
needs:
- build
- package
secrets: inherit
uses: ./.github/workflows/vscode-ui.yaml
uses: ./.github/workflows/e2e.yaml
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,10 @@ node_modules
.pnpm-store
.Rproj.user

# Possible e2e tests assets
test/e2e/content-workspace/**/.posit
test/e2e/cypress/downloads/
test/e2e/cypress/screenshots/

# Possible e2e tests deployment assets
test/e2e/content-workspace/**/.posit
25 changes: 19 additions & 6 deletions test/e2e/Dockerfile.cypress
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
FROM cypress/browsers:node-18.20.3-chrome-125.0.6422.141-1-ff-126.0.1-edge-125.0.2535.85-1

RUN mkdir /app
WORKDIR /app
# Install Python and required system dependencies
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
python3-venv \
&& rm -rf /var/lib/apt/lists/*

COPY package*.json ./
RUN npm ci
# Create and activate virtual environment
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

ENV PATH /app/node_modules/.bin:$PATH
# Install rsconnect, used for bootstraping first user and API key
RUN pip install rsconnect-python

# Setup the env for Cypress
WORKDIR /app/e2e

CMD ["cypress", "run"]
COPY test/e2e/package*.json ./
RUN npm ci

ENV PATH /app/e2e/node_modules/.bin:$PATH

CMD ["cypress", "run", "--browser", "chrome"]
21 changes: 17 additions & 4 deletions test/e2e/cypress.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,29 @@ module.exports = defineConfig({
baseUrl: "http://localhost:8080",
supportFile: "support/index.js",
specPattern: "tests/**/*.cy.{js,jsx,ts,tsx}",
defaultCommandTimeout: 20000,
// eslint-disable-next-line no-unused-vars
setupNodeEvents(on, config) {
// implement node event listeners here
on("before:browser:launch", (browser = {}, launchOptions) => {
// Allow the non SSL access point to code server http://code-server:8080
// to be treated as secure, else, vscode complains about security and does not load.
// > 'crypto.subtle' is not available so webviews will not work.
// This is likely because the editor is not running in a secure context
// (https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).
if (browser.name === "chrome") {
launchOptions.args.push(
"--unsafely-treat-insecure-origin-as-secure=http://code-server:8080",
);
}
return launchOptions;
});
},
},
env: {
BOOTSTRAP_ADMIN_API_KEY: "", // To be updated by Cypress when spinning up
BOOTSTRAP_SECRET_KEY: "bootstrap-secret.key", // To be updated by Cypress when spinning up
CONNECT_SERVER_URL: "http://localhost:3939",
CONNECT_MANAGER_URL: "http://localhost:4723",
BOOTSTRAP_SECRET_KEY: "bootstrap-secret.key",
CONNECT_SERVER_URL: "http://localhost:3939", // Updated by docker-compose env var for CI runs
CONNECT_MANAGER_URL: "http://localhost:4723", // Updated by docker-compose env var for CI runs
},
chromeWebSecurity: false,
});
14 changes: 14 additions & 0 deletions test/e2e/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,17 @@ services:
- ../../dist:/home/coder/vsix
ports:
- "8080:8080"

# Cypress instance, meant to be used only on CI
# or to run e2e tests without the Cypress UI
cypress:
container_name: publisher-e2e.cypress
build:
context: ../..
dockerfile: test/e2e/Dockerfile.cypress
environment:
- CYPRESS_BASE_URL=http://code-server:8080
- CYPRESS_CONNECT_SERVER_URL=http://connect-publisher-e2e:3939
- CYPRESS_CONNECT_MANAGER_URL=http://connect-publisher-e2e:4723
volumes:
- ./:/app/e2e
31 changes: 28 additions & 3 deletions test/e2e/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,16 @@ stop:
lint:
npm run lint

# Install local dependencies, start Connect in development mode, and open Cypress UI locally (not from a container)
build-images:
#!/usr/bin/env bash
set -euo pipefail

just build "connect-publisher-e2e"
just build "code-server"
just build "cypress"

# Install local dependencies, start Connect in development mode,
# and open Cypress UI locally (not from a container)
dev:
#!/usr/bin/env bash
set -euo pipefail
Expand All @@ -34,12 +43,28 @@ dev:
USE_PLATFORM="linux/amd64" just ../../package
just clear-credentials
just install
just build "connect-publisher-e2e"
just build "code-server"
just start "connect-publisher-e2e"
just start "code-server"
npm run cypress:open

# Run Cypress tests using the CLI
# Meant for CI or automatic runs where a build for linux/amd64 already exists
cypress-run:
#!/usr/bin/env bash
set -euo pipefail

function cleanup() {
just clear-credentials
}
trap cleanup EXIT

just clear-credentials
just install
just start "connect-publisher-e2e"
just start "code-server"
docker compose run --rm cypress
just stop

clear-credentials:
#!/usr/bin/env bash
set -euo pipefail
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/tests/credentials.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ describe("Credentials Section", () => {

cy.findInPublisherWebview(
'[data-automation="admin-code-server-list"]',
).then(($credRecord) => {
).should(($credRecord) => {
expect($credRecord.find(".tree-item-title").text()).to.equal(
"admin-code-server",
);
Expand Down
20 changes: 7 additions & 13 deletions test/e2e/tests/deployments.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,6 @@ describe("Deployments Section", () => {
.should("be.visible")
.click();

cy.loadProjectConfigFile("static").then((config) => {
expect(config.title).to.equal("static");
expect(config.type).to.equal("html");
expect(config.entrypoint).to.equal("index.html");
expect(config.files[0]).to.equal("/index.html");
expect(config.files[1]).to.match(
/\/.posit\/publish\/static-[A-Z0-9]{4}\.toml/,
);
expect(config.files[2]).to.match(
/\/.posit\/publish\/deployments\/deployment-[A-Z0-9]{4}\.toml/,
);
});

cy.publisherWebview()
.findByTestId("deploy-button")
.should("be.visible")
Expand All @@ -83,5 +70,12 @@ describe("Deployments Section", () => {
.should("not.exist");

cy.findByText("Deployment was successful").should("be.visible");

cy.loadProjectConfigFile("static").then((config) => {
expect(config.title).to.equal("static");
expect(config.type).to.equal("html");
expect(config.entrypoint).to.equal("index.html");
expect(config.files[0]).to.equal("/index.html");
});
});
});
Loading