Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add block-network-request command #600

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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) {
GuillaumeGomez marked this conversation as resolved.
Show resolved Hide resolved
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
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you mention this in the documentation as well please? Could be surprising that a test fails if you block a request in another command.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I've addressed both nits.

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