Skip to content
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
25 changes: 17 additions & 8 deletions docs/e2e-testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The setup script (`scripts/setup.php`) creates these WordPress pages:

## What is covered

The suite currently contains 78 tests across 11 spec files (one skipped pending JOIN-158).
The join form specs (the table below) are listed with their test counts. The settings page specs in `tests/settings/` are covered in "Settings page coverage" below. Run `npx playwright test --list` in `packages/join-e2e` for the current total.

| Spec file | Area | Tests | What it verifies |
|-----------|------|------:|------------------|
Expand All @@ -69,6 +69,20 @@ The suite currently contains 78 tests across 11 spec files (one skipped pending
- **Validation** for required fields and email format is exercised.


## Settings page coverage

`tests/settings/` tests the settings on WP Admin > Join: each is saved (read back through `Settings::get`), has its effect, and still works when loaded as Carbon Fields stored it. The readme ("Settings page regression tests") explains how these tests are built. Known problems are `test.fixme` tests linked to Linear issues.

| Tab | Spec | Covered |
|---|---|---|
| Features | `features.spec.ts`, `features-integrations.spec.ts` | Every setting. Integration switches: refused without credentials, saved with them, payment-step and form effects. Use Stripe sets global plans up in Stripe on save (fake API). Known problem: JOIN-161 (a rejected Stripe key crashes the save). |
| Membership Plans | | Not yet |
| Theme | | Not yet |
| Copy | | Not yet |
| Integrations | | Not yet. What Mailchimp, Action Network and Zetkin receive on a join will be covered here. |
| Logging | | Not yet |
| Debug | | Not yet |

## What is not covered

### Payment UI rendering
Expand All @@ -89,16 +103,11 @@ No tests. When `IS_UPDATE_FLOW=true`, personal details are skipped and the form

### Payment method selection page

The `payment-method` step (choosing between Direct Debit and Card when multiple providers are enabled) is never exercised. Tests either mock everything or bypass payment.
Now partly covered by the settings tests: `tests/settings/features-integrations.spec.ts` checks the step appears, with both methods, when GoCardless and Chargebee are both on. Choosing a method and going on from there is still untested.

### Optional data collection flags

The following flags control whether additional fields appear on the details page, but none are tested:

- `COLLECT_DATE_OF_BIRTH`
- `COLLECT_COUNTY`
- `COLLECT_HEAR_ABOUT_US`
- `COLLECT_PHONE_AND_EMAIL_CONTACT_CONSENT`
Now covered by the settings tests (`tests/settings/features.spec.ts`).

### Custom fields

Expand Down
49 changes: 47 additions & 2 deletions packages/join-e2e/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ x-wordpress-volumes: &wordpress-volumes
- wordpress:/var/www/html
- ../join-block:/var/www/html/wp-content/plugins/join-block
- ./scripts:/var/www/html/wp-content/e2e-scripts
# Trust the fake API's test CA: PHP's curl and streams, WordPress's own
# HTTP API (via a must-use plugin) and the Stripe and Chargebee SDKs each have their own CA
# setting. Nothing may be mounted over WordPress's core files: the image
# copies them into the volume on first start and fails if one is in the way.
- ./fake-api/certs/ca.crt:/usr/local/share/e2e-fake-api-ca.crt:ro
- ./fake-api/php-ca.ini:/usr/local/etc/php/conf.d/zz-e2e-fake-api-ca.ini:ro
- ./fake-api/e2e-fake-api-ca.php:/var/www/html/wp-content/mu-plugins/e2e-fake-api-ca.php:ro
- ./fake-api/certs/ca.crt:/var/www/html/wp-content/plugins/join-block/vendor/stripe/stripe-php/data/ca-certificates.crt:ro
Comment thread
conatus marked this conversation as resolved.
Resolved
- ./fake-api/certs/ca.crt:/var/www/html/wp-content/plugins/join-block/vendor/chargebee/chargebee-php/lib/ssl/ca-certs.crt:ro

x-wordpress-environment: &wordpress-environment
WORDPRESS_DB_HOST: db
Expand All @@ -17,6 +26,38 @@ x-wordpress-environment: &wordpress-environment
WORDPRESS_DB_NAME: wordpress

services:
# Stands in for every third-party API the plugin calls. Inside this network
# the aliases below resolve here instead of to the real services. Tests talk
# to its control API on localhost:8890 (tests/settings/fake-api.ts).
fake-api:
image: node:22.23.4-alpine
command: ['node', '/app/server.js']
volumes:
- ./fake-api:/app:ro
ports:
- '8890:8080'
healthcheck:
test: ['CMD', 'wget', '-qO-', 'http://localhost:8080/health']
interval: 2s
timeout: 5s
retries: 30
networks:
default:
# Keep in step with fake-api/certs/san.cnf.
aliases:
- api.stripe.com
- actionnetwork.org
- api.zetk.in
- api.dev.zetkin.org
- us1.api.mailchimp.com
- e2e.eu.auth0.com
- api.gocardless.com
- api-sandbox.gocardless.com
- e2e.chargebee.com
- api.postcodes.io
- api.getaddress.io
- api.ideal-postcodes.co.uk

db:
image: mariadb:11.4
environment:
Expand All @@ -35,6 +76,8 @@ services:
depends_on:
db:
condition: service_healthy
fake-api:
condition: service_healthy
ports:
- '8889:80'
volumes: *wordpress-volumes
Expand All @@ -45,10 +88,12 @@ services:
define('WP_DEBUG_LOG', true);
define('SCRIPT_DEBUG', true);

# One-off WP-CLI runs: docker compose run --rm cli wp <command>
# WP-CLI, kept running so commands start quickly:
# docker compose exec cli wp <command> (or scripts/env.sh wp <command>)
cli:
image: wordpress:cli-2.12.0-php8.2
profiles: [cli]
command: ['sleep', 'infinity']
init: true
user: '33:33'
depends_on:
- wordpress
Expand Down
20 changes: 20 additions & 0 deletions packages/join-e2e/fake-api/certs/ca.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDPzCCAiegAwIBAgIUL1NIuEmpA0RWqABA149MgtVN6S8wDQYJKoZIhvcNAQEL
BQAwLjEsMCoGA1UEAwwjSm9pbiBFMkUgdGVzdCBDQSAobm90IGZvciByZWFsIHVz
ZSkwIBcNMjYxMDIzMTc1NDA2WhgPMjEyNjA5MjkxNzU0MDZaMC4xLDAqBgNVBAMM
I0pvaW4gRTJFIHRlc3QgQ0EgKG5vdCBmb3IgcmVhbCB1c2UpMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5MZLGxuo1wv3q/KZlHPYs1msn5HP9/MS93px
sfubWlrPxW0CWIxTMtv98kyeNggsQ6pqbFdpLSpDrMI2L4+OTYwTwV+LrzV4neSm
GXHVAqB93QLaHLQwdWdjiGJ8vaX069c8LzNvnZb8KVf7MtLWX2MsRNYJtXCCtxuT
wV3RZDQs4TNOqGikoyRg/JNCxkgBPHNSm7ptCj3rj2rbQGDM7nu1skBzH3L6xKiA
QGiYb+vNDWcdK4I38cA8BbQdS+DXvHIf+Y6Qlq8h6esI7a8pnbhm60RIHNvsEdFq
qPFPowydKT8RyjABZHnajyYXyv3PGeGjXC/hRRTsaJg54GUxiwIDAQABo1MwUTAd
BgNVHQ4EFgQU6xlodRtSMB1hTbE+cfkyMBWT2QUwHwYDVR0jBBgwFoAU6xlodRtS
MB1hTbE+cfkyMBWT2QUwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
AQEAGjcNh/YqYwRw5w+ilPybR9DHl0OG7/k7VXrGRqml0QvbDD1h4jR4Hqz2AwXr
HFt6LdnXOvlVk+u6t6FvNflFu059sNeJx7b5FRBoTvrjNZfFehoKD5NkuamGGWdk
XIEeG0NIBaYF4DYu9qK1jKL1DcpM4lFOfy55pcNEqyBEyULmpJVYhBAsddb4gtuU
oZHM/rZdp/k463E53SHUPMD3arh3CDcq+JLSr3uDs7nRex7HfY0U7DFd4DlcuuH/
oWnAGLOcb17zzahyAdsmCetiGuzAp7SU7p6DBLnT3Yr5i/CjhWKoKCDqAIaybIgw
dIdD1NBq1DZNpTYgPl/dvaa5fg==
-----END CERTIFICATE-----
17 changes: 17 additions & 0 deletions packages/join-e2e/fake-api/certs/generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
# Regenerates the fake API's test CA and server certificate.
#
# Only needed when adding a hostname: add it to san.cnf, run this, and add the
# same hostname to the fake-api network aliases in ../../docker-compose.yml.
# The CA key is deleted afterwards, so these files can't sign anything else.
# Test-only: trusted only inside the E2E Docker network.
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"

openssl req -x509 -newkey rsa:2048 -nodes -keyout ca.key -out ca.crt -days 36500 \
-subj "/CN=Join E2E test CA (not for real use)"
openssl req -newkey rsa:2048 -nodes -keyout server.key -out server.csr \
-subj "/CN=fake-api" -config san.cnf
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out server.crt -days 36500 -extfile san.cnf -extensions ext
rm -f server.csr ca.srl ca.key
22 changes: 22 additions & 0 deletions packages/join-e2e/fake-api/certs/san.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[req]
distinguished_name = dn
[dn]
[ext]
subjectAltName = @alt
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
[alt]
DNS.1 = api.stripe.com
DNS.2 = actionnetwork.org
DNS.3 = api.zetk.in
DNS.4 = api.dev.zetkin.org
DNS.5 = us1.api.mailchimp.com
DNS.6 = e2e.eu.auth0.com
DNS.7 = api.gocardless.com
DNS.8 = api-sandbox.gocardless.com
DNS.9 = e2e.chargebee.com
DNS.10 = api.postcodes.io
DNS.11 = api.getaddress.io
DNS.12 = api.ideal-postcodes.co.uk
DNS.13 = fake-api
26 changes: 26 additions & 0 deletions packages/join-e2e/fake-api/certs/server.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIETTCCAzWgAwIBAgIUcBvmd6AYMCx4hAsRuJYvExc18BUwDQYJKoZIhvcNAQEL
BQAwLjEsMCoGA1UEAwwjSm9pbiBFMkUgdGVzdCBDQSAobm90IGZvciByZWFsIHVz
ZSkwIBcNMjYxMDIzMTc1NDA2WhgPMjEyNjA5MjkxNzU0MDZaMBMxETAPBgNVBAMM
CGZha2UtYXBpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAreVk2RGX
irbBcE/J6YDanGGDwf404Lh9ni6Akw2zEANeVLxqvKiyi5l8wK1q+ah3J2jqo/LU
KrD65ZuhscZW5V+t9w/KqTkOE/4O76s3wJB8Y4sQcUuW4XtV/Wd028gZORu/DMp9
A1lK7ysqtuu/6K1D1/8evI6LsMNjrQshh3FXcJiUhcrfgrmM8lWVQE652KJIeRTi
iKQm9Xiwo8+Pj632bbmTfvCA6yLHrhOaLS9OB14XSjzzXSoxqLTLP9UTA6GvMLGi
FIlzl/ch8ZlnI9t/37JiEhBY2QzaEymKl2yLNcgG2YCQx71T8xAuuwu7Yy2E/A4k
C2o/LQcp2iJPowIDAQABo4IBejCCAXYwggEFBgNVHREEgf0wgfqCDmFwaS5zdHJp
cGUuY29tghFhY3Rpb25uZXR3b3JrLm9yZ4ILYXBpLnpldGsuaW6CEmFwaS5kZXYu
emV0a2luLm9yZ4IVdXMxLmFwaS5tYWlsY2hpbXAuY29tghBlMmUuZXUuYXV0aDAu
Y29tghJhcGkuZ29jYXJkbGVzcy5jb22CGmFwaS1zYW5kYm94LmdvY2FyZGxlc3Mu
Y29tghFlMmUuY2hhcmdlYmVlLmNvbYIQYXBpLnBvc3Rjb2Rlcy5pb4IRYXBpLmdl
dGFkZHJlc3MuaW+CGWFwaS5pZGVhbC1wb3N0Y29kZXMuY28udWuCCGZha2UtYXBp
MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB0G
A1UdDgQWBBRmOT+xWfG1qKOcrTEPx4PG5jjkwzAfBgNVHSMEGDAWgBTrGWh1G1Iw
HWFNsT5x+TIwFZPZBTANBgkqhkiG9w0BAQsFAAOCAQEAM0haZ0adhRNvYMHkNm3B
IH614SRIsOlFt2SUYi33DYIy0Im0Mk3BGozgx/zY2/8LUu6mon47aKjJJpP922ew
MzzswMoAM7FnKiN0DV9asfsmCH8OeePjFHde4VWU6elTQ2Tb5Lmg0Tqafaew4sB6
xFe4usEl3AIaYtoZ6MULdsdNOXF42M4xlNp2l7uMcJT1IYQODxByJ1vd40k0q1Uz
uZx4qiRsF7HqV4q2/emjUu/67R871J5uM8aKxvRS2YLjuP2JruTOnjSQbJf1js60
PcGGWPREVvveXSLJiwD9DpXHjApKTZjMj7lk5fcGYe+Ka0CDxmhHhewiGiblRjcJ
YA==
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions packages/join-e2e/fake-api/certs/server.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCt5WTZEZeKtsFw
T8npgNqcYYPB/jTguH2eLoCTDbMQA15UvGq8qLKLmXzArWr5qHcnaOqj8tQqsPrl
m6GxxlblX633D8qpOQ4T/g7vqzfAkHxjixBxS5bhe1X9Z3TbyBk5G78Myn0DWUrv
Kyq267/orUPX/x68jouww2OtCyGHcVdwmJSFyt+CuYzyVZVATrnYokh5FOKIpCb1
eLCjz4+PrfZtuZN+8IDrIseuE5otL04HXhdKPPNdKjGotMs/1RMDoa8wsaIUiXOX
9yHxmWcj23/fsmISEFjZDNoTKYqXbIs1yAbZgJDHvVPzEC67C7tjLYT8DiQLaj8t
BynaIk+jAgMBAAECggEASIz4vsGiroph+SgozuVmD7F1haW3zPvb2PeAyBmCmA83
t3WmuJBPcYO3czHG/GMnV0dkAcPJdghBnTMJyoA799Wr4HRzspdtwrSP6blO+OWv
J964nPQS/n71GNSlgh6hO1zSoBUJBDEoXNFvMEL6XaqQMBkt6zAzoqtaNjN7KSTV
qfPyySMcnRJNHZGsSz8i4dekGZDUSwUV7u7kjmp2vlL5vo6T6tlY2JqHYRcm/qdl
GqI6JuH2fFmaLDlP2eyUu3Judqoq0PrwMgcEVz0Rtg7szEUcHrZg6O7YVVWVCyuS
+nC9yPtmbs1oyiXXQsKdItZiy5LwdzuGKXXrXw7WHQKBgQDe7ioZzHhQS39hg87o
YJQJdtlyTemgFywjtItWeX2Arq2n1nj4BioxJlvtEMXuFntYqUgJSOOB2m0n2k2v
duT7EUrON6+xcoHaGDaoT9qZHAzEr5OQb+dJmTUlWWDuU5xGGeBwFmIboO/2vNeS
E9/tqo9L2VU5P9WV2YPHH+pxxQKBgQDHsSQeVPSFzfLw6UvwiMrco8SdU15TOjFF
7hUzNESq/qo3WPuNiAiNDE8frWqVXzMRpbeYpujAFZd+XUONjI29z8CBTbcrZYjp
PKW1VxLn5gL1MCsGModdRnupzp8DVPvRuQhG1wgfqKLtP0wMvhLPkOpO24V5LokL
FRwnaP/aRwKBgQCIdHm6ruiaJYxD8T1OCgezP1dcWwp83pI7DMEZXmYOxV0wVdxX
3NYonZU5J8IvuP0pSPz6Ce6QRlX4Rey1UW5Zq70BOx7E3BVVnOqf3bktbPj3z4zg
pU6KQ0g/o1TsrKsEUcSKd3j39mvLuM2u8ZFo1bS+tbovv74J6kl6MjP8DQKBgH1B
q7oq58YWTNC4RZ327+g+AVH9vSjPU6DdmgaoPnpTi0l0UzWPom12zxq7mCNht5LW
M7dY2p3B7Wih74GWLEJnUgTJTp+17I8AL6DzoTQ8npZVRGd6wlXLpD37ENryL5J5
Uau9rabODIRsM7O6deokqBQWtj4w5l1BPIur3PB5AoGAYSXUMSGROOwFsJBWMyV0
Zkki7WTEqtkWD2WA4sggmxQw9jtbuiud558v6BT8RwbolUWICeNlfae0sxNNhMOV
9vQTeemYjZIDTaK8iJ7RdEqoLl27SjhmPsnXdn4+eunBEBUahs2U3QtAJ0SxLSlU
W8tmx1Coy7OXOWnP/jc1PoA=
-----END PRIVATE KEY-----
14 changes: 14 additions & 0 deletions packages/join-e2e/fake-api/e2e-fake-api-ca.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
/**
* Plugin Name: E2E fake API CA
* Description: E2E only. Makes WordPress's HTTP API trust the fake API's test CA (see fake-api/server.js).
*
* Mounted into wp-content/mu-plugins by the E2E docker-compose.yml. Uses the
* http_request_args filter rather than replacing WordPress's own CA bundle,
* which would stop the WordPress image installing itself on a fresh volume.
*/

add_filter('http_request_args', function ($args) {
$args['sslcertificates'] = '/usr/local/share/e2e-fake-api-ca.crt';
return $args;
});
3 changes: 3 additions & 0 deletions packages/join-e2e/fake-api/php-ca.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
; E2E only: trust the fake API's test CA (see fake-api/server.js).
curl.cainfo = /usr/local/share/e2e-fake-api-ca.crt
openssl.cafile = /usr/local/share/e2e-fake-api-ca.crt
Loading
Loading