Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 停靠的角度E2E测试在本地计算机上通过,但在Travis CI中超时_Angular_Selenium_Docker_Protractor_Travis Ci - Fatal编程技术网

Angular 停靠的角度E2E测试在本地计算机上通过,但在Travis CI中超时

Angular 停靠的角度E2E测试在本地计算机上通过,但在Travis CI中超时,angular,selenium,docker,protractor,travis-ci,Angular,Selenium,Docker,Protractor,Travis Ci,我试图将我的角度e2e测试记录下来。简单地说,我创建了一个docker-compose.test.yml文件: version: "3.4" services: # set up angular app angular: build: context: ./frontend dockerfile: sample.Dockerfile target: test image: angular:test container_nam

我试图将我的角度e2e测试记录下来。简单地说,我创建了一个docker-compose.test.yml文件:

version: "3.4"

services:
  # set up angular app
  angular:
    build: 
      context: ./frontend
      dockerfile: sample.Dockerfile
      target: test
    image: angular:test
    container_name: angular
    ports: 
      - "4200:4200"
    depends_on: 
      - nodejs 
    command: npm run e2e -- --protractor-config=e2e/protractor-docker.conf.js --host 0.0.0.0

  nodejs:
    build:
      context: ./backend
      dockerfile: Dockerfile
      target: development
    image: nodejs:dev
    container_name: nodejs
    ports: 
      - "3000:3000"
    networks:
      - backend
    depends_on: 
      - db
    restart: always
  # the mongo database
  db:
    image: mongo
    container_name: db
    networks: 
      - backend
    ports: 
      - "27017:27017"
networks: 
  backend: 
    driver: bridge
version: '3.4'

services:
  selenium-hub:
    image: selenium/hub:3.141.59
    container_name: selenium-hub
    environment: 
      - GRID_TIMEOUT=10000
    ports: 
      - "4444:4444"
    privileged: true
    #tty: true

  chrome_node:
    image: selenium/node-chrome:3.141.59
    volumes: 
      - /dev/shm:/dev/shm
    container_name: chrome_node
    environment:
      - HUB_PORT_4444_TCP_ADDR=selenium-hub
      - HUB_PORT_4444_TCP_PORT=4444
    ports:
      - "5555:5555"
    privileged: true
    depends_on:
      - selenium-hub
    #tty: true
  proxy: 
    build: 
      context: ./proxy
      dockerfile: Dockerfile
    image: proxy
    container_name: proxy
    # HOST:CONTAINER
    ports: 
      - "80:80"
    #tty: true
    depends_on: 
      - angular
  angular:
    build:
      context: ./frontend
      dockerfile: sample.Dockerfile
      target: production
    image: angular:prod
    container_name: angular
    ports:
      - "4200:4200"
    privileged: true 
    depends_on: 
        - nodejs
    #tty: true
  nodejs:
    build:
      context: ./backend
      dockerfile: Dockerfile
      target: development
    image: nodejs:dev
    container_name: nodejs
    ports: 
      - "3000:3000"
    depends_on: 
      - db
    restart: always
    #tty: true
  # the mongo database
  db:
    image: mongo
    container_name: db
    ports: 
      - "27017:27017"
    #tty: true
  protractor:
    build:
      context: ./frontend
      dockerfile: sample.Dockerfile
      target: test
    image: angular:test
    container_name: protractor
    ports: 
      - "9876:9876"
    privileged: true
    depends_on:
      - selenium-hub
      - chrome_node
    #tty: true --> not neccesary
    command: npm run e2e -- --protractor-config=e2e/protractor-ci.conf.js --webdriver-update=false --dev-server-target= 
对于量角器配置,我遵循了此链接中的教程:

我不得不做一些调整,例如:

let config = require('./protractor.conf').config;

// Tell protrator where the chrome driver is
// https://gitlab.com/dasch8/angular-ci/
// https://hub.docker.com/r/weboaks/node-karma-protractor-chrome/
config.chromeDriver = "/usr/bin/chromedriver";

config.allScriptsTimeout = 60000;

config.getPageTimeout = 60000;

