Skip to content

Commit 709a859

Browse files
test(ddev): Add end-to-end test for ddev stack [WIP]
1 parent 8f2d19f commit 709a859

24 files changed

+1629
-0
lines changed

docs/ddev.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# DDEV-Local stack for WordPress
2+
3+
The purpose of this repo is to share my WordPress [DDEV-Local](https://ddev.readthedocs.io/en/stable/) stack.
4+
5+
6+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
7+
8+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
9+
10+
## Quick start
11+
12+
_We will suppose that you want to test on a WordPress 5.6.5 instance. Change the version number if you prefer another
13+
release._
14+
15+
### DDEV-Local installation
16+
17+
Please follow the [official instructions](https://ddev.readthedocs.io/en/stable/#installation). On a Linux
18+
distribution, this should be as simple as
19+
20+
sudo apt-get install linuxbrew-wrapper
21+
brew tap drud/ddev && brew install ddev
22+
23+
24+
### Prepare DDEV WordPress environment
25+
26+
The final structure of the project will look like below.
27+
28+
```
29+
wp-sources
30+
31+
│ (WordPress sources)
32+
33+
└───.ddev
34+
│ │
35+
│ │ (Cloned sources of a specific WordPress ddev repo)
36+
37+
└───my-own-modules
38+
39+
40+
└───crowdsec-bouncer
41+
42+
│ (Sources of a this module)
43+
44+
```
45+
46+
- Create an empty folder that will contain all necessary sources:
47+
```
48+
mkdir wp-sources
49+
```
50+
- Create an empty `.ddev` folder for DDEV and clone our pre-configured DDEV repo:
51+
52+
```
53+
mkdir wp-sources/.ddev && cd wp-sources/.ddev && git clone git@github.com:julienloizelet/ddev-wp.git ./
54+
```
55+
- Copy some configurations file:
56+
57+
```
58+
cp .ddev/config_overrides/config.wp565.yaml .ddev/config.wp565.yaml
59+
cp .ddev/config_overrides/config.crowdsec.yaml .ddev/config.crowdsec.yaml
60+
```
61+
- Launch DDEV
62+
63+
```
64+
cd .ddev && ddev start
65+
```
66+
This should take some times on the first launch as this will download all necessary docker images.
67+
68+
69+
### WordPress installation
70+
71+
```
72+
cd wp-sources
73+
wget https://wordpress.org/wordpress-5.6.5.tar.gz
74+
tar -xf wordpress-5.6.5.tar.gz wordpress
75+
cp -r wordpress/. ./
76+
rm -rf wordpress
77+
rm wordpress-5.6.5.tar.gz
78+
ddev start
79+
ddev exec wp core install --url='https://wp565.ddev.site' --title='WordPress' --admin_user='admin'
80+
--admin_password='admin123' --admin_email='admin@admin.com'
81+
82+
```
83+
84+
85+
## Usage
86+
87+
### Test the module
88+
89+
#### End-to-end tests
90+
91+
```
92+
cd wp-sources/my-own-module/crowdsec-bouncer/tests/e2e-ddev/__scripts__
93+
```
94+
95+
Before testing with the `docker` or `ci` parameter, you have to install all the required dependencies
96+
in the playwright container with this command :
97+
98+
./test-init.sh
99+
100+
If you want to test with the `host` parameter, you will have to install manually all the required dependencies:
101+
102+
```
103+
yarn --cwd ./tests/e2e-ddev --force
104+
yarn global add cross-env
105+
```
106+
107+
Finally, you can test by running:
108+
109+
`./run-test.sh [context] [files]` where `[context]` can be `ci`, `docker` or `host` and files is the list of file to
110+
test (all files if empty);
111+
112+
For example:
113+
114+
`./run-tests.sh host "./2-live-mode-remediations.js"`
115+
116+
## License
117+
118+
[MIT](LICENSE)

tests/e2e-ddev/.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

tests/e2e-ddev/.eslintrc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"parserOptions": {
3+
// Required for certain syntax usages
4+
"ecmaVersion": 2018
5+
},
6+
"extends": [
7+
"eslint:recommended",
8+
"airbnb-base",
9+
"plugin:prettier/recommended"
10+
],
11+
"rules": {
12+
"no-unused-vars": 1,
13+
"no-underscore-dangle": 0,
14+
"import/no-dynamic-require": 0,
15+
"no-console": [1, { "allow": ["warn", "error", "debug"] }]
16+
},
17+
"env": {
18+
"jest": true
19+
}
20+
}

tests/e2e-ddev/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
.cookies.json
3+
.test-results-*.json
4+
*.lock
5+
*.log

tests/e2e-ddev/.prettierrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"semi": true,
3+
"trailingComma": "all",
4+
"printWidth": 80,
5+
"tabWidth": 4
6+
}

