Skip to content

Commit b708c31

Browse files
authored
Merge pull request #3314 from Strategy11/reduce_formidable_api_calls_when_running_cypress
Reduce formidable API calls when running cypress
2 parents 0f39e51 + 0ff5ca0 commit b708c31

8 files changed

Lines changed: 2376 additions & 81 deletions

File tree

.github/workflows/cypress.yml

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -66,36 +66,52 @@ jobs:
6666
if: steps.cache-npm.outputs.cache-hit != 'true'
6767
run: npm ci --legacy-peer-deps --include=dev
6868

69-
# Serve the form-templates API from a fixture instead of calling
70-
# formidableforms.com on every run. The cache key is the UTC date, so
71-
# the fixture is refreshed at most once a day and all four shards share
72-
# the one copy - without this, each shard fetches it separately. If the
73-
# fetch fails the committed fixture is used, so the suite still runs
74-
# when the API is unreachable.
69+
# Serve the formidableforms.com APIs from fixtures instead of calling
70+
# them on every run. The cache key is the UTC date, so the fixtures are
71+
# refreshed at most once a day and all four shards share the one copy -
72+
# without this, each shard fetches them separately. If a fetch fails the
73+
# committed fixture is used, so the suite still runs when the API is
74+
# unreachable.
7575
- name: Get current date
7676
id: date
7777
run: echo "date=$( date -u +%Y-%m-%d )" >> "$GITHUB_OUTPUT"
7878

79-
- name: Cache form templates API response
80-
id: cache-templates
79+
- name: Cache API responses
80+
id: cache-api
8181
uses: actions/cache@v4
8282
with:
83-
path: tests/mu-plugins/form-templates-api.json
84-
key: form-templates-${{ steps.date.outputs.date }}
85-
86-
- name: Refresh form templates fixture
87-
if: steps.cache-templates.outputs.cache-hit != 'true'
83+
path: |
84+
tests/mu-plugins/form-templates-api.json
85+
tests/mu-plugins/style-templates-api.json
86+
tests/mu-plugins/view-templates-api.json
87+
tests/mu-plugins/addons-api.json
88+
key: frm-api-fixtures-${{ steps.date.outputs.date }}
89+
90+
- name: Refresh API fixtures
91+
if: steps.cache-api.outputs.cache-hit != 'true'
8892
run: |
89-
# Write to a temp file first so a partial or failed response never
90-
# clobbers the committed fallback.
91-
if curl -fsS --max-time 40 -A 'formidable-e2e' \
92-
'https://formidableforms.com/wp-json/form-templates/v1/list?l=RlJFRVRFTVBMQVRFUyEhIQ%3D%3D' \
93-
-o /tmp/form-templates-api.json && [ -s /tmp/form-templates-api.json ]; then
94-
mv /tmp/form-templates-api.json tests/mu-plugins/form-templates-api.json
95-
echo "Refreshed the form templates fixture from the API."
96-
else
97-
echo "Could not reach the templates API; using the committed fixture."
98-
fi
93+
# Each line is "<fixture> <url>". The URLs match what the plugin
94+
# requests on an unlicensed install, which is what wp-env is - so
95+
# the add-ons list comes from the Cloudflare worker, and only the
96+
# form templates endpoint takes the free-templates license.
97+
while read -r fixture url; do
98+
[ -n "$fixture" ] || continue
99+
100+
# Write to a temp file first so a partial or failed response never
101+
# clobbers the committed fallback.
102+
if curl -fsS --max-time 40 -A 'formidable-e2e' "$url" -o "/tmp/$fixture" \
103+
&& [ -s "/tmp/$fixture" ]; then
104+
mv "/tmp/$fixture" "tests/mu-plugins/$fixture"
105+
echo "Refreshed $fixture from the API."
106+
else
107+
echo "Could not reach $url; using the committed $fixture."
108+
fi
109+
done <<'FIXTURES'
110+
form-templates-api.json https://formidableforms.com/wp-json/form-templates/v1/list?l=RlJFRVRFTVBMQVRFUyEhIQ%3D%3D
111+
style-templates-api.json https://formidableforms.com/wp-json/style-templates/v1/list
112+
view-templates-api.json https://formidableforms.com/wp-json/view-templates/v1/list
113+
addons-api.json https://plapi.formidableforms.com/list/
114+
FIXTURES
99115
100116
- name: Set up WP environment
101117
run: npm run env start

