Browsers blocks abusable JavaScript API calls until the user has interacted with the document. Examples would be opening new tab or start playing video or audio.
E.g. if you attempt to call video.play()
in a test, the call will reject with a message like this:
NotAllowedError: play() failed because the user didn't interact with the document first. https://goo.gl/xX8pDD
Workaround
To pretend document interaction in a test you can create an element, click on it, and remove the element again. This unblocks the entire JavaScript API for the current page.
You can include the following module in your test to get a method interact_with_page
that does just that:
module InteractWithPage
def interact_with_page
create_empty_interaction_stub
click_empty_interaction_stub
ensure
remove_empty_interaction_stub
end
private
def create_empty_interaction_stub
page.execute_script(<<~JS)
let stub = document.createElement('div')
stub.classList.add('empty-interaction')
// Stop the click from bubbling up and closing any overlays
stub.addEventListener('click', function(event) {
event.stopImmediatePropagation()
event.preventDefault()
})
// Make sure the stub has a clickable area
stub.style.width = '1px'
stub.style.height = '1px'
stub.style.backgroundColor = 'blue'
// Make sure the stub is positioned over any overlays to be clickable
stub.style.position = 'fixed'
stub.style.bottom = '0'
stub.style.right = '0'
stub.style.zIndex = '9999999999999999'
document.body.appendChild(stub)
JS
end
def click_empty_interaction_stub
page.find('.empty-interaction').click
end
def remove_empty_interaction_stub
page.execute_script(<<~JS)
let stub = document.querySelector('.empty-interaction')
if (stub) {
stub.remove()
}
JS
end
end
To use it in Cucumber:
World(InteractWithPage)
When 'I have interacted with the page' do
interact_with_page
end
Posted by Henning Koch to makandra dev (2021-03-10 10:04)