Skip to content

Setting baseUrl in protractor.conf is not working #11089

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jared-christensen opened this issue Jun 1, 2018 · 15 comments
Closed

Setting baseUrl in protractor.conf is not working #11089

jared-christensen opened this issue Jun 1, 2018 · 15 comments

Comments

@jared-christensen
Copy link

Versions

Angular CLI: 6.0.7
Node: 10.2.1
OS: darwin x64
Angular: 6.0.3
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.6.7
@angular-devkit/build-angular     0.6.7
@angular-devkit/build-optimizer   0.6.7
@angular-devkit/core              0.6.7
@angular-devkit/schematics        0.6.7
@angular/cli                      6.0.7
@ngtools/webpack                  6.0.7
@schematics/angular               0.6.7
@schematics/update                0.6.7
rxjs                              6.2.0
typescript                        2.7.2
webpack                           4.8.3

node: v10.2.1
npm: 6.1.0
macOS High Sierra 10.13.4

Repro steps

  • In a new Angular Cli project, in the e2e folder open protractor.conf.js
  • change baseUrl to https://google.com
  • run ng e2e

Observed behavior

The brower opens up to http://localhost:4200/ and not https://google.com

Desired behavior

I think it should go to what the baseurl is set to.

Mention any other details that might be useful (optional)

I add browser.sleep(900000) in the first test after navigateTo so I have time to see what is going on.

@flodan
Copy link

flodan commented Jun 21, 2018

I have the same problem here. Is there any information about when this is fixed? Or is there a certain workaround?

@Schmaga
Copy link

Schmaga commented Jul 2, 2018

It seems to have to do with using the "serve" target for that configuration, which for some reason overwrites the baseUrl from the protractor.conf. We managed to work around it by either modifying the default "production" e2e config to not use the "serve" as "devServerTarget", or creating a separate configuration in the e2e project part of the angular.json for accessing a different webserver, like this:

"e2e": {
  "builder": "@angular-devkit/build-angular:protractor",
  "options": {
   },
  "configurations": {
     "local": {
        "protractorConfig": "./protractor.conf.js"
        "devServerTarget": "my-app:serve:production",
      },
     "remote": {
        "protractorConfig": "./protractor.conf.remote.js",
      }
   }
}

The first "local" config is used for e2e testing against a locally running "ng served" web server, and the "remote" config is used to run the test suite against a remote web server, which is configured using the baseUrl in the different protractor.conf.remote.js.

Maybe this will help other people with the same problem.

Update: Just to clarify, you don't need a separate protractor.conf in case you only want to overwrite the baseUrl. You can simply do that using the "baseUrl" property of the configuration, or the "base-url" command line parameter:

"remote": {
  "baseUrl": "http://mytestserver",
}

@SaydChada
Copy link

You can pass --public-host arg to your ng e2e call (i.e: ng e2e --public-host="https://hostname.com")

@mtaylor769
Copy link

@Schmaga - Leaving the "options" block empty like that causes the following error:
Schema validation failed with the following errors: Data path "" should have required property 'protractorConfig'.

I have a local build that needs to point to a dedicated selenium server (not localhost) and while I was hopeful this would work, isn't acting as expected even when I add distinct 'baseURL' arguments to both "remote" and "local" blocks within "configurations"

@mtaylor769
Copy link

mtaylor769 commented Aug 7, 2018

Here's my angular.json block for 'e2e':

"e2e": {
  "builder": "@angular-devkit/build-angular:protractor",
  "options": {
    "protractorConfig": "./tests/e2e/protractor.conf.js",
    "devServerTarget": "my-app:serve",
  },
  "configurations": {
    "local": {
      "protractorConfig": "./tests/e2e/protractor.conf.js",
      "devServerTarget": "my-app:serve",
      "baseUrl": "https://my.qa.app.server.com/"
    },
    "remote": {
      "baseUrl": "https://my.prod.app.server.com/"
    }
  }
}

@Schmaga
Copy link

Schmaga commented Aug 7, 2018

@mtaylor769 Sorry I should have explained that the options block was omitted for brevity

@mtaylor769
Copy link

@Schmaga understood, but I'm still seeing the issue of it redirecting to localhost:4200 in the 'beforeEach' in the spec unless I prepend some sort of 'baseURL' that's hardcoded in a config somewhere. My understanding was that the variables declared and set in the beforeEach were then in scope for the subsequent tests.

One note, however, I am using Page Object Models and it's the browser.get() calls in those that I am seeing this behavior in.

