Skip to content

Commit c1e47d3

Browse files
[js][bidi] Script Module Add/Remove preload script command (#12117)
[js][bidi] Script Module Add/Remove preload script Co-authored-by: Sri Harsha <[email protected]>
1 parent 8a73d50 commit c1e47d3

File tree

5 files changed

+329
-0
lines changed

5 files changed

+329
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<script>window.preloadScriptFunction()</script>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<script>delete window.foo</script>

javascript/node/selenium-webdriver/bidi/scriptManager.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const {
2323
} = require('./evaluateResult')
2424
const { RealmInfo } = require('./realmInfo')
2525
const { RemoteValue } = require('./protocolValue')
26+
const { WebDriverError } = require('../lib/error')
2627

2728
class ScriptManager {
2829
constructor(driver) {
@@ -179,6 +180,39 @@ class ScriptManager {
179180
return this.createEvaluateResult(response)
180181
}
181182

183+
async addPreloadScript(
184+
functionDeclaration,
185+
argumentValueList = null,
186+
sandbox = null
187+
) {
188+
const params = {
189+
functionDeclaration: functionDeclaration,
190+
arguments: argumentValueList,
191+
sandbox: sandbox,
192+
}
193+
194+
const command = {
195+
method: 'script.addPreloadScript',
196+
params,
197+
}
198+
199+
let response = await this.bidi.send(command)
200+
return response.result.script
201+
}
202+
203+
async removePreloadScript(script) {
204+
const params = { script: script }
205+
const command = {
206+
method: 'script.removePreloadScript',
207+
params,
208+
}
209+
let response = await this.bidi.send(command)
210+
if ('error' in response) {
211+
throw new WebDriverError(response.error)
212+
}
213+
return response.result
214+
}
215+
182216
getCallFunctionParams(
183217
targetType,
184218
id,

javascript/node/selenium-webdriver/lib/test/fileserver.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ const Pages = (function () {
109109
addPage('uploadInvisibleTestPage', 'upload_invisible.html')
110110
addPage('virtualAuthenticator', 'virtual-authenticator.html')
111111
addPage('logEntryAdded', 'bidi/logEntryAdded.html')
112+
addPage('scriptTestAccessProperty', 'bidi/scriptTestAccessProperty.html')
113+
addPage('scriptTestRemoveProperty', 'bidi/scriptTestRemoveProperty.html')
112114

113115
return pages
114116
})()

javascript/node/selenium-webdriver/test/bidi/bidi_test.js

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const { EvaluateResultType } = require('../../bidi/evaluateResult')
4141
const { ResultOwnership } = require('../../bidi/resultOwnership')
4242
const { SpecialNumberType } = require('../../bidi/protocolType')
4343
const { RealmType } = require('../../bidi/realmInfo')
44+
const { WebDriverError } = require('../../lib/error')
4445

4546
suite(
4647
function (env) {
@@ -1438,6 +1439,296 @@ suite(
14381439
assert.notEqual(windowRealm.realmId, null)
14391440
assert.equal(windowRealm.browsingContext, windowId)
14401441
})
1442+
1443+
it('can add preload script', async function () {
1444+
const id = await driver.getWindowHandle()
1445+
const manager = await ScriptManager(id, driver)
1446+
1447+
await manager.addPreloadScript("() => { window.foo='bar'; }")
1448+
1449+
// Check that preload script didn't apply the changes to the current context
1450+
let result = await manager.evaluateFunctionInBrowsingContext(
1451+
id,
1452+
'window.foo',
1453+
true
1454+
)
1455+
assert.equal(result.result.type, 'undefined')
1456+
1457+
await driver.switchTo().newWindow('window')
1458+
const new_window_id = await driver.getWindowHandle()
1459+
1460+
// Check that preload script applied the changes to the window
1461+
result = await manager.evaluateFunctionInBrowsingContext(
1462+
new_window_id,
1463+
'window.foo',
1464+
true
1465+
)
1466+
1467+
assert.equal(result.resultType, EvaluateResultType.SUCCESS)
1468+
assert.notEqual(result.realmId, null)
1469+
assert.equal(result.result.type, 'string')
1470+
assert.notEqual(result.result.value, null)
1471+
assert.equal(result.result.value, 'bar')
1472+
1473+
const browsingContext = await BrowsingContext(driver, {
1474+
type: 'tab',
1475+
})
1476+
1477+
await browsingContext.navigate(Pages.logEntryAdded, 'complete')
1478+
1479+
// Check that preload script was applied after navigation
1480+
result = await manager.evaluateFunctionInBrowsingContext(
1481+
new_window_id,
1482+
'window.foo',
1483+
true
1484+
)
1485+
1486+
assert.equal(result.result.type, 'string')
1487+
assert.equal(result.result.value, 'bar')
1488+
})
1489+
1490+
it('can add same preload script twice', async function () {
1491+
const id = await driver.getWindowHandle()
1492+
const manager = await ScriptManager(id, driver)
1493+
1494+
const script_1 = await manager.addPreloadScript('() => { return 42; }')
1495+
const script_2 = await manager.addPreloadScript('() => { return 42; }')
1496+
1497+
assert.notEqual(script_1, script_2)
1498+
})
1499+
1500+
it('can access preload script properties', async function () {
1501+
const id = await driver.getWindowHandle()
1502+
const manager = await ScriptManager(id, driver)
1503+
1504+
await manager.addPreloadScript(
1505+
'() => { window.preloadScriptFunction = () => window.baz = 42; }'
1506+
)
1507+
1508+
await driver.switchTo().newWindow('tab')
1509+
const new_tab_id = await driver.getWindowHandle()
1510+
await driver.get(Pages.scriptTestAccessProperty)
1511+
1512+
const result = await manager.evaluateFunctionInBrowsingContext(
1513+
new_tab_id,
1514+
'window.baz',
1515+
true
1516+
)
1517+
1518+
assert.equal(result.result.type, 'number')
1519+
assert.equal(result.result.value, 42)
1520+
})
1521+
1522+
it('can add preload script to sandbox', async function () {
1523+
const id = await driver.getWindowHandle()
1524+
const manager = await ScriptManager(id, driver)
1525+
1526+
await manager.addPreloadScript('() => { window.foo = 1; }')
1527+
await manager.addPreloadScript(
1528+
'() => { window.bar = 2; }',
1529+
null,
1530+
'sandbox'
1531+
)
1532+
1533+
await driver.switchTo().newWindow('tab')
1534+
const new_tab_id = await driver.getWindowHandle()
1535+
1536+
let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
1537+
new_tab_id,
1538+
'window.foo',
1539+
true,
1540+
null,
1541+
'sandbox'
1542+
)
1543+
1544+
assert.equal(result_in_sandbox.result.type, 'undefined')
1545+
1546+
let result = await manager.evaluateFunctionInBrowsingContext(
1547+
new_tab_id,
1548+
'window.bar',
1549+
true
1550+
)
1551+
1552+
assert.equal(result.result.type, 'undefined')
1553+
1554+
result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
1555+
new_tab_id,
1556+
'window.bar',
1557+
true,
1558+
null,
1559+
'sandbox'
1560+
)
1561+
1562+
assert.equal(result_in_sandbox.result.type, 'number')
1563+
assert.equal(result_in_sandbox.result.value, 2)
1564+
})
1565+
1566+
it('can remove properties set by preload script', async function () {
1567+
const id = await driver.getWindowHandle()
1568+
const manager = await ScriptManager(id, driver)
1569+
1570+
await manager.addPreloadScript('() => { window.foo = 42; }')
1571+
await manager.addPreloadScript(
1572+
'() => { window.foo = 50; }',
1573+
null,
1574+
'sandbox_1'
1575+
)
1576+
1577+
await driver.switchTo().newWindow('tab')
1578+
const new_tab_id = await driver.getWindowHandle()
1579+
await driver.get(Pages.scriptTestRemoveProperty)
1580+
1581+
let result = await manager.evaluateFunctionInBrowsingContext(
1582+
new_tab_id,
1583+
'window.foo',
1584+
true
1585+
)
1586+
assert.equal(result.result.type, 'undefined')
1587+
1588+
result = await manager.evaluateFunctionInBrowsingContext(
1589+
new_tab_id,
1590+
'window.foo',
1591+
true,
1592+
null,
1593+
'sandbox_1'
1594+
)
1595+
assert.equal(result.result.type, 'number')
1596+
assert.equal(result.result.value, 50)
1597+
})
1598+
1599+
it('can remove preload script', async function () {
1600+
const id = await driver.getWindowHandle()
1601+
const manager = await ScriptManager(id, driver)
1602+
1603+
let script = await manager.addPreloadScript(
1604+
"() => { window.foo='bar'; }"
1605+
)
1606+
1607+
await driver.switchTo().newWindow('tab')
1608+
const tab_1_id = await driver.getWindowHandle()
1609+
1610+
let result = await manager.evaluateFunctionInBrowsingContext(
1611+
tab_1_id,
1612+
'window.foo',
1613+
true
1614+
)
1615+
1616+
assert.equal(result.result.type, 'string')
1617+
assert.equal(result.result.value, 'bar')
1618+
1619+
await manager.removePreloadScript(script)
1620+
1621+
await driver.switchTo().newWindow('tab')
1622+
const tab_2_id = await driver.getWindowHandle()
1623+
1624+
// Check that changes from preload script were not applied after script was removed
1625+
result = await manager.evaluateFunctionInBrowsingContext(
1626+
tab_2_id,
1627+
'window.foo',
1628+
true
1629+
)
1630+
1631+
assert.equal(result.result.type, 'undefined')
1632+
})
1633+
1634+
it('cannot remove same preload script twice', async function () {
1635+
const id = await driver.getWindowHandle()
1636+
const manager = await ScriptManager(id, driver)
1637+
1638+
let script = await manager.addPreloadScript(
1639+
"() => { window.foo='bar'; }"
1640+
)
1641+
1642+
await manager.removePreloadScript(script)
1643+
1644+
await manager.removePreloadScript(script).catch((error) => {
1645+
assert(error instanceof WebDriverError)
1646+
})
1647+
})
1648+
1649+
it('can remove one of preload script', async function () {
1650+
const id = await driver.getWindowHandle()
1651+
const manager = await ScriptManager(id, driver)
1652+
1653+
let script_1 = await manager.addPreloadScript(
1654+
"() => { window.bar='foo'; }"
1655+
)
1656+
1657+
let script_2 = await manager.addPreloadScript(
1658+
"() => { window.baz='bar'; }"
1659+
)
1660+
1661+
await manager.removePreloadScript(script_1)
1662+
1663+
await driver.switchTo().newWindow('tab')
1664+
const new_tab_id = await driver.getWindowHandle()
1665+
1666+
// Check that the first script didn't run
1667+
let result = await manager.evaluateFunctionInBrowsingContext(
1668+
new_tab_id,
1669+
'window.bar',
1670+
true
1671+
)
1672+
1673+
assert.equal(result.result.type, 'undefined')
1674+
1675+
// Check that the second script still applied the changes to the window
1676+
result = await manager.evaluateFunctionInBrowsingContext(
1677+
new_tab_id,
1678+
'window.baz',
1679+
true
1680+
)
1681+
1682+
assert.equal(result.result.type, 'string')
1683+
assert.equal(result.result.value, 'bar')
1684+
1685+
// Clean up the second script
1686+
await manager.removePreloadScript(script_2)
1687+
})
1688+
1689+
it('can remove one of preload script from sandbox', async function () {
1690+
const id = await driver.getWindowHandle()
1691+
const manager = await ScriptManager(id, driver)
1692+
1693+
let script_1 = await manager.addPreloadScript(
1694+
'() => { window.foo = 1; }'
1695+
)
1696+
1697+
let script_2 = await manager.addPreloadScript(
1698+
'() => { window.bar = 2; }',
1699+
null,
1700+
'sandbox'
1701+
)
1702+
1703+
// Remove first preload script
1704+
await manager.removePreloadScript(script_1)
1705+
1706+
// Remove second preload script
1707+
await manager.removePreloadScript(script_2)
1708+
1709+
await driver.switchTo().newWindow('tab')
1710+
const new_tab_id = await driver.getWindowHandle()
1711+
1712+
// Make sure that changes from first preload script were not applied
1713+
let result_in_window = await manager.evaluateFunctionInBrowsingContext(
1714+
new_tab_id,
1715+
'window.foo',
1716+
true
1717+
)
1718+
1719+
assert.equal(result_in_window.result.type, 'undefined')
1720+
1721+
// Make sure that changes from second preload script were not applied
1722+
let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
1723+
new_tab_id,
1724+
'window.bar',
1725+
true,
1726+
null,
1727+
'sandbox'
1728+
)
1729+
1730+
assert.equal(result_in_sandbox.result.type, 'undefined')
1731+
})
14411732
})
14421733

14431734
describe('Integration Tests', function () {

0 commit comments

Comments
 (0)