Skip to content

Commit 1ed22d0

Browse files
Add support for maxSupportedVersion (#1912)
* Add support for maxSupportedVersion * Lint fix * Don't disable top level features * Remove unit test * Fix test * Fix up integration tests * Add test cases * Add more unit test cases
1 parent fd430a6 commit 1ed22d0

File tree

10 files changed

+543
-2
lines changed

10 files changed

+543
-2
lines changed

injected/docs/test-pages-guide.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,12 @@ It's unadvisable to add custom state for tests directly in `.spec.js` files as i
196196

197197
### 2. Platform Configuration
198198

199-
The `Platform` parameter can be passed to test functions to simulate different platform environments. This is demonstrated in the min-supported-version tests in [pages.spec.js](../integration-test/pages.spec.js):
199+
The `Platform` parameter can be passed to test functions to simulate different platform environments. This is demonstrated in the version tests in [pages.spec.js](../integration-test/pages.spec.js):
200200

201201
- `minSupportedVersion (string)`: Uses `{ version: '1.5.0' }`
202202
- `minSupportedVersion (int)`: Uses `{ version: 99 }`
203+
- `maxSupportedVersion (string)`: Uses `{ version: '1.5.0' }`
204+
- `maxSupportedVersion (int)`: Uses `{ version: 99 }`
203205

204206
This is needed when testing features that have platform-specific behavior or version requirements. The platform object allows testing how features behave under different version constraints without modifying the core test infrastructure.
205207

injected/integration-test/pages.spec.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
*
1313
* 2. PLATFORM CONFIGURATION:
1414
* The 'Platform' parameter can be passed as an argument to testPage() to simulate different
15-
* platform environments. This is demonstrated in the min-supported-version tests:
15+
* platform environments. This is demonstrated in the version tests:
1616
* - minSupportedVersion (string): Uses { version: '1.5.0' }
1717
* - minSupportedVersion (int): Uses { version: 99 }
18+
* - maxSupportedVersion (string): Uses { version: '1.5.0' }
19+
* - maxSupportedVersion (int): Uses { version: 99 }
1820
*
1921
* This is needed when testing features that have platform-specific behavior or version
2022
* requirements. The platform object allows testing how features behave under different
@@ -155,4 +157,24 @@ test.describe('Test integration pages', () => {
155157
{ version: 99 },
156158
);
157159
});
160+
161+
test('maxSupportedVersion (string)', async ({ page }, testInfo) => {
162+
await testPage(
163+
page,
164+
testInfo,
165+
'/infra/pages/max-supported-version-string.html',
166+
'./integration-test/test-pages/infra/config/max-supported-version-string.json',
167+
{ version: '1.5.0' },
168+
);
169+
});
170+
171+
test('maxSupportedVersion (int)', async ({ page }, testInfo) => {
172+
await testPage(
173+
page,
174+
testInfo,
175+
'/infra/pages/max-supported-version-int.html',
176+
'./integration-test/test-pages/infra/config/max-supported-version-int.json',
177+
{ version: 99 },
178+
);
179+
});
158180
});
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
{
2+
"readme": "Test maxSupportedVersion (int) with apiManipulation and conditionalPatching.",
3+
"version": 1,
4+
"features": {
5+
"apiManipulation": {
6+
"state": "enabled",
7+
"exceptions": [],
8+
"settings": {
9+
"apiChanges": {
10+
},
11+
"conditionalChanges": [
12+
{
13+
"condition": {
14+
"maxSupportedVersion": 100
15+
},
16+
"patchSettings": [
17+
{
18+
"op": "add",
19+
"path": "/apiChanges/versionIntTestAbove",
20+
"value": {
21+
"type": "descriptor",
22+
"getterValue": {
23+
"type": "boolean",
24+
"value": true
25+
},
26+
"define": true
27+
}
28+
}
29+
]
30+
},
31+
{
32+
"condition": {
33+
"maxSupportedVersion": 99
34+
},
35+
"patchSettings": [
36+
{
37+
"op": "add",
38+
"path": "/apiChanges/versionIntTestSame",
39+
"value": {
40+
"type": "descriptor",
41+
"getterValue": {
42+
"type": "boolean",
43+
"value": true
44+
},
45+
"define": true
46+
}
47+
}
48+
]
49+
},
50+
{
51+
"condition": {
52+
"maxSupportedVersion": 98
53+
},
54+
"patchSettings": [
55+
{
56+
"op": "add",
57+
"path": "/apiChanges/versionIntTestBelow",
58+
"value": {
59+
"type": "descriptor",
60+
"getterValue": {
61+
"type": "boolean",
62+
"value": true
63+
},
64+
"define": true
65+
}
66+
}
67+
]
68+
}
69+
]
70+
}
71+
}
72+
},
73+
"unprotectedTemporary": []
74+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
{
2+
"readme": "Test maxSupportedVersion (string) with apiManipulation and conditionalPatching.",
3+
"version": 1,
4+
"features": {
5+
"apiManipulation": {
6+
"state": "enabled",
7+
"exceptions": [],
8+
"settings": {
9+
"apiChanges": {},
10+
"conditionalChanges": [
11+
{
12+
"condition": {
13+
"maxSupportedVersion": "2.0.0"
14+
},
15+
"patchSettings": [
16+
{
17+
"op": "add",
18+
"path": "/apiChanges/versionStringTestAbove",
19+
"value": {
20+
"type": "descriptor",
21+
"getterValue": {
22+
"type": "boolean",
23+
"value": true
24+
},
25+
"define": true
26+
}
27+
}
28+
]
29+
},
30+
{
31+
"condition": {
32+
"maxSupportedVersion": "1.5.0"
33+
},
34+
"patchSettings": [
35+
{
36+
"op": "add",
37+
"path": "/apiChanges/versionStringTestSame",
38+
"value": {
39+
"type": "descriptor",
40+
"getterValue": {
41+
"type": "boolean",
42+
"value": true
43+
},
44+
"define": true
45+
}
46+
}
47+
]
48+
},
49+
{
50+
"condition": {
51+
"maxSupportedVersion": "1.0.0"
52+
},
53+
"patchSettings": [
54+
{
55+
"op": "add",
56+
"path": "/apiChanges/versionStringTestBelow",
57+
"value": {
58+
"type": "descriptor",
59+
"getterValue": {
60+
"type": "boolean",
61+
"value": true
62+
},
63+
"define": true
64+
}
65+
}
66+
]
67+
}
68+
]
69+
}
70+
}
71+
},
72+
"unprotectedTemporary": []
73+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Max Supported Version (int)</title>
6+
<link rel="stylesheet" href="../../shared/style.css" />
7+
</head>
8+
<body>
9+
<script src="../../shared/utils.js"></script>
10+
<p><a href="../index.html">[Infra]</a></p>
11+
<p>This page verifies maxSupportedVersion (int) conditional patching. Load with 99 as the version number.</p>
12+
<script>
13+
test('maxSupportedVersion (int)', async () => {
14+
const results = [];
15+
results.push({
16+
name: 'versionIntTestAbove should always be true',
17+
result: window.versionIntTestAbove,
18+
expected: true,
19+
});
20+
results.push({
21+
name: 'versionIntTestSame should always be true',
22+
result: window.versionIntTestSame,
23+
expected: true,
24+
});
25+
results.push({
26+
name: 'versionIntTestBelow should always be false/undefined',
27+
result: window.versionIntTestBelow,
28+
expected: undefined,
29+
});
30+
return results;
31+
});
32+
renderResults();
33+
</script>
34+
</body>
35+
</html>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Max Supported Version (string)</title>
6+
<link rel="stylesheet" href="../../shared/style.css" />
7+
</head>
8+
<body>
9+
<script src="../../shared/utils.js"></script>
10+
<p><a href="../index.html">[Infra]</a></p>
11+
<p>This page verifies maxSupportedVersion (string) conditional patching. Load with 1.5.0 as the version number.</p>
12+
<script>
13+
test('maxSupportedVersion (string)', async () => {
14+
const results = [];
15+
results.push({
16+
name: 'versionStringTestAbove should always be true',
17+
result: window.versionStringTestAbove,
18+
expected: true,
19+
});
20+
results.push({
21+
name: 'versionStringTestSame should always be true',
22+
result: window.versionStringTestSame,
23+
expected: true,
24+
});
25+
results.push({
26+
name: 'versionStringTestBelow should always be false/undefined',
27+
result: window.versionStringTestBelow,
28+
expected: undefined,
29+
});
30+
return results;
31+
});
32+
renderResults();
33+
</script>
34+
</body>
35+
</html>

injected/src/config-feature.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
parseFeatureSettings,
77
computeLimitedSiteObject,
88
isSupportedVersion,
9+
isMaxSupportedVersion,
910
} from './utils.js';
1011
import { URLPattern } from 'urlpattern-polyfill';
1112

@@ -124,6 +125,7 @@ export default class ConfigFeature {
124125
* @property {string[] | string} [domain]
125126
* @property {object} [urlPattern]
126127
* @property {object} [minSupportedVersion]
128+
* @property {object} [maxSupportedVersion]
127129
* @property {object} [experiment]
128130
* @property {string} [experiment.experimentName]
129131
* @property {string} [experiment.cohort]
@@ -160,6 +162,7 @@ export default class ConfigFeature {
160162
urlPattern: this._matchUrlPatternConditional,
161163
experiment: this._matchExperimentConditional,
162164
minSupportedVersion: this._matchMinSupportedVersion,
165+
maxSupportedVersion: this._matchMaxSupportedVersion,
163166
injectName: this._matchInjectNameConditional,
164167
};
165168

@@ -294,6 +297,16 @@ export default class ConfigFeature {
294297
return isSupportedVersion(conditionBlock.minSupportedVersion, this.#args?.platform?.version);
295298
}
296299

300+
/**
301+
* Takes a condition block and returns true if the platform version satisfies the `maxSupportedFeature`
302+
* @param {ConditionBlock} conditionBlock
303+
* @returns {boolean}
304+
*/
305+
_matchMaxSupportedVersion(conditionBlock) {
306+
if (!conditionBlock.maxSupportedVersion) return false;
307+
return isMaxSupportedVersion(conditionBlock.maxSupportedVersion, this.#args?.platform?.version);
308+
}
309+
297310
/**
298311
* Return the settings object for a feature
299312
* @param {string} [featureName] - The name of the feature to get the settings for; defaults to the name of the feature

injected/src/utils.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,24 @@ export function isSupportedVersion(minSupportedVersion, currentVersion) {
651651
return false;
652652
}
653653

654+
/**
655+
* @param {string | number | undefined} maxSupportedVersion
656+
* @param {string | number | undefined} currentVersion
657+
* @returns {boolean}
658+
*/
659+
export function isMaxSupportedVersion(maxSupportedVersion, currentVersion) {
660+
if (typeof currentVersion === 'string' && typeof maxSupportedVersion === 'string') {
661+
if (satisfiesMinVersion(currentVersion, maxSupportedVersion)) {
662+
return true;
663+
}
664+
} else if (typeof currentVersion === 'number' && typeof maxSupportedVersion === 'number') {
665+
if (maxSupportedVersion >= currentVersion) {
666+
return true;
667+
}
668+
}
669+
return false;
670+
}
671+
654672
/**
655673
* @typedef RemoteConfig
656674
* @property {Record<string, { state: string; settings: any; exceptions: { domain: string }[], minSupportedVersion?: string|number }>} features

0 commit comments

Comments
 (0)