hubatish
hubatish

Reputation: 5250

How to send message from Browser to WebDriver with Protractor?

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

Answers (1)

Tarun Lalwani
Tarun Lalwani

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

Related Questions