angularjs - Protractor :测试 'busy indicator'/互联网连接速度慢的行为

标签 angularjs testing selenium-webdriver protractor end-to-end

如果 HTTP 请求花费的时间超过 1 秒,我会显示一个忙指示器。如果它在不到 1 秒内返回,则不会显示忙碌指示符。

用 Protractor 测试这个的最好方法是什么?我在想我需要两个测试用例:

it('should not show busy indicator because http response is quick', function () {
    // ??
});

it('should show busy indicator because http response is taking longer than 1 second', function () {
    // ??
});

最佳答案

实现此目的的一种方法是设置 Protractor 启动的浏览器使用的可配置代理服务器。该代理服务器可以为请求增加延迟,从而模拟缓慢的互联网连接/网络(或者至少模拟它足以满足您的目的)。

这样的代理服务器 + 迷你 API 使其可配置是这样的:

// proxy.js

// Config ports
var PROXY_PORT = 8001;
var CONFIG_PORT = 8002;

// Latency used for all requests
var latency = 0;

// Proxy
var hoxy = require('hoxy');
var proxy = new hoxy.Proxy();
proxy.intercept('request', function(req, resp) {
  req.slow({latency: latency}); 
});
proxy.listen(PROXY_PORT);

// API Server for tests to configure latency
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.post('/', function(req, res) {
  latency = req.body.latency;;
  res.send('');
});
app.listen(CONFIG_PORT);

上面请求npm包hoxyexpressbody-parser,每个都可以通过命令安装

npm install hoxy --save-dev

上面的服务器,假设它被保存到 proxy.js 可以在命令行上启动

node proxy.js

请注意,它在 2 个端口上监听:8001 用于一个简单的 HTTP 代理,它会增加请求的延迟,8002 用于一个简单的 API,它在 / 上监听,接受一个带有单个键的 JSON 对象: latency 以毫秒为单位减慢通过代理的所有后续请求。

要在 Protractor 中使用代理,您可以将其添加到其配置文件中,例如对于 Chrome,通过:

capabilities: {
  browserName: 'chrome',
  proxy: {
    proxyType: 'manual',
    httpProxy: 'localhost:8001'
  }
}

然后在您的规范文件中,您可以创建一个函数来设置后续请求的延迟

describe('My Component', function() {
  var http = require('http');

  function setLatency(latency) {
    return browser.controlFlow().execute(function () {
      var deferred = protractor.promise.defer();
      var data = JSON.stringify({latency:latency});
      var req = http.request({
        method: 'POST',
        host: 'localhost',
        port: 8002,
        headers: {
          'Content-Type': 'application/json',
          'Content-Length': data.length
        }
      }, function() {
        deferred.fulfill();
      });
      req.write(data);
      req.end();  
      return deferred.promise;
    });
  }
...

请注意,我们将代码添加到控制流中,并在设置延迟的请求完成后返回一个已解决的 promise 。这意味着我们可以以与其他 Protractor 元素查找器/期望相同的自然方式使用它,而无需使用手动 then 回调。

您的实际测试完全取决于您显示忙碌指示器的方式,但您应该能够执行如下操作:

it('should not show busy indicator because http response is quick', function () {
  setLatency(900);
  element(by.css('button')).click();
  browser.ignoreSynchronization = true;
  browser.sleep(500);
  expect(element(by.css('.loading-indicator')).isPresent()).not.toBe(true);
  browser.ignoreSynchronization = false;
  setLatency(0);
});

it('should show busy indicator because http response is taking longer than 1 second', function () {
  setLatency(2000);
  element(by.css('button')).click();
  browser.ignoreSynchronization = true;
  browser.sleep(1000);
  expect(element(by.css('.loading-indicator')).isPresent()).toBe(true);
  browser.ignoreSynchronization = false;
  setLatency(0);
});

上述测试并不完美。具体来说,繁忙指示器未显示的测试实际上并不表明它从未出现过。它只是测试它不会在 900 毫秒的请求中出现 500 毫秒。

注意 browser.ignoreSynchronization = false 的设置。如果我们不将它设置为 false,那么测试将不会进行,直到所有 $http 请求都完成,在这种情况下我们不想这样做,因为我们正在测试请求期间发生的行为。

关于angularjs - Protractor :测试 'busy indicator'/互联网连接速度慢的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27879924/

相关文章:

java - 是否可以在 selenium 测试中访问 java bean?

java - 打开循环中的每个链接(Selenium)

javascript - Angular 力矩 : Moment Timezone has no data for America/New_York

angularjs - Angular ui 路由器 : Parent & Child Views

javascript - Angularjs - 属性等于值

python - Django 测试 - 更新 View 不​​会更改数据库对象字段

javascript - 合并多个 Angular scope watch 语句

java - 使用 cssSelector 按文本选择嵌套元素 - Selenium WebDriver

angularjs - 在非 Angular 页面上使用 Protractor 测试登录

java - 在 Selenium WebDriver 中使用特定语言有好处吗?