Skip to content

Commit 840773e

Browse files
authored
feat: get docker-compose to work as the backend for Cypress tests (#31796)
1 parent 2874096 commit 840773e

File tree

15 files changed

+110
-113
lines changed

15 files changed

+110
-113
lines changed

docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ services:
8989
restart: unless-stopped
9090
ports:
9191
- 8088:8088
92+
# When in cypress-mode ->
93+
- 8081:8081
9294
extra_hosts:
9395
- "host.docker.internal:host-gateway"
9496
user: *superset-user

docker/docker-bootstrap.sh

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ if [ "$DEV_MODE" == "true" ]; then
2626
fi
2727
fi
2828
REQUIREMENTS_LOCAL="/app/docker/requirements-local.txt"
29+
PORT=${PORT:-8088}
2930
# If Cypress run – overwrite the password for admin and export env variables
3031
if [ "$CYPRESS_CONFIG" == "true" ]; then
31-
export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
3232
export SUPERSET_TESTENV=true
33-
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset
33+
export POSTGRES_DB=superset_cypress
34+
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset_cypress
35+
PORT=8081
3436
fi
3537
if [[ "$DATABASE_DIALECT" == postgres* ]] ; then
3638
echo "Installing postgres requirements"
@@ -65,7 +67,7 @@ case "${1}" in
6567
;;
6668
app)
6769
echo "Starting web app (using development server)..."
68-
flask run -p 8088 --with-threads --reload --debugger --host=0.0.0.0
70+
flask run -p $PORT --with-threads --reload --debugger --host=0.0.0.0
6971
;;
7072
app-gunicorn)
7173
echo "Starting web app..."
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env bash
2+
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
# ------------------------------------------------------------------------
21+
# Creates the examples database and respective user. This database location
22+
# and access credentials are defined on the environment variables
23+
# ------------------------------------------------------------------------
24+
set -e
25+
26+
psql -v ON_ERROR_STOP=1 --username "${POSTGRES_USER}" <<-EOSQL
27+
CREATE DATABASE superset_cypress;
28+
EOSQL

docker/docker-init.sh

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,18 @@ fi
3030

3131
echo_step() {
3232
cat <<EOF
33-
3433
######################################################################
35-
36-
3734
Init Step ${1}/${STEP_CNT} [${2}] -- ${3}
38-
39-
4035
######################################################################
41-
4236
EOF
4337
}
4438
ADMIN_PASSWORD="${ADMIN_PASSWORD:-admin}"
4539
# If Cypress run – overwrite the password for admin and export env variables
4640
if [ "$CYPRESS_CONFIG" == "true" ]; then
4741
ADMIN_PASSWORD="general"
48-
export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
4942
export SUPERSET_TESTENV=true
50-
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset
43+
export POSTGRES_DB=superset_cypress
44+
export SUPERSET__SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://superset:superset@db:5432/superset_cypress
5145
fi
5246
# Initialize the database
5347
echo_step "1" "Starting" "Applying DB migrations"
@@ -57,11 +51,11 @@ echo_step "1" "Complete" "Applying DB migrations"
5751
# Create an admin user
5852
echo_step "2" "Starting" "Setting up admin user ( admin / $ADMIN_PASSWORD )"
5953
superset fab create-admin \
60-
--username admin \
61-
--firstname Superset \
62-
--lastname Admin \
63-
64-
--password "$ADMIN_PASSWORD"
54+
--username admin \
55+
--firstname Superset \
56+
--lastname Admin \
57+
58+
--password "$ADMIN_PASSWORD"
6559
echo_step "2" "Complete" "Setting up admin user"
6660
# Create default roles and permissions
6761
echo_step "3" "Starting" "Setting up roles and perms"

docker/pythonpath_dev/superset_config.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#
2323
import logging
2424
import os
25+
import sys
2526

2627
from celery.schedules import crontab
2728
from flask_caching.backends.filesystemcache import FileSystemCache
@@ -107,6 +108,18 @@ class CeleryConfig:
107108
log_level_text = os.getenv("SUPERSET_LOG_LEVEL", "INFO")
108109
LOG_LEVEL = getattr(logging, log_level_text.upper(), logging.INFO)
109110

