Skip to content

Commit

Permalink
Merge pull request #600 from notriddle/notriddle/block-network-request
Browse files Browse the repository at this point in the history
Add block-network-request command
  • Loading branch information
GuillaumeGomez committed Apr 4, 2024
2 parents 09259bf + 0e79e04 commit 9fdd000
Show file tree
Hide file tree
Showing 20 changed files with 178 additions and 0 deletions.
21 changes: 21 additions & 0 deletions goml-script.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ Here's the command list:
* [`assert-variable-false`](#assert-variable-false)
* [`assert-window-property`](#assert-window-property)
* [`assert-window-property-false`](#assert-window-property-false)
* [`block-network-request`](#block-network-request)
* [`call-function`](#call-function)
* [`click`](#click)
* [`click-with-offset`](#click-with-offset)
Expand Down Expand Up @@ -861,6 +862,26 @@ assert-window-property-false: (
)
```

#### block-network-request

**block-network-request** prevents a URL that matches a glob from loading. Asterisks `*` are wildcards:

```
// Prevent search index from loading
block-network-request: "*/search-index.js"
```

By default, a failed network request will cause the test to fail.
Use the [`fail-on-request-error`](#fail-on-request-error) to change this.

* If you use `block-network-request` with `fail-on-request-error` turned on,
which is the default, the test case will fail if the page makes a blocked
network request. It acts as an assertion that the request is not made.

* To test the page's functionality after the request fails, turn it off:

fail-on-request-error: false

#### call-function

**call-function** command allows you to call a function defined with `define-function`. It expects a tuple containing the name of the function to call and its arguments (if any). Example:
Expand Down
1 change: 1 addition & 0 deletions src/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const ORDERS = {
'assert-variable-false': commands.parseAssertVariableFalse,
'assert-window-property': commands.parseAssertWindowProperty,
'assert-window-property-false': commands.parseAssertWindowPropertyFalse,
'block-network-request': commands.parseBlockNetworkRequest,
'click': commands.parseClick,
'click-with-offset': commands.parseClickWithOffset,
'call-function': commands.parseCallFunction,
Expand Down
2 changes: 2 additions & 0 deletions src/commands/all.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const functions = require('./functions.js');
const general = require('./general.js');
const input = require('./input.js');
const navigation = require('./navigation.js');
const network = require('./network.js');
const store = require('./store.js');
const wait = require('./wait.js');

Expand Down Expand Up @@ -37,6 +38,7 @@ module.exports = {
'parseAssertVariableFalse': assert.parseAssertVariableFalse,
'parseAssertWindowProperty': assert.parseAssertWindowProperty,
'parseAssertWindowPropertyFalse': assert.parseAssertWindowPropertyFalse,
'parseBlockNetworkRequest': network.parseBlockNetworkRequest,
'parseCallFunction': functions.parseCallFunction,
'parseClick': input.parseClick,
'parseClickWithOffset': input.parseClickWithOffset,
Expand Down
57 changes: 57 additions & 0 deletions src/commands/network.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// List commands handling network blocking.

const { validator } = require('../validator.js');
// Not the same `utils.js`!
const { hasError } = require('../utils.js');

// Input: glob (for example: "*.js")
function parseBlockNetworkRequest(parser) {
const ret = validator(parser, {
kind: 'string',
allowEmpty: false,
});
if (hasError(ret)) {
return ret;
}
const glob = ret.value.value.trim();

return {
'instructions': [
`await page.setRequestInterception(true);
page.on('request', interceptedRequest => {
if (interceptedRequest.isInterceptResolutionHandled()) return;
function matchesGlob(glob, text) {
const wildcard = glob.indexOf("*");
if (wildcard === -1) {
return glob === text;
}
const prefixGlob = glob.substring(0, wildcard);
const prefixText = text.substring(0, wildcard);
if (prefixGlob !== prefixText) {
return false;
}
const suffixGlob = glob.substring(wildcard + 1);
let suffixText = text.substring(wildcard);
if (suffixGlob.indexOf("*") === -1) {
return suffixText.endsWith(suffixGlob);
}
let matched = matchesGlob(suffixGlob, suffixText);
while (suffixText !== "" && !matched) {
suffixText = suffixText.substring(1);
matched = matchesGlob(suffixGlob, suffixText);
}
return matched;
}
if (matchesGlob("${glob}", interceptedRequest.url())) {
interceptedRequest.abort();
} else {
interceptedRequest.continue({}, 0);
}
});`,
],
};
}

module.exports = {
'parseBlockNetworkRequest': parseBlockNetworkRequest,
};
1 change: 1 addition & 0 deletions tests/api-output/parseBlockNetworkRequest/err-float.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a string, found `1.1` (a number)"""
1 change: 1 addition & 0 deletions tests/api-output/parseBlockNetworkRequest/err-int.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a string, found `1` (a number)"""
1 change: 1 addition & 0 deletions tests/api-output/parseBlockNetworkRequest/err-quote-2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected `\"` at the end of the string"""
1 change: 1 addition & 0 deletions tests/api-output/parseBlockNetworkRequest/err-quote.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected `\"` at the end of the string"""
1 change: 1 addition & 0 deletions tests/api-output/parseBlockNetworkRequest/err-tuple-2.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a string, found `(\"a\", 2)` (a tuple)"""
1 change: 1 addition & 0 deletions tests/api-output/parseBlockNetworkRequest/err-tuple-3.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a string, found `()` (a tuple)"""
1 change: 1 addition & 0 deletions tests/api-output/parseBlockNetworkRequest/err-tuple-4.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a string, found `(\"x\")` (a tuple)"""
1 change: 1 addition & 0 deletions tests/api-output/parseBlockNetworkRequest/err-tuple.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
error = """expected a string, found `(a, \"b\")` (a tuple)"""
33 changes: 33 additions & 0 deletions tests/api-output/parseBlockNetworkRequest/ok.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
instructions = [
"""await page.setRequestInterception(true);
page.on('request', interceptedRequest => {
if (interceptedRequest.isInterceptResolutionHandled()) return;
function matchesGlob(glob, text) {
const wildcard = glob.indexOf(\"*\");
if (wildcard === -1) {
return glob === text;
}
const prefixGlob = glob.substring(0, wildcard);
const prefixText = text.substring(0, wildcard);
if (prefixGlob !== prefixText) {
return false;
}
const suffixGlob = glob.substring(wildcard + 1);
let suffixText = text.substring(wildcard);
if (suffixGlob.indexOf(\"*\") === -1) {
return suffixText.endsWith(suffixGlob);
}
let matched = matchesGlob(suffixGlob, suffixText);
while (suffixText !== \"\" && !matched) {
suffixText = suffixText.substring(1);
matched = matchesGlob(suffixGlob, suffixText);
}
return matched;
}
if (matchesGlob(\"x\", interceptedRequest.url())) {
interceptedRequest.abort();
} else {
interceptedRequest.continue({}, 0);
}
});""",
]
2 changes: 2 additions & 0 deletions tests/html_files/external-script.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<script src="external-script.js"></script>
1 change: 1 addition & 0 deletions tests/html_files/external-script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
document.write("<div id=output></div>");
13 changes: 13 additions & 0 deletions tests/ui/block-network-request-multiple-star.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// This test is meant to ensure that we can block an external script request.
// Since we are intentionally causing request errors, don't block them.
fail-on-request-error: false
go-to: "file://" + |CURRENT_DIR| + "/" + |DOC_PATH| + "/external-script.html"
assert: "#output"
// This does not match, so it won't cause a fail.
block-network-request: "*s6ojwNhzwbj9F2cYwA9tqjtnFyUzt6YhQzfviRjB*.js"
reload:
assert: "#output"
// This matches, so the script won't load
block-network-request: "*extern*.js"
reload:
assert-false: "#output"
5 changes: 5 additions & 0 deletions tests/ui/block-network-request-multiple-star.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
=> Starting doc-ui tests...

block-network-request-multiple-star... OK

<= doc-ui tests done: 1 succeeded, 0 failed
13 changes: 13 additions & 0 deletions tests/ui/block-network-request.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// This test is meant to ensure that we can block an external script request.
// Since we are intentionally causing request errors, don't block them.
fail-on-request-error: false
go-to: "file://" + |CURRENT_DIR| + "/" + |DOC_PATH| + "/external-script.html"
assert: "#output"
// This does not match, so it won't cause a fail.
block-network-request: "*s6ojwNhzwbj9F2cYwA9tqjtnFyUzt6YhQzfviRjB.js"
reload:
assert: "#output"
// This matches, so the script won't load
block-network-request: "*.js"
reload:
assert-false: "#output"
5 changes: 5 additions & 0 deletions tests/ui/block-network-request.output
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
=> Starting doc-ui tests...

block-network-request... OK

<= doc-ui tests done: 1 succeeded, 0 failed
17 changes: 17 additions & 0 deletions tools/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,18 @@ function checkAssertObjProperty(x, func) {
func('({"a"."b": null}, CONTAINS)', 'object-path-4');
}

function checkBlockNetworkRequest(x, func) {
func('"', 'err-quote');
func('"x', 'err-quote-2');
func('1', 'err-int');
func('1.1', 'err-float');
func('(a, "b")', 'err-tuple');
func('("a", 2)', 'err-tuple-2');
func('()', 'err-tuple-3');
func('("x")', 'err-tuple-4');
func('"x"', 'ok');
}

function checkAssertVariable(x, func) {
func('', 'err-1');
func('hello', 'err-2');
Expand Down Expand Up @@ -2447,6 +2459,11 @@ const TO_CHECK = [
return wrapper(parserFuncs.parseAssertWindowPropertyFalse, x, e, name, o);
},
},
{
'name': 'block-network-request',
'func': checkBlockNetworkRequest,
'toCall': (x, e, name, o) => wrapper(parserFuncs.parseBlockNetworkRequest, x, e, name, o),
},
{
'name': 'set-attribute',
'func': checkAttributeProperty,
Expand Down

0 comments on commit 9fdd000

Please sign in to comment.