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

moved cypress out of container #6931

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
client/.tmp/
client/cypress/
node_modules/
viz-lib/node_modules/
.tmp/
Expand All @@ -12,3 +13,8 @@ venv/
/.github/
/netlify.toml
/setup/
.github/
compose.*
*.md
LICENSE*
Dockerfile*
7 changes: 2 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- master
env:
CYPRESS_COVERAGE: "true"
CYPRESS_CACHE_FOLDER: ${{ github.workspace }}/node_modules/.cache/Cypress
NODE_VERSION: 18
YARN_VERSION: 1.22.22
REDASH_COOKIE_SECRET: 2H9gNG9obnAQ9qnR9BDTQUph6CbXKCzF
Expand Down Expand Up @@ -149,10 +150,7 @@ jobs:
runs-on: ubuntu-22.04
needs: frontend-lint
env:
CYPRESS_INSTALL_BINARY: 0
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 1
INSTALL_GROUPS: main
COMPOSE_PROFILES: e2e
PERCY_TOKEN: ${{ secrets.PERCY_TOKEN }}
CYPRESS_PROJECT_ID: ${{ secrets.CYPRESS_PROJECT_ID }}
CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
Expand All @@ -179,8 +177,7 @@ jobs:
touch .env
yarn build
yarn cypress build
yarn cypress start -- --skip-db-seed
docker compose run cypress yarn cypress db-seed
yarn cypress start
- name: Execute Cypress Tests
run: yarn cypress run-ci
- name: "Failure: output container logs to console"
Expand Down
Empty file removed .yarnrc
Empty file.
5 changes: 2 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
RUN useradd -m -d /frontend redash
USER redash
WORKDIR /frontend
COPY --chown=redash package.json yarn.lock .yarnrc /frontend/
COPY --chown=redash package.json yarn.lock /frontend/
COPY --chown=redash viz-lib /frontend/viz-lib
COPY --chown=redash scripts /frontend/scripts

RUN yarn --frozen-lockfile --network-concurrency 1;
RUN yarn --frozen-lockfile --network-concurrency 1
COPY --chown=redash client /frontend/client
COPY --chown=redash webpack.config.js /frontend/
RUN yarn build
Expand Down
12 changes: 0 additions & 12 deletions Dockerfile.cypress

This file was deleted.

6 changes: 0 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

export COMPOSE_DOCKER_CLI_BUILD=1
export DOCKER_BUILDKIT=1
export COMPOSE_PROFILES=local

compose_build: .env
docker compose build
Expand All @@ -28,12 +27,7 @@ create_database: create_db

clean:
docker compose down
docker compose --project-name cypress down
docker compose rm --stop --force
docker compose --project-name cypress rm --stop --force
docker image rm --force \
cypress-server:latest cypress-worker:latest cypress-scheduler:latest \
redash-server:latest redash-worker:latest redash-scheduler:latest
docker container prune --force
docker image prune --force
docker volume prune --force
Expand Down
60 changes: 8 additions & 52 deletions client/cypress/cypress.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,5 @@
/* eslint-disable import/no-extraneous-dependencies, no-console */
const { find } = require("lodash");
const { execSync } = require("child_process");
const { get, post } = require("request").defaults({ jar: true });
const { seedData } = require("./seed-data");
const fs = require("fs");
var Cookie = require("request-cookies").Cookie;

let cypressConfigBaseUrl;
try {
const cypressConfig = JSON.parse(fs.readFileSync("cypress.json"));
cypressConfigBaseUrl = cypressConfig.baseUrl;
} catch (e) {}

const baseUrl = process.env.CYPRESS_baseUrl || cypressConfigBaseUrl || "http://localhost:5001";

function seedDatabase(seedValues) {
get(baseUrl + "/login", (_, { headers }) => {
const request = seedValues.shift();
const data = request.type === "form" ? { formData: request.data } : { json: request.data };

if (headers["set-cookie"]) {
const cookies = headers["set-cookie"].map(cookie => new Cookie(cookie));
const csrfCookie = find(cookies, { key: "csrf_token" });
if (csrfCookie) {
if (request.type === "form") {
data["formData"] = { ...data["formData"], csrf_token: csrfCookie.value };
} else {
data["headers"] = { "X-CSRFToken": csrfCookie.value };
}
}
}

post(baseUrl + request.route, data, (err, response) => {
const result = response ? response.statusCode : err;
console.log("POST " + request.route + " - " + result);
if (seedValues.length) {
seedDatabase(seedValues);
}
});
});
}