(https://github.com/angular/protractor/blob/master/docs/page-objects.md)

@Schmaga
Copy link

Schmaga commented Aug 21, 2018

@mtaylor769 Are you sure you are not still using the "serve" target? That always seems to overwrite the baseUrl.

@aniruddhadas9
Copy link
Contributor

aniruddhadas9 commented Sep 26, 2018

@intellix
Copy link
Contributor

intellix commented Oct 8, 2018

I'm setting up a Selenium grid and after getting it to work, wanted to share a composition of what you need to do.

Basically the workaround is to remove the devServerTarget from myapp-e2e.targets.e2e.options and manually serve, so something like this for an external e2e server that needs to talk to your app:

angular.json snippet:

"myapp-e2e": {
  "root": "e2e/",
  "projectType": "application",
  "targets": {
    "e2e": {
      "builder": "@angular-devkit/build-angular:protractor",
      "options": {
        "protractorConfig": "e2e/protractor.conf.js"
      },
      "configurations": {
        "production": {
          "devServerTarget": "myapp:serve:production"
        }
      }
    },

protractor.conf.js:

directConnect: false,
seleniumAddress: 'https://salenium.myapp.com/wd/hub',
baseUrl: 'http://somewhere-where-selenium-can-access-ng-serve:4200',

commands to run in parallel:

ng serve --host=0.0.0.0 --disable-host-check
ng e2e

ng e2e will instruct the external Selenium server to run tests against the server accessible via baseUrl

@filipesilva
Copy link
Contributor

Unless I'm missing something here, this behaviour is very much intended.

When devServerTarget is present in the options and is different from an empty string, the protractor baseUrl will always be overwritten with a computed value. Semantically it means "I want to test this dev server". All the host related options from the devServer (publicHost, host, ssl, port) will be used in this computation.

So if you don't actually want to use the devServer, you should create a configuration that sets "devServerTarget": "". If you want to use the devServer exposed in another address, I'd suggest using publicHost on the devServer target.

@intellix
Copy link
Contributor

intellix commented Oct 8, 2018

One problem I have is that the value needs to be dynamic as we don't know where the server is going to be accessible from ahead of time.

We're using Jenkins pipelines to run the e2e tests. That Jenkins executor is bought up dynamically within a Kubernetes cluster and will have a randomised IP. Our Selenium grid deploys pods in Kubernetes and needs to be able to access the ng e2e web-server running within randomly placed Jenkins executor pod.

package.json scripts:

"scripts": {
  "e2e": "ng e2e",
  "e2e:ci": "CI=true npm run e2e",
  "serve": "ng serve --host=0.0.0.0 --disable-host-check"
}

Jenkinsfile pipeline for starting the e2e tests:

POD_POST = sh (
    script: 'ip r show dev "$(ip r|awk \'$1=="default"{print$NF}\')"|awk \'$1!="default"{print$NF}\'',
    returnStdout: true
).trim()
withEnv(['POD_HOST=' + POD_POST]) {
    sh 'docker-compose up --abort-on-container-exit ngserve e2e'
}

docker-compose.yml:

services:
  ngserve:
    image: app
    build: .
    command: npm run serve
    ports:
      - "4200:4200"

  e2e:
    image: app
    command: npm run e2e:ci
    depends_on:
      - ngserve
    environment:
      POD_HOST:

Inside the protractor.config.js file:

baseUrl: process.env.CI ? `http://${process.env.POD_HOST}:4200` : 'http://localhost:4200/',
directConnect: process.env.CI ? false : true,
seleniumAddress: 'https://zalenium.k8s.ourserver.io/wd/hub',

When you deploy within a K8S cluster the host/port are totally randomised and I don't see how this can be accomplished within angular.json without using bash magic

Everything I used to use was ripped away from CLI and placed into static configuration files and it just gets more and more difficult to accomplish :)

@filipesilva
Copy link
Contributor

@intellix no, there isn't a good way to call call ng e2e and send CLI overrides to the serve command, unfortunately.

That's an interest use case. I'm not sure how it can be addressed without fully exposing all transitive dependencies. Perhaps by allowing the config file to pull values from the environment or commands.

@manofthelionarmy
Copy link

One problem I have is that the value needs to be dynamic as we don't know where the server is going to be accessible from ahead of time.

We're using Jenkins pipelines to run the e2e tests. That Jenkins executor is bought up dynamically within a Kubernetes cluster and will have a randomised IP. Our Selenium grid deploys pods in Kubernetes and needs to be able to access the ng e2e web-server running within randomly placed Jenkins executor pod.

package.json scripts:

"scripts": {
  "e2e": "ng e2e",
  "e2e:ci": "CI=true npm run e2e",
  "serve": "ng serve --host=0.0.0.0 --disable-host-check"
}

Jenkinsfile pipeline for starting the e2e tests:

POD_POST = sh (
    script: 'ip r show dev "$(ip r|awk \'$1=="default"{print$NF}\')"|awk \'$1!="default"{print$NF}\'',
    returnStdout: true
).trim()
withEnv(['POD_HOST=' + POD_POST]) {
    sh 'docker-compose up --abort-on-container-exit ngserve e2e'
}

docker-compose.yml:

services:
  ngserve:
    image: app
    build: .
    command: npm run serve
    ports:
      - "4200:4200"

  e2e:
    image: app
    command: npm run e2e:ci
    depends_on:
      - ngserve
    environment:
      POD_HOST:

Inside the protractor.config.js file:

baseUrl: process.env.CI ? `http://${process.env.POD_HOST}:4200` : 'http://localhost:4200/',
directConnect: process.env.CI ? false : true,
seleniumAddress: 'https://zalenium.k8s.ourserver.io/wd/hub',

When you deploy within a K8S cluster the host/port are totally randomised and I don't see how this can be accomplished within angular.json without using bash magic

Everything I used to use was ripped away from CLI and placed into static configuration files and it just gets more and more difficult to accomplish :)

I'm faced with a similar issue, except I'm using Travis CI. During my builds, I need to get the Docker Host IP in Travis CI, and I'm not certain if that IP will be random. It is the last piece I need to ensure my angular e2e tests pass on Travis CI.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants