Skip to content

Commit

Permalink
Support Conditional Clicking in Broker Protection (#1141)
Browse files Browse the repository at this point in the history
* First pass at conditional clicking

* Add additional tests

* Fix linting issues, remove unneeded operators

* Fix types for BuildUrl

* Minor refactor, add unit tests

* Clean-up error reporting and add test

* Refactor subactions to run from routing

* Refactor click action error workflow

* Flip bit back on integration test

* Missed conflict resolution

* Add collector to integration tests

* Missed one

* Adopt additional API changes

* Lint fixes
  • Loading branch information
brianhall authored Nov 21, 2024
1 parent 22e3eb0 commit 389144d
Show file tree
Hide file tree
Showing 17 changed files with 592 additions and 59 deletions.
75 changes: 75 additions & 0 deletions injected/integration-test/broker-protection.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,70 @@ test.describe('Broker Protection communications', () => {
await page.waitForURL((url) => url.hash === '#1-2', { timeout: 2000 });
});

test('conditional clicks - hard-coded success', async ({ page }, workerInfo) => {
const dbp = BrokerProtectionPage.create(page, workerInfo.project.use);
await dbp.enabled();
await dbp.navigatesTo('conditional-clicks.html');
await dbp.receivesAction('conditional-clicks-hard-coded-success.json');
const response = await dbp.collector.waitForMessage('actionCompleted');

dbp.isSuccessMessage(response);
await page.waitForURL((url) => url.hash === '#yes', { timeout: 2000 });
});

test('conditional clicks - hard-coded default', async ({ page }, workerInfo) => {
const dbp = BrokerProtectionPage.create(page, workerInfo.project.use);
await dbp.enabled();
await dbp.navigatesTo('conditional-clicks.html');
await dbp.receivesAction('conditional-clicks-hard-coded-default.json');
const response = await dbp.collector.waitForMessage('actionCompleted');

dbp.isSuccessMessage(response);
await page.waitForURL((url) => url.hash === '#no', { timeout: 2000 });
});

test('conditional clicks - do not throw error on defined (but empty) default', async ({ page }, workerInfo) => {
const dbp = BrokerProtectionPage.create(page, workerInfo.project.use);
await dbp.enabled();
await dbp.navigatesTo('conditional-clicks.html');
await dbp.receivesAction('conditional-clicks-hard-coded-null-default.json');
const response = await dbp.collector.waitForMessage('actionCompleted');

dbp.isSuccessMessage(response);
});

test('conditional clicks - throw error if default is undefined', async ({ page }, workerInfo) => {
const dbp = BrokerProtectionPage.create(page, workerInfo.project.use);
await dbp.enabled();
await dbp.navigatesTo('conditional-clicks.html');
await dbp.receivesAction('conditional-clicks-hard-coded-undefined-default.json');
const response = await dbp.collector.waitForMessage('actionCompleted');

dbp.isErrorMessage(response);
});

test('conditional clicks - interpolated success', async ({ page }, workerInfo) => {
const dbp = BrokerProtectionPage.create(page, workerInfo.project.use);
await dbp.enabled();
await dbp.navigatesTo('conditional-clicks.html');
await dbp.receivesAction('conditional-clicks-interpolated-success.json');
const response = await dbp.collector.waitForMessage('actionCompleted');

dbp.isSuccessMessage(response);
await page.waitForURL((url) => url.hash === '#yes', { timeout: 2000 });
});

test('conditional clicks - interpolated default', async ({ page }, workerInfo) => {
const dbp = BrokerProtectionPage.create(page, workerInfo.project.use);
await dbp.enabled();
await dbp.navigatesTo('conditional-clicks.html');
await dbp.receivesAction('conditional-clicks-interpolated-default.json');
const response = await dbp.collector.waitForMessage('actionCompleted');

dbp.isSuccessMessage(response);
await page.waitForURL((url) => url.hash === '#no', { timeout: 2000 });
});

test('getCaptchaInfo', async ({ page }, workerInfo) => {
const dbp = BrokerProtectionPage.create(page, workerInfo.project.use);
await dbp.enabled();
Expand Down Expand Up @@ -524,6 +588,17 @@ test.describe('Broker Protection communications', () => {
expect(currentUrl).not.toContain('#');
});

test('expectation with conditional subaction', async ({ page }, workerInfo) => {
const dbp = BrokerProtectionPage.create(page, workerInfo.project.use);
await dbp.enabled();
await dbp.navigatesTo('expectation-actions.html');
await dbp.receivesAction('expectation-actions-conditional-subaction.json');
const response = await dbp.collector.waitForMessage('actionCompleted');

dbp.isSuccessMessage(response);
await page.waitForURL((url) => url.hash === '#2', { timeout: 2000 });
});

test.describe('retrying', () => {
test('retrying a click', async ({ page }, workerInfo) => {
const dbp = BrokerProtectionPage.create(page, workerInfo.project.use);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"state": {
"action": {
"actionType": "click",
"id": "1",
"choices": [
{
"condition": {
"left": "40",
"operation": ">=",
"right": "45"
},
"elements": [
{ "type": "button", "selector": ".//a[text()='Yes']" }
]
}
],
"default": {
"elements": [
{ "type": "button", "selector": ".//a[text()='No']" }
]
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"state": {
"action": {
"actionType": "click",
"id": "1",
"choices": [
{
"condition": {
"left": "40",
"operation": ">=",
"right": "45"
},
"elements": [
{ "type": "button", "selector": ".//a[text()='Yes']" }
]
}
],
"default": null
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"state": {
"action": {
"actionType": "click",
"id": "1",
"choices": [
{
"condition": {
"left": "50",
"operation": ">=",
"right": "45"
},
"elements": [
{ "type": "button", "selector": ".//a[text()='Yes']" }
]
}
],
"default": {
"elements": [
{ "type": "button", "selector": ".//a[text()='No']" }
]
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"state": {
"action": {
"actionType": "click",
"id": "1",
"retry": {
"environment": "web",
"interval": { "ms": 1000 },
"maxAttempts": 1
},
"choices": [
{
"condition": {
"left": "40",
"operation": ">=",
"right": "45"
},
"elements": [
{ "type": "button", "selector": ".//a[text()='Yes']" }
]
}
]
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"state": {
"action": {
"actionType": "click",
"id": "1",
"choices": [
{
"condition": {
"left": "${age}",
"operation": ">=",
"right": "45"
},
"elements": [
{ "type": "button", "selector": ".//a[text()='Yes']" }
]
}
],
"default": {
"elements": [
{ "type": "button", "selector": ".//a[text()='No']" }
]
}
},
"data": {
"userProfile": {
"age": "40"
}
}
}
}



Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"state": {
"action": {
"actionType": "click",
"id": "1",
"choices": [
{
"condition": {
"left": "${age}",
"operation": ">=",
"right": "45"
},
"elements": [
{ "type": "button", "selector": ".//a[text()='Yes']" }
]
}
],
"default": {
"elements": [
{ "type": "button", "selector": ".//a[text()='No']" }
]
}
},
"data": {
"userProfile": {
"age": "50"
}
}
}
}



Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"state": {
"action": {
"actionType": "expectation",
"id": "2",
"expectations": [
{
"type": "text",
"selector": "body",
"expect": "How old is John Doe?"
}
],
"actions": [
{
"actionType": "click",
"id": "1",
"choices": [
{
"condition": {
"left": "${age}",
"operation": ">=",
"right": "45"
},
"elements": [
{ "type": "button", "selector": ".//a[text()='Yes']" }
]
}
],
"default": {
"elements": [
{ "type": "button", "selector": ".//a[text()='No']" }
]
}
}
]
},
"data": {
"userProfile": {
"age": "40"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Broker Protection</title>
</head>
<body>
<div class="result">
<h3>Is John Doe over the age of 45?</h3>
<a href="#" class="answer" data-id="yes">Yes</a>
<a href="#" class="answer" data-id="no">No</a>
</div>
<script>
document.querySelectorAll('.answer').forEach(answer =>
answer.addEventListener('click', function(e) {
e.preventDefault();
const id = this.getAttribute('data-id');

window.location.hash = id;
this.removeEventListener('click', arguments.callee);
})
);
</script>
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,19 @@
<body>
<div class="result">
How old is John Doe?
<a href="#" class="view-more" data-id="1">View More</a>
<a href="#" class="view-more" data-id="1">Yes</a>
<a href="#" class="view-more" data-id="2">No</a>
</div>
<script>
document.querySelector('.view-more').addEventListener('click', function(e) {
e.preventDefault();
const id = this.getAttribute('data-id');
document.querySelectorAll('.view-more').forEach(viewMore =>
viewMore.addEventListener('click', function(e) {
e.preventDefault();
const id = this.getAttribute('data-id');

window.location.hash = id;
this.removeEventListener('click', arguments.callee);
})
window.location.hash = id;
this.removeEventListener('click', arguments.callee);
})
);
</script>
</body>
</html>
Loading

0 comments on commit 389144d

Please sign in to comment.