_typos.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ check-file = false
1818
extend-glob = ["denylist/*.txt"]
1919
check-file = false
2020

21+
[type.addons-api]
22+
extend-glob = ["*addons-api.json"]
23+
check-file = false
24+
2125
[default]
2226
extend-ignore-re = [
2327
"/mis'",

tests/mu-plugins/addons-api.json

Lines changed: 2255 additions & 0 deletions
Large diffs are not rendered by default.

tests/mu-plugins/form-templates-api.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

tests/mu-plugins/frm-stub-api.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<?php
2+
// Serves the formidableforms.com APIs from local fixtures in the e2e test
3+
// environment, so the suite never depends on a live call: form templates,
4+
// style templates, application (view) templates and the add-ons list.
5+
//
6+
// Two things go wrong without this. A fresh wp-env has an empty cache, and
7+
// FrmFormApi::get_api_info() returns an empty array outright when another
8+
// request for the same data is already in flight (the is_running() guard)
9+
// rather than waiting for it - so the list renders empty and assertions like
10+
// [frm-search-text="user registration"] never match. The `Get Instant Access`
11+
// signup flow then calls reset_cached(), clearing the cache mid-run and
12+
// re-opening the same window for whatever runs next.
13+
//
14+
// Sharding sharpened this: every shard is its own wp-env with its own cold
15+
// cache, so one live fetch per run became one per shard.
16+
//
17+
// Filtering pre_http_request rather than seeding the cache options keeps this
18+
// independent of FrmFormApi's cache internals - the option keys are derived
19+
// from the license, and reset_cached() deletes them - and it is the standard
20+
// WordPress way to stub an outbound request.
21+
//
22+
// The fixtures sit beside this file on purpose. The whole mu-plugins
23+
// directory is mapped to a known path inside the container, whereas the
24+
// plugin directory is named `formidable` locally and `formidable-forms` in
25+
// CI, so a path built from the plugin folder would break in one of the two.
26+
// WordPress only auto-loads .php from the mu-plugins root, so the .json
27+
// siblings are inert.
28+
add_filter(
29+
'pre_http_request',
30+
function ( $preempt, $args, $url ) {
31+
// URL fragment => fixture file. The add-ons list has two endpoints:
32+
// unlicensed installs (which is what wp-env is) hit the Cloudflare
33+
// worker, licensed ones hit s11edd.
34+
$fixtures = array(
35+
'/wp-json/form-templates/v1/list' => 'form-templates-api.json',
36+
'/wp-json/style-templates/v1/list' => 'style-templates-api.json',
37+
'/wp-json/view-templates/v1/list' => 'view-templates-api.json',
38+
'plapi.formidableforms.com/list/' => 'addons-api.json',
39+
'/wp-json/s11edd/v1/updates/' => 'addons-api.json',
40+
);
41+
42+
$fixture = '';
43+
44+
foreach ( $fixtures as $fragment => $file ) {
45+
if ( false !== strpos( $url, $fragment ) ) {
46+
$fixture = __DIR__ . '/' . $file;
47+
break;
48+
}
49+
}
50+
51+
if ( ! $fixture ) {
52+
return $preempt;
53+
}
54+
55+
if ( ! is_readable( $fixture ) ) {
56+
// Let the real request through rather than failing the run with an
57+
// empty list, which is the confusing symptom this exists to
58+
// prevent.
59+
return $preempt;
60+
}
61+
62+
return array(
63+
'headers' => array(),
64+
'body' => file_get_contents( $fixture ),
65+
'response' => array(
66+
'code' => 200,
67+
'message' => 'OK',
68+
),
69+
'cookies' => array(),
70+
'filename' => null,
71+
);
72+
},
73+
10,
74+
3
75+
);

tests/mu-plugins/frm-stub-template-api.php

Lines changed: 0 additions & 57 deletions
This file was deleted.

0 commit comments

Comments
 (0)