function buildServer() {
console.log("Building the server...");
Expand Down Expand Up @@ -67,10 +27,12 @@ function runCypressCI() {
process.env.CYPRESS_OPTIONS = "--record";
}

execSync(
"docker compose run --name cypress cypress ./node_modules/.bin/percy exec -t 300 -- ./node_modules/.bin/cypress run $CYPRESS_OPTIONS",
{ stdio: "inherit" }
);
// Remove four lines below after it's merged
delete process.env.CYPRESS_INSTALL_BINARY;
execSync("rm -r node_modules", { stdio: "inherit" });
execSync("yarn install", { stdio: "inherit" });

execSync("yarn percy cypress run $CYPRESS_OPTIONS", { stdio: "inherit" });
}

const command = process.argv[2] || "all";
Expand All @@ -81,12 +43,6 @@ switch (command) {
break;
case "start":
startServer();
if (!process.argv.includes("--skip-db-seed")) {
seedDatabase(seedData);
}
break;
case "db-seed":
seedDatabase(seedData);
break;
case "run":
execSync("cypress run", { stdio: "inherit" });
Expand All @@ -95,18 +51,18 @@ switch (command) {
execSync("cypress open", { stdio: "inherit" });
break;
case "run-ci":
execSync("docker compose run server create_db", { stdio: "inherit" });
runCypressCI();
break;
case "stop":
stopServer();
break;
case "all":
startServer();
seedDatabase(seedData);
execSync("cypress run", { stdio: "inherit" });
stopServer();
break;
default:
console.log("Usage: yarn cypress [build|start|db-seed|open|run|stop]");
console.log("Usage: yarn cypress [build|start|open|run|stop]");
break;
}
46 changes: 0 additions & 46 deletions client/cypress/seed-data.js

This file was deleted.

101 changes: 100 additions & 1 deletion client/cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,106 @@ import "@testing-library/cypress/add-commands";

const { each } = Cypress._;

Cypress.Commands.add("login", (email = "admin@redash.io", password = "password") => {
const LOGIN_NAME = process.env.CYPRESS_LOGIN_NAME || "Example Admin";
const LOGIN_EMAIL = process.env.CYPRESS_LOGIN_EMAIL || "admin@redash.io";
const LOGIN_PASSWORD = process.env.CYPRESS_LOGIN_PASSWORD || "password";
const ORG_NAME = process.env.CYPRESS_ORG_NAME || "Redash";

Cypress.Commands.add("setup", () => {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can I call this from terminal?
I got stuck so it never pass login screen on any test after I typed npm run cypress all

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this cypress command can be called using cy.setup, it's added to client/cypress/support/commands.js
it's executed before e2e tests execution. you need to run yarn cypress run-ci

Copy link

@mirkan1 mirkan1 May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested it on both node v16 and v20; this file has no access to .env file so please accept PR#24

const email = LOGIN_EMAIL;
const password = LOGIN_PASSWORD;
const org_name = ORG_NAME;
const name = LOGIN_NAME;
let csrf;
cy.visit("/setup");
cy.location().then(loc => {
if (loc.pathname === "/setup") {
cy.getCookie("csrf_token")
.then(cookie => {
if (cookie) {
csrf = cookie.value;
} else {
cy.visit("/setup").then(() => {
cy.get('input[name="csrf_token"]')
.invoke("val")
.then(csrf_token => {
csrf = csrf_token;
});
});
}
})
.then(() => {
cy.request({
url: "/setup",
method: "POST",
form: true,
body: {
name,
org_name,
email,
password,
csrf_token: csrf,
},
});
});
cy.login();
cy.setupDatasource();
cy.setupDestination();
}
});
});

Cypress.Commands.add("setupDatasource", () => {
const dbname = "postgres";
const host = "postgres";
const port = 5432;
const sslmode = "prefer";
const user = "postgres";
cy.getCookie("csrf_token").then(cookie => {
cy.request({
headers: {
"X-CSRF-TOKEN": cookie.value,
},
url: "/api/data_sources",
method: "POST",
body: {
name: "Test PostgreSQL",
options: {
dbname,
host,
port,
sslmode,
user,
},
type: "pg",
},
});
});
});

Cypress.Commands.add("setupDestination", () => {
const name = "Test Email Destination";
const options = {
addresses: "test@example.com",
};
const type = "email";
cy.getCookie("csrf_token").then(cookie => {
cy.request({
headers: {
"X-CSRF-TOKEN": cookie.value,
},
url: "/api/destinations",
method: "POST",
body: {
name,
options,
type,
},
});
});
});

Cypress.Commands.add("login", (email = LOGIN_EMAIL, password = LOGIN_PASSWORD) => {
let csrf;
cy.visit("/login");
cy.getCookie("csrf_token")
Expand Down
4 changes: 4 additions & 0 deletions client/cypress/support/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ Cypress.on("uncaught:exception", err => {
return false;
}
});

before(() => {
cy.setup();
});
1 change: 1 addition & 0 deletions compose.base.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
services:
.redash:
image: local/redash:latest
build:
context: .
args:
Expand Down