config.jasmineNodeOpts.defaultTimeoutInterval = 60000;

// have it connect to the angular app
// config.baseUrl = "http://angular:4200";

config.capabilities = {
  browserName: 'chrome',
  chromeOptions: {
    args: ['--headless', '--no-sandbox', '--disable-gpu']
  },

};


exports.config = config;
使用该配置,e2e测试在我的本地机器上成功。但是,当我在.travis.yml的脚本中运行此命令时:

before_script: 
    - docker-compose -f docker-compose.test.yml build
  script:
    - docker-compose -f docker-compose.test.yml run --name angular -p 4200:4200 angular
before_script: 
        - docker-compose -f docker-compose.selenium.yml build
script:
        - docker-compose -f docker-compose.selenium.yml up -d chrome_node proxy
        - docker container ls
        - docker-compose -f docker-compose.selenium.yml up protractor
特拉维斯·西失败了。输出为:

 - Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
  - Failed: Timed out waiting for asynchronous Angular tasks to finish after 60 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular
这很奇怪,因为我写道:

import { AppPage } from './app.po';

// Test bed
describe('workspace-project App', () => {
  let page: AppPage;

  beforeEach(() => {
    page = new AppPage();
  });

  it('should display navbar with title',  () => {
    page.navigateTo().then(() => {
      console.log('Successfully connected to the page');
    });

    expect(page.getHeaderText()).toEqual('hobbies');

  });
});
在Travis CI的日志中,日志打印出来:

已成功连接到该页。其余日志可在此处找到:


我不确定我做错了什么。真奇怪,我的本地机器通过了测试。我试图通过使用selenium/hub和selenium/node chrome图像以不同的方式解决这个问题,并将量角器连接到selenium服务器。这是同一个故事。我让它在本地机器上工作,但在TravisCI中失败了。我将在另一个问题中询问硒的问题

那么,添加如下等待是否会影响什么

import { AppPage } from './app.po';

// Test bed
describe('workspace-project App', () => {
  let page: AppPage;

  beforeEach(() => {
    page = new AppPage();
  });

  it('should display navbar with title',  () => {
    page.navigateTo().then(() => {
      console.log('Successfully connected to the page');
    });

browser.ignoreSynchronization = true

driver.wait(function () {
return driver.isElementPresent(page.getHeaderText('hobbies'));
}, timeout);

    expect(page.getHeaderText()).toEqual('hobbies');

    browser.ignoreSynchronization = false;

  });
});

我跟着C·派克的回答。我在我的本地机器上进行了测试,它工作了;但是,它在TravisCI中仍然不起作用,如我的日志所示:

我甚至将等待超时设置为11秒,测试仍然失败。然后,我将
量角器docker.conf.js
中的
allScriptsTimeout
增加到180000。完成此操作后,测试通过:


然而,测试花了2分10秒才完成。这是令人沮丧的,因为我只是检查标题是否出现在导航栏中。我担心如果我测试一些东西,比如表单和点击按钮,Travis CI可能需要更长的时间

终于解决了!!!因此,我找到了这个链接,并获得了一些灵感:

幸运的是,个人使用的配置几乎相同,但有趣的是,个人正在反向代理他们的web应用程序

我也这样做了:

#default.conf for proxy service

upstream docker-web {

    #docker angular container
    server angular:4200; 
}