tests/e2e-ddev/CustomEnvironment.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const PlaywrightEnvironment =
2+
require("jest-playwright-preset/lib/PlaywrightEnvironment").default;
3+
4+
class CustomEnvironment extends PlaywrightEnvironment {
5+
async handleTestEvent(event) {
6+
if (process.env.FAIL_FAST) {
7+
if (
8+
event.name === "hook_failure" ||
9+
event.name === "test_fn_failure"
10+
) {
11+
this.failedTest = true;
12+
} else if (this.failedTest && event.name === "test_start") {
13+
// eslint-disable-next-line no-param-reassign
14+
event.test.mode = "skip";
15+
}
16+
}
17+
18+
if (super.handleTestEvent) {
19+
await super.handleTestEvent(event);
20+
}
21+
}
22+
}
23+
24+
module.exports = CustomEnvironment;
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/bin/bash
2+
# Run test suite
3+
# Usage: ./run-tests.sh <type> <file-list>
4+
# type : host, docker or ci (default: host)
5+
# file-list : a list of test files (default: empty so it will run all the tests)
6+
# Example: ./run-tests.sh docker "./__tests__/2-live-mode-remediations.js ./__tests__/3-live-mode-more.js"
7+
8+
YELLOW='\033[33m'
9+
RESET='\033[0m'
10+
if ! ddev --version >/dev/null 2>&1; then
11+
printf "${YELLOW}Ddev is required for this script. Please see doc/ddev.md.${RESET}\n"
12+
exit 1
13+
fi
14+
15+
16+
TYPE=${1:-host}
17+
FILE_LIST=${2:-""}
18+
19+
20+
case $TYPE in
21+
"host")
22+
echo "Running with host stack"
23+
;;
24+
25+
"docker")
26+
echo "Running with ddev docker stack"
27+
;;
28+
29+
30+
"ci")
31+
echo "Running in CI context"
32+
;;
33+
34+
*)
35+
echo "Unknown param '${TYPE}'"
36+
echo "Usage: ./run-tests.sh <type> <file-list>"
37+
exit 1
38+
;;
39+
esac
40+
41+
42+
HOSTNAME=$(ddev exec printenv DDEV_HOSTNAME | sed 's/\r//g')
43+
WORDPRESS_VERSION=$(ddev exec printenv DDEV_PROJECT | sed 's/\r//g' | sed 's/wp//g')
44+
WORDPRESS_URL=https://$HOSTNAME
45+
PROXY_IP=$(ddev find-ip ddev-router)
46+
BOUNCER_KEY=$(ddev exec wp option get crowdsec_api_key | tail -n 2 | head -n 1 | sed 's/\r//g')
47+
JEST_PARAMS="--bail=true --runInBand --verbose"
48+
# If FAIL_FAST, will exit on first individual test fail
49+
# @see CustomEnvironment.js
50+
FAIL_FAST=true
51+
52+
53+
case $TYPE in
54+
"host")
55+
cd "../"
56+
DEBUG_STRING="PWDEBUG=1"
57+
YARN_PATH="./"
58+
COMMAND="yarn --cwd ${YARN_PATH} cross-env"
59+
LAPI_URL_FROM_PLAYWRIGHT=http://$HOSTNAME:8080
60+
CURRENT_IP=$(ddev find-ip host)
61+
TIMEOUT=31000
62+
HEADLESS=false
63+
SLOWMO=150
64+
;;
65+
66+
"docker")
67+
DEBUG_STRING=""
68+
YARN_PATH="./var/www/html/my-own-modules/crowdsec-bouncer/Test/EndToEnd"
69+
COMMAND="ddev exec -s playwright yarn --cwd ${YARN_PATH} cross-env"
70+
LAPI_URL_FROM_PLAYWRIGHT=http://crowdsec:8080
71+
CURRENT_IP=$(ddev find-ip playwright)
72+
TIMEOUT=31000
73+
HEADLESS=true
74+
SLOWMO=0
75+
;;
76+
77+
"ci")
78+
DEBUG_STRING="DEBUG=pw:api"
79+
YARN_PATH="./var/www/html/my-own-modules/crowdsec-bouncer/Test/EndToEnd"
80+
COMMAND="ddev exec -s playwright xvfb-run --auto-servernum -- yarn --cwd ${YARN_PATH} cross-env"
81+
LAPI_URL_FROM_PLAYWRIGHT=http://crowdsec:8080
82+
CURRENT_IP=$(ddev find-ip playwright)
83+
TIMEOUT=60000
84+
HEADLESS=true
85+
SLOWMO=0
86+
;;
87+
88+
*)
89+
echo "Unknown param '${TYPE}'"
90+
echo "Usage: ./run-tests.sh <type> <file-list>"
91+
exit 1
92+
;;
93+
esac
94+
95+
96+
97+
# Run command
98+
99+
$COMMAND \
100+
WORDPRESS_URL=$WORDPRESS_URL \
101+
$DEBUG_STRING \
102+
BOUNCER_KEY=$BOUNCER_KEY \
103+
PROXY_IP=$PROXY_IP \
104+
LAPI_URL_FROM_PLAYWRIGHT=$LAPI_URL_FROM_PLAYWRIGHT \
105+
CURRENT_IP=$CURRENT_IP \
106+
TIMEOUT=$TIMEOUT \
107+
HEADLESS=$HEADLESS \
108+
FAIL_FAST=$FAIL_FAST \
109+
SLOWMO=$SLOWMO \
110+
yarn --cwd $YARN_PATH test \
111+
$JEST_PARAMS \
112+
--json \
113+
--outputFile=./.test-results-$M2VERSION.json \
114+
$FILE_LIST
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash
2+
# Prepare Playwright container before testing
3+
# Usage : ./test-init.sh
4+
5+
YELLOW='\033[33m'
6+
RESET='\033[0m'
7+
if ! ddev --version >/dev/null 2>&1; then
8+
printf "${YELLOW}Ddev is required for this script. Please see doc/ddev.md.${RESET}\n"
9+
exit 1
10+
fi
11+
12+
ddev exec -s playwright yarn --cwd ./var/www/html/my-own-modules/crowdsec-bouncer/tests/e2e-ddev --force && \
13+
ddev exec -s playwright yarn global add cross-env
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* eslint-disable no-undef */
2+
const {
3+
ADMIN_LOGIN,
4+
ADMIN_PASSWORD,
5+
WORDPRESS_VERSION,
6+
WP58,
7+
WP57,
8+
WP56,
9+
WP55,
10+
WP54,
11+
WP53,
12+
} = require("../utils/constants");
13+
14+
const {
15+
notify,
16+
waitForNavigation,
17+
goToPublicPage,
18+
disableAutoPrependFileInHtaccess,
19+
deleteExistingStandaloneSettings,
20+
} = require("../utils/helpers");
21+
22+
describe(`Setup WordPress ${WORDPRESS_VERSION}`, () => {
23+
it('Should install wordpress"', async () => {
24+
// Remove the htaccess directive if existing from a previous test run.
25+
await disableAutoPrependFileInHtaccess();
26+
await deleteExistingStandaloneSettings();
27+
28+
// Go to home
29+
await goToPublicPage();
30+
31+
if (WP54 || WP55 || WP56 || WP57 || WP58) {
32+
// "Language selection" page
33+
await page.click('option[lang="en"]');
34+
await page.click("#language-continue");
35+
await waitForNavigation;
36+
}
37+
38+
// "Account creation" page
39+
await page.fill("#weblog_title", "My website");
40+
await page.fill("#user_login", ADMIN_LOGIN);
41+
if (WP53 || WP54 || WP55 || WP56 || WP57 || WP58) {
42+
await page.fill("#pass1", ADMIN_PASSWORD);
43+
} else {
44+
await page.fill("#pass1-text", ADMIN_PASSWORD);
45+
}
46+
await page.fill("#admin_email", "admin@admin.admin");
47+
await page.click("#submit");
48+
await waitForNavigation;
49+
50+
// "Success" page
51+
52+
await expect(page).toHaveText("h1", "Success!");
53+
await page.click(".wp-core-ui > .step > .button");
54+
await waitForNavigation;
55+
});
56+
});

0 commit comments

Comments
 (0)