Reputation: 5250
I'm using Protractor to run integration tests on my Angular web app. My web app makes API calls using my custom Angular service ApiClient
. I mock that service with browser.addMockModule
and angular.module().factory()
. This lets me mock all my backend APIs! Here's my code:
setup() {
// Out in WebDriver.
// Third argument 'apiRequestsMap' is made available as an argument 'map'
// to the anonymous function which constructs the module.
browser.addMockModule(
'mockDataModule',
(map) =>
angular.module('mockDataModule', []).value('apiRequestsMap', map),
this.apiRequestsMap_);
const apiModuleMaker = () => {
const mockModule = angular.module('mockapiModule', ['mockDataModule']);
mockModule.factory(
'apiClient',
($q, apiRequestsMap) => ({
request: (req) => {
// In Browser.
// I can access 'apiRequestsMap'!
// And I use it to mock those API calls.
}
}));
};
browser.addMockModule('mockapiModule', apiModuleMaker);
browser.get('www.mywebpage.com/example');
}
This works pretty well and lets me set up mock APIs in my Protractor tests. The important part is that I can pass the this.apiRequestsMap_
variable from WebDriver to the Browser as apiRequestsMap
.
Now I'm wondering - can I do the opposite? How can I pass a variable from the Browser back out to WebDriver?
My first attempt was simply to edit the apiRequestsMap
object I passed in. But this seems to have been a one-way transfer. ie, when In Browser, setting apiRequestsMap.aVar = 5;
does not change this.apiRequestsMap_.aVar
.
Looking at the Protractor API, I also found browser.getRegisteredMockModules
. Unfortunately console.log(JSON.stringify(browser.getRegisteredMockModules()));
prints out [null, null, null, null, null]
.
Sorry for posting so much code and context! I'm in way over my head, so I wasn't sure which parts I could remove while allowing my code to still run. Maybe there's a better way to mock API calls directly with WebDriver? This would be a fine workaround.
Another possible take-away is me filing a feature request/bug to the Protractor developers.
Upvotes: 1
Views: 784
Reputation: 146520
You can execute Javascript code in the Browser directly from Protractor.
So in your javascript do something like below
window.__myvariable__ = {data:2, name: "abc"};
Which can be accessed by executing some Javascript code with Selenium. In Protractor that's
browser.executeScript('return window.__myvariable__;');
which returns a normal expectable Protractor promise. Note the window.__myvariable__
object returned should be json convertible.
This will get the value in your test code and it will remain until the page is refreshed. For a more detailed response look at
Access window object / browser scope from protractor
Upvotes: 2