upstream docker-node {

    #docker nodejs container
    server nodejs:3000;
}

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://docker-web;
        #proxy_redirect off; 
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;
        add_header         X-Upstream $upstream_addr;
    }

    location /api {
        proxy_pass http://docker-node;
        proxy_redirect off; 
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;
        add_header         X-Upstream $upstream_addr;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
对于我在nginx上托管的angular web应用程序:

server {
    listen       4200;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }



    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
我使用角度图像为量角器创建了一个单独的容器,我将提供:

###################
##    builder    ##
###################

FROM  node:10-alpine AS builder
RUN  mkdir -p /usr/src/frontend
WORKDIR /usr/src/frontend
COPY package.json /usr/src/frontend
RUN npm cache clean --force \
  && npm install
COPY . /usr/src/frontend
RUN npm run build -- --prod


##################
##  production  ##
##################

FROM nginx:alpine AS production
COPY --from=builder /usr/src/frontend/dist/frontend /usr/share/nginx/html
COPY --from=builder /usr/src/frontend/nginx/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

#################
## development ##
#################

# because development uses the same stuff from builder image
FROM builder AS development
EXPOSE 4200
CMD ["npm", "start"]


##################
##     test     ##
##################


# because test uses the same stuff from builder image
FROM builder AS test
RUN apk update && \
    apk upgrade && \
    apk add --no-cache chromium nss chromium-chromedriver
EXPOSE 9876
ENV CHROME_BIN /usr/bin/chromium-browser
# just needed the chromedriver!!!
# https://github.com/angular/angular-cli/issues/5019
# https://gitlab.com/dasch8/angular-ci/blob/master/README.md
CMD [ "npm", "run", "test", "--", "--no-watch", "--no-progress", "--browsers=ChromeHeadlessCI"]


FROM production
然后我创建了一个selenium网格服务和chrome节点服务。Docker Selenium的文档可在此处找到:

我的错误是主机名(docker compose文件中的容器/服务名)解析不正确,因为它们不在同一网络上。由于量角器连接到selenium,selenium处理E2E测试,
browser.get('http://proxy“)
找不到angular应用程序,因为Selenium与代理容器不在同一网络上。然后,我删除了docker compose文件中使用的所有网络,并创建了一个新的docker compose文件,其中包括我的selenium网格服务(称为selenium hub)、selenium/node chrome服务(称为chrome_node)、MEAN stack(angular、nodejs、db)和量角器服务(通过从docker文件中定位测试构建)

My docker-compose.selenium.yml文件:

version: "3.4"

services:
  # set up angular app
  angular:
    build: 
      context: ./frontend
      dockerfile: sample.Dockerfile
      target: test
    image: angular:test
    container_name: angular
    ports: 
      - "4200:4200"
    depends_on: 
      - nodejs 
    command: npm run e2e -- --protractor-config=e2e/protractor-docker.conf.js --host 0.0.0.0

  nodejs:
    build:
      context: ./backend
      dockerfile: Dockerfile
      target: development
    image: nodejs:dev
    container_name: nodejs
    ports: 
      - "3000:3000"
    networks:
      - backend
    depends_on: 
      - db
    restart: always
  # the mongo database
  db:
    image: mongo
    container_name: db
    networks: 
      - backend
    ports: 
      - "27017:27017"
networks: 
  backend: 
    driver: bridge
version: '3.4'

services:
  selenium-hub:
    image: selenium/hub:3.141.59
    container_name: selenium-hub
    environment: 
      - GRID_TIMEOUT=10000
    ports: 
      - "4444:4444"
    privileged: true
    #tty: true

  chrome_node:
    image: selenium/node-chrome:3.141.59
    volumes: 
      - /dev/shm:/dev/shm
    container_name: chrome_node
    environment:
      - HUB_PORT_4444_TCP_ADDR=selenium-hub
      - HUB_PORT_4444_TCP_PORT=4444
    ports:
      - "5555:5555"
    privileged: true
    depends_on:
      - selenium-hub
    #tty: true
  proxy: 
    build: 
      context: ./proxy
      dockerfile: Dockerfile
    image: proxy
    container_name: proxy
    # HOST:CONTAINER
    ports: 
      - "80:80"
    #tty: true
    depends_on: 
      - angular
  angular:
    build:
      context: ./frontend
      dockerfile: sample.Dockerfile
      target: production
    image: angular:prod
    container_name: angular
    ports:
      - "4200:4200"
    privileged: true 
    depends_on: 
        - nodejs
    #tty: true
  nodejs:
    build:
      context: ./backend
      dockerfile: Dockerfile
      target: development
    image: nodejs:dev
    container_name: nodejs
    ports: 
      - "3000:3000"
    depends_on: 
      - db
    restart: always
    #tty: true
  # the mongo database
  db:
    image: mongo
    container_name: db
    ports: 
      - "27017:27017"
    #tty: true
  protractor:
    build:
      context: ./frontend
      dockerfile: sample.Dockerfile
      target: test
    image: angular:test
    container_name: protractor
    ports: 
      - "9876:9876"
    privileged: true
    depends_on:
      - selenium-hub
      - chrome_node
    #tty: true --> not neccesary
    command: npm run e2e -- --protractor-config=e2e/protractor-ci.conf.js --webdriver-update=false --dev-server-target= 
这是我的新量角器配置文件:

let config = require('./protractor.conf').config;


// do not use the chromeDriver. If you do, it will not connect to Selenium service
config.directConnect = false;


// have it connect to the angular app
config.baseUrl = "http://proxy";

// Protractor getting the page-timeout
config.getPageTimeout = 60000;

// Selenium Webdriver timeout
config.allScriptsTimeout = 60000;

// Jasmine test script timeout
config.jasmineNodeOpts.defaultTimeoutInterval = 60000;

config.seleniumAddress = 'http://selenium-hub:4444/wd/hub'

config.capabilities = {
  browserName: 'chrome',
  chromeOptions: {
    args: ['--headless', '--disable-gpu', '--no-sandbox'],
  },
};
标志
--dev server target=
让我们知道不要启动ng serve(因为我们正在nginx中启动angular应用程序)。这样做之后,我的测试通过了!!!而且,我将超时设置为60000,测试在3秒内通过,这是一个很大的改进!!!!:)

我在.travis.yml中使用的脚本:

before_script: 
    - docker-compose -f docker-compose.test.yml build
  script:
    - docker-compose -f docker-compose.test.yml run --name angular -p 4200:4200 angular
before_script: 
        - docker-compose -f docker-compose.selenium.yml build
script:
        - docker-compose -f docker-compose.selenium.yml up -d chrome_node proxy
        - docker container ls
        - docker-compose -f docker-compose.selenium.yml up protractor
对于网络,
docker compose up
命令会自行处理,docker的DNS解析器将解析主机名(docker compose文件中的容器/服务名)。有关docker compose网络的更多信息,请参见docker文档:

以下是生成的日志:


我希望这对将来的任何人都有帮助:)