111+
if os.getenv("CYPRESS_CONFIG") == "true":
112+
# When running the service as a cypress backend, we need to import the config
113+
# located @ tests/integration_tests/superset_test_config.py
114+
base_dir = os.path.dirname(__file__)
115+
module_folder = os.path.abspath(
116+
os.path.join(base_dir, "../../tests/integration_tests/")
117+
)
118+
sys.path.insert(0, module_folder)
119+
from superset_test_config import * # noqa
120+
121+
sys.path.pop(0)
122+
110123
#
111124
# Optionally import superset_config_docker.py (which will have been included on
112125
# the PYTHONPATH) in order to allow for local settings to be overridden

docs/docs/contributing/development.mdx

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -643,71 +643,6 @@ To run a single test file:
643643
npm run test -- path/to/file.js
644644
```
645645
646-
### Integration Testing
647-
648-
We use [Cypress](https://www.cypress.io/) for integration tests. To open Cypress and explore tests first setup and run test server:
649-
650-
```bash
651-
export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
652-
export SUPERSET_TESTENV=true
653-
export CYPRESS_BASE_URL="http://localhost:8081"
654-
superset db upgrade
655-
superset load_test_users
656-
superset load-examples --load-test-data
657-
superset init
658-
superset run --port 8081
659-
```
660-
661-
Run Cypress tests:
662-
663-
```bash
664-
cd superset-frontend
665-
npm run build-instrumented
666-
667-
cd cypress-base
668-
npm install
669-
670-
# run tests via headless Chrome browser (requires Chrome 64+)
671-
npm run cypress-run-chrome
672-
673-
# run tests from a specific file
674-
npm run cypress-run-chrome -- --spec cypress/e2e/explore/link.test.ts
675-
676-
# run specific file with video capture
677-
npm run cypress-run-chrome -- --spec cypress/e2e/dashboard/index.test.js --config video=true
678-
679-
# to open the cypress ui
680-
npm run cypress-debug
681-
682-
# to point cypress to a url other than the default (http://localhost:8088) set the environment variable before running the script
683-
# e.g., CYPRESS_BASE_URL="http://localhost:9000"
684-
CYPRESS_BASE_URL=<your url> npm run cypress open
685-
```
686-
687-
See [`superset-frontend/cypress_build.sh`](https://github.com/apache/superset/blob/master/superset-frontend/cypress_build.sh).
688-
689-
As an alternative you can use docker compose environment for testing:
690-
691-
Make sure you have added below line to your /etc/hosts file:
692-
`127.0.0.1 db`
693-
694-
If you already have launched Docker environment please use the following command to ensure a fresh database instance:
695-
`docker compose down -v`
696-
697-
Launch environment:
698-
699-
`CYPRESS_CONFIG=true docker compose up --build`
700-
701-
It will serve the backend and frontend on port 8088.
702-
703-
Run Cypress tests:
704-
705-
```bash
706-
cd cypress-base
707-
npm install
708-
npm run cypress open
709-
```
710-
711646
### Debugging Server App
712647
713648
#### Local

docs/docs/contributing/howtos.mdx

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -225,22 +225,10 @@ npm run test -- path/to/file.js
225225
226226
### e2e Integration Testing
227227
228-
For e2e testing, we recommend that you use a `docker-compose` backed-setup
229-
230-
Alternatively, you can go lower level and set things up in your
231-
development environment by following these steps:
232-
233-
First set up a python/flask backend:
228+
For e2e testing, we recommend that you use a `docker compose` backend
234229
235230
```bash
236-
export SUPERSET_CONFIG=tests.integration_tests.superset_test_config
237-
export SUPERSET_TESTENV=true
238-
export CYPRESS_BASE_URL="http://localhost:8081"
239-
superset db upgrade
240-
superset load_test_users
241-
superset init
242-
superset load-examples --load-test-data
243-
superset run --port 8081
231+
CYPRESS_CONFIG=true docker compose up
244232
```
245233
246234
In another terminal, prepare the frontend and run Cypress tests:
@@ -255,6 +243,9 @@ npm install
255243
# run tests via headless Chrome browser (requires Chrome 64+)
256244
npm run cypress-run-chrome
257245
246+
# use interactive mode to run tests, while keeping memory usage contained (default is 50!)
247+
npx cypress open --config numTestsKeptInMemory=3
248+
258249
# run tests from a specific file
259250
npm run cypress-run-chrome -- --spec cypress/e2e/explore/link.test.ts
260251

scripts/cypress_run.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ def run_cypress_for_test_file(
5555
group_id = f"matrix{group}-file{i}-{attempt}"
5656
cmd = (
5757
f"{XVFB_PRE_CMD} "
58-
f'{cypress_cmd} --spec "{test_file}" --browser {browser} '
58+
f'{cypress_cmd} --spec "{test_file}" '
59+
f"--config numTestsKeptInMemory=0 "
60+
f"--browser {browser} "
5961
f"--record --group {group_id} --tag {REPO},{GITHUB_EVENT_NAME} "
6062
f"--ci-build-id {build_id} "
6163
f"-- {chrome_flags}"
@@ -64,7 +66,9 @@ def run_cypress_for_test_file(
6466
os.environ.pop("CYPRESS_RECORD_KEY", None)
6567
cmd = (
6668
f"{XVFB_PRE_CMD} "
67-
f"{cypress_cmd} --browser {browser} "
69+
f"{cypress_cmd} "
70+
f"--browser {browser} "
71+
f"--config numTestsKeptInMemory=0 "
6872
f'--spec "{test_file}" '
6973
f"-- {chrome_flags}"
7074
)

superset-frontend/cypress-base/cypress.config.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ export default eyesPlugin(
2626
defineConfig({
2727
chromeWebSecurity: false,
2828
defaultCommandTimeout: 8000,
29-
numTestsKeptInMemory: 0,
30-
experimentalFetchPolyfill: true,
29+
numTestsKeptInMemory: 5,
30+
// Disabled after realizing this MESSES UP rison encoding in intricate ways
31+
experimentalFetchPolyfill: false,
3132
experimentalMemoryManagement: true,
3233
requestTimeout: 10000,
3334
video: false,
@@ -62,6 +63,7 @@ export default eyesPlugin(
6263
}
6364
return launchOptions;
6465
});
66+
6567
// eslint-disable-next-line global-require
6668
require('@cypress/code-coverage/task')(on, config);
6769
on('task', verifyDownloadTasks);
@@ -70,6 +72,7 @@ export default eyesPlugin(
7072
},
7173
baseUrl: 'http://localhost:8088',
7274
excludeSpecPattern: [],
75+
experimentalRunAllSpecs: true,
7376
specPattern: [
7477
'cypress/e2e/**/*.{js,jsx,ts,tsx}',
7578
'cypress/applitools/**/*.{js,jsx,ts,tsx}',

superset-frontend/cypress-base/cypress/e2e/chart_list/list.test.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import {
2626
visitSampleChartFromList,
2727
saveChartToDashboard,
2828
interceptFiltering,
29+
interceptFavoriteStatus,
2930
} from '../explore/utils';
3031
import { interceptGet as interceptDashboardGet } from '../dashboard/utils';
3132

@@ -49,8 +50,10 @@ function confirmDelete() {
4950

5051
function visitChartList() {
5152
interceptFiltering();
53+
interceptFavoriteStatus();
5254
cy.visit(CHART_LIST);
5355
cy.wait('@filtering');
56+
cy.wait('@favoriteStatus');
5457
}
5558

5659
describe('Charts list', () => {
@@ -78,20 +81,15 @@ describe('Charts list', () => {
7881
cy.wait('@get');
7982
});
8083

81-
it('should show the newly added dashboards in a tooltip', () => {
84+
it.only('should show the newly added dashboards in a tooltip', () => {
8285
interceptDashboardGet();
8386
visitSampleChartFromList('1 - Sample chart');
8487
saveChartToDashboard('1 - Sample dashboard');
8588
saveChartToDashboard('2 - Sample dashboard');
8689
saveChartToDashboard('3 - Sample dashboard');
8790
visitChartList();
91+
8892
cy.getBySel('count-crosslinks').should('be.visible');
89-
cy.getBySel('crosslinks').first().trigger('mouseover');
90-
cy.get('.antd5-tooltip')
91-
.contains('3 - Sample dashboard')
92-
.invoke('removeAttr', 'target')
93-
.click();
94-
cy.wait('@get');
9593
});
9694
});
9795

@@ -116,7 +114,7 @@ describe('Charts list', () => {
116114

117115
it('should sort correctly in list mode', () => {
118116
cy.getBySel('sort-header').eq(1).click();
119-
cy.getBySel('table-row').first().contains('% Rural');
117+
cy.getBySel('table-row').first().contains('Area Chart');
120118
cy.getBySel('sort-header').eq(1).click();
121119
cy.getBySel('table-row').first().contains("World's Population");
122120
cy.getBySel('sort-header').eq(1).click();

0 commit comments

Comments
 (0)