您是说容器中的E2E测试在您的机器上成功了,还是直接运行它们?当您在本地使用这些docker compose命令时会发生什么?容器中的E2E测试在我的机器上成功。当我在本地运行docker compose命令时,测试通过了@琼斯哈皮埃罗。我将所有超时值(config.allScriptsTimeout、config.getPageTimeout、config.jasmineNodeOpts.defaultTimeoutInterval)增加到180000毫秒。这样做使我的测试通过了Travis CI。但是,如果我遇到需要更长时间的测试,该怎么办?我需要猜测一个合适的超时时间来确保我的测试通过Travis CI吗?我建议仔细研究它到底在哪里失败,并在此之前添加一个动态等待。在你的测试中,它是否总是在同一点失败?@C.Peck是的,它总是在同一点失败。我也在考虑添加一个等待。我按照你的建议做了,但仍然出现超时错误。下面是我根据您的建议添加的代码的github repo:@C.PeckI会再尝试一件事:在操作之前关闭
waitforAngular()
,然后告诉它重新打开,注意
浏览器。忽略同步
行。有什么不同的结果吗?我已经克隆了你的项目,但要让它继续运行,还有很多设置要做。我建议删除我的.travis.yml中的加密行。Travis将停止,因为我使用Travis@C.PeckI对一些文件进行了加密。我现在遇到以下错误,我相信我已经安装了所有内容:
error:t错误:⨯ 无法编译TypeScript:错误TS2688:找不到“jasmine”的类型定义文件。错误TS2688:找不到“jasminewd2”的类型定义文件。错误TS2688:找不到“节点”的类型定义文件。
正如我担心的那样,当我尝试测试表单时,测试超时。它在我的本地机器上工作,但在Travis CIThis上超时这应该是不必要的,这是一个荒谬的长时间必须持续等待。我希望我能告诉你发生了什么,但这里显然有个问题。我也有同样的感觉,这些测试几乎让我毛骨悚然@佩奇瘦