@telefonica/acceptance-testing 2.9.1 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,7 @@ import fs from 'fs';
3
3
  import findRoot from 'find-root';
4
4
  import { queries, getDocument } from 'pptr-testing-library';
5
5
  import { configureToMatchImageSnapshot } from 'jest-image-snapshot';
6
+ import globToRegExp from 'glob-to-regexp';
6
7
 
7
8
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
8
9
  try {
@@ -806,6 +807,9 @@ var _excluded = ["captureBeyondViewport"],
806
807
  _excluded2 = ["userAgent", "isDarkMode", "viewport", "cookies"];
807
808
 
808
809
  var _pkg$acceptanceTests, _ref;
810
+
811
+ var execSync = /*#__PURE__*/require('child_process').execSync;
812
+
809
813
  var getGlobalBrowser = function getGlobalBrowser() {
810
814
  return global.browser;
811
815
  };
@@ -955,6 +959,18 @@ var normalizeSreenshotOptions = function normalizeSreenshotOptions(_temp2) {
955
959
  return _extends({}, options, {
956
960
  captureBeyondViewport: captureBeyondViewport
957
961
  });
962
+ }; // Puppeteer already calls scrollIntoViewIfNeeded before clicking an element. But it doesn't work in all situations
963
+ // For example, when there is a fixed footer in the page and the element to click is under it, the browser won't scroll
964
+ // because the element is already in the viewport (the ifNeeded part is important here). By forcing the scroll to the
965
+ // center, we manage to fix these edge cases.
966
+
967
+
968
+ var scrollIntoView = function scrollIntoView(el) {
969
+ return el.evaluate(function (e) {
970
+ return e.scrollIntoView({
971
+ block: 'center'
972
+ });
973
+ });
958
974
  };
959
975
 
960
976
  var getPageApi = function getPageApi(page) {
@@ -966,9 +982,13 @@ var getPageApi = function getPageApi(page) {
966
982
  while (1) {
967
983
  switch (_context2.prev = _context2.next) {
968
984
  case 0:
985
+ _context2.next = 2;
986
+ return scrollIntoView(elementHandle);
987
+
988
+ case 2:
969
989
  return _context2.abrupt("return", elementHandle.type(text, options));
970
990
 
971
- case 1:
991
+ case 3:
972
992
  case "end":
973
993
  return _context2.stop();
974
994
  }
@@ -987,9 +1007,13 @@ var getPageApi = function getPageApi(page) {
987
1007
  while (1) {
988
1008
  switch (_context3.prev = _context3.next) {
989
1009
  case 0:
1010
+ _context3.next = 2;
1011
+ return scrollIntoView(elementHandle);
1012
+
1013
+ case 2:
990
1014
  return _context3.abrupt("return", elementHandle.click(options));
991
1015
 
992
- case 1:
1016
+ case 3:
993
1017
  case "end":
994
1018
  return _context3.stop();
995
1019
  }
@@ -1013,13 +1037,17 @@ var getPageApi = function getPageApi(page) {
1013
1037
  while (1) {
1014
1038
  switch (_context4.prev = _context4.next) {
1015
1039
  case 0:
1040
+ _context4.next = 2;
1041
+ return scrollIntoView(elementHandle);
1042
+
1043
+ case 2:
1016
1044
  for (_len = _args4.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1017
1045
  values[_key - 1] = _args4[_key];
1018
1046
  }
1019
1047
 
1020
1048
  return _context4.abrupt("return", elementHandle.select.apply(elementHandle, values));
1021
1049
 
1022
- case 2:
1050
+ case 4:
1023
1051
  case "end":
1024
1052
  return _context4.stop();
1025
1053
  }
@@ -1109,14 +1137,88 @@ var getPageApi = function getPageApi(page) {
1109
1137
 
1110
1138
  return api;
1111
1139
  };
1140
+ var needsRequestInterception = false;
1141
+ var requestHandlers = [];
1142
+
1143
+ var requestInterceptor = function requestInterceptor(req) {
1144
+ var _requestHandlers$find;
1145
+
1146
+ var _ref11 = (_requestHandlers$find = requestHandlers.find(function (_ref12) {
1147
+ var matcher = _ref12.matcher;
1148
+ return matcher(req);
1149
+ })) != null ? _requestHandlers$find : {
1150
+ handler: null
1151
+ },
1152
+ handler = _ref11.handler;
1153
+
1154
+ if (!handler) {
1155
+ req["continue"]();
1156
+ return;
1157
+ }
1158
+
1159
+ var response = handler(req);
1160
+ req.respond(response);
1161
+ };
1162
+
1163
+ var interceptRequest = function interceptRequest(matcher) {
1164
+ needsRequestInterception = true;
1165
+ var spy = jest.fn();
1166
+ requestHandlers.push({
1167
+ matcher: matcher,
1168
+ handler: spy
1169
+ });
1170
+ return spy;
1171
+ };
1172
+ var createApiEndpointMock = function createApiEndpointMock(_ref13) {
1173
+ var baseUrl = _ref13.baseUrl;
1174
+ interceptRequest(function (req) {
1175
+ return req.method() === 'OPTIONS' && req.url().startsWith(baseUrl);
1176
+ }).mockImplementation(function () {
1177
+ return {
1178
+ status: 204,
1179
+ headers: {
1180
+ 'Access-Control-Allow-Origin': '*',
1181
+ 'Access-Control-Allow-Methods': 'POST,PATCH,PUT,GET,OPTIONS',
1182
+ 'Access-Control-Allow-Headers': 'Content-Type,Authorization'
1183
+ }
1184
+ };
1185
+ });
1186
+ return {
1187
+ spyOn: function spyOn(path, method) {
1188
+ if (method === void 0) {
1189
+ method = 'GET';
1190
+ }
1191
+
1192
+ var matcher = function matcher(req) {
1193
+ var url = req.url();
1194
+ var urlPath = url.substring(baseUrl.length);
1195
+ return req.method() === method && url.startsWith(baseUrl) && !!urlPath.match(globToRegExp(path));
1196
+ };
1197
+
1198
+ var spy = jest.fn();
1199
+ interceptRequest(matcher).mockImplementation(function (req) {
1200
+ var resBody = spy(req);
1201
+ return {
1202
+ status: 200,
1203
+ headers: {
1204
+ 'Access-Control-Allow-Origin': '*'
1205
+ },
1206
+ contentType: 'application/json',
1207
+ body: JSON.stringify(resBody)
1208
+ };
1209
+ });
1210
+ return spy;
1211
+ }
1212
+ };
1213
+ };
1112
1214
  var openPage = /*#__PURE__*/function () {
1113
- var _ref12 = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(_ref11) {
1215
+ var _ref15 = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(_ref14) {
1114
1216
  var userAgent, isDarkMode, viewport, cookies, urlConfig, url, currentUserAgent, page, connectionError;
1115
1217
  return runtime_1.wrap(function _callee7$(_context7) {
1116
1218
  while (1) {
1117
1219
  switch (_context7.prev = _context7.next) {
1118
1220
  case 0:
1119
- userAgent = _ref11.userAgent, isDarkMode = _ref11.isDarkMode, viewport = _ref11.viewport, cookies = _ref11.cookies, urlConfig = /*#__PURE__*/_objectWithoutPropertiesLoose(_ref11, _excluded2);
1221
+ userAgent = _ref14.userAgent, isDarkMode = _ref14.isDarkMode, viewport = _ref14.viewport, cookies = _ref14.cookies, urlConfig = /*#__PURE__*/_objectWithoutPropertiesLoose(_ref14, _excluded2);
1120
1222
 
1121
1223
  url = function () {
1122
1224
  if (urlConfig.url !== undefined) {
@@ -1200,20 +1302,32 @@ var openPage = /*#__PURE__*/function () {
1200
1302
  });
1201
1303
 
1202
1304
  case 23:
1203
- _context7.prev = 23;
1305
+ if (!needsRequestInterception) {
1306
+ _context7.next = 27;
1307
+ break;
1308
+ }
1309
+
1204
1310
  _context7.next = 26;
1205
- return page["goto"](url);
1311
+ return page.setRequestInterception(true);
1206
1312
 
1207
1313
  case 26:
1208
- _context7.next = 37;
1314
+ page.on('request', requestInterceptor);
1315
+
1316
+ case 27:
1317
+ _context7.prev = 27;
1318
+ _context7.next = 30;
1319
+ return page["goto"](url);
1320
+
1321
+ case 30:
1322
+ _context7.next = 41;
1209
1323
  break;
1210
1324
 
1211
- case 28:
1212
- _context7.prev = 28;
1213
- _context7.t1 = _context7["catch"](23);
1325
+ case 32:
1326
+ _context7.prev = 32;
1327
+ _context7.t1 = _context7["catch"](27);
1214
1328
 
1215
1329
  if (!_context7.t1.message.includes('net::ERR_CONNECTION_REFUSED')) {
1216
- _context7.next = 36;
1330
+ _context7.next = 40;
1217
1331
  break;
1218
1332
  }
1219
1333
 
@@ -1221,33 +1335,33 @@ var openPage = /*#__PURE__*/function () {
1221
1335
  Error.captureStackTrace(connectionError, openPage);
1222
1336
  throw connectionError;
1223
1337
 
1224
- case 36:
1338
+ case 40:
1225
1339
  throw _context7.t1;
1226
1340
 
1227
- case 37:
1228
- _context7.next = 39;
1341
+ case 41:
1342
+ _context7.next = 43;
1229
1343
  return page.waitForFunction('document.fonts.status === "loaded"');
1230
1344
 
1231
- case 39:
1345
+ case 43:
1232
1346
  return _context7.abrupt("return", getPageApi(page));
1233
1347
 
1234
- case 40:
1348
+ case 44:
1235
1349
  case "end":
1236
1350
  return _context7.stop();
1237
1351
  }
1238
1352
  }
1239
- }, _callee7, null, [[23, 28]]);
1353
+ }, _callee7, null, [[27, 32]]);
1240
1354
  }));
1241
1355
 
1242
1356
  return function openPage(_x11) {
1243
- return _ref12.apply(this, arguments);
1357
+ return _ref15.apply(this, arguments);
1244
1358
  };
1245
1359
  }();
1246
1360
 
1247
1361
  var buildQueryMethods = function buildQueryMethods(_temp3) {
1248
- var _ref13 = _temp3 === void 0 ? {} : _temp3,
1249
- page = _ref13.page,
1250
- element = _ref13.element;
1362
+ var _ref16 = _temp3 === void 0 ? {} : _temp3,
1363
+ page = _ref16.page,
1364
+ element = _ref16.element;
1251
1365
 
1252
1366
  var boundQueries = {};
1253
1367
 
@@ -1255,7 +1369,7 @@ var buildQueryMethods = function buildQueryMethods(_temp3) {
1255
1369
  var _Object$entries$_i = _Object$entries[_i],
1256
1370
  queryName = _Object$entries$_i[0],
1257
1371
  queryFn = _Object$entries$_i[1];
1258
- boundQueries[queryName] = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9() {
1372
+ boundQueries[queryName] = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee12() {
1259
1373
  var doc,
1260
1374
  body,
1261
1375
  _len2,
@@ -1264,25 +1378,25 @@ var buildQueryMethods = function buildQueryMethods(_temp3) {
1264
1378
  queryArgs,
1265
1379
  elementHandle,
1266
1380
  newElementHandle,
1267
- _args9 = arguments;
1381
+ _args12 = arguments;
1268
1382
 
1269
- return runtime_1.wrap(function _callee9$(_context9) {
1383
+ return runtime_1.wrap(function _callee12$(_context12) {
1270
1384
  while (1) {
1271
- switch (_context9.prev = _context9.next) {
1385
+ switch (_context12.prev = _context12.next) {
1272
1386
  case 0:
1273
- _context9.next = 2;
1387
+ _context12.next = 2;
1274
1388
  return getDocument(page != null ? page : getGlobalPage());
1275
1389
 
1276
1390
  case 2:
1277
- doc = _context9.sent;
1278
- _context9.next = 5;
1391
+ doc = _context12.sent;
1392
+ _context12.next = 5;
1279
1393
  return doc.$('body');
1280
1394
 
1281
1395
  case 5:
1282
- body = _context9.sent;
1396
+ body = _context12.sent;
1283
1397
 
1284
- for (_len2 = _args9.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
1285
- args[_key2] = _args9[_key2];
1398
+ for (_len2 = _args12.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
1399
+ args[_key2] = _args12[_key2];
1286
1400
  }
1287
1401
 
1288
1402
  queryArgs = [].concat(args);
@@ -1297,15 +1411,15 @@ var buildQueryMethods = function buildQueryMethods(_temp3) {
1297
1411
  });
1298
1412
  }
1299
1413
 
1300
- _context9.next = 11;
1414
+ _context12.next = 11;
1301
1415
  return queryFn.apply(void 0, [element != null ? element : body].concat(queryArgs));
1302
1416
 
1303
1417
  case 11:
1304
- elementHandle = _context9.sent;
1418
+ elementHandle = _context12.sent;
1305
1419
  newElementHandle = Object.create(elementHandle);
1306
1420
 
1307
1421
  newElementHandle.screenshot = /*#__PURE__*/function () {
1308
- var _ref15 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(options) {
1422
+ var _ref18 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(options) {
1309
1423
  return runtime_1.wrap(function _callee8$(_context8) {
1310
1424
  while (1) {
1311
1425
  switch (_context8.prev = _context8.next) {
@@ -1336,18 +1450,87 @@ var buildQueryMethods = function buildQueryMethods(_temp3) {
1336
1450
  }));
1337
1451
 
1338
1452
  return function (_x12) {
1339
- return _ref15.apply(this, arguments);
1453
+ return _ref18.apply(this, arguments);
1454
+ };
1455
+ }();
1456
+
1457
+ newElementHandle.click = /*#__PURE__*/function () {
1458
+ var _ref19 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9(options) {
1459
+ return runtime_1.wrap(function _callee9$(_context9) {
1460
+ while (1) {
1461
+ switch (_context9.prev = _context9.next) {
1462
+ case 0:
1463
+ _context9.next = 2;
1464
+ return scrollIntoView(elementHandle);
1465
+
1466
+ case 2:
1467
+ return _context9.abrupt("return", elementHandle.click(options));
1468
+
1469
+ case 3:
1470
+ case "end":
1471
+ return _context9.stop();
1472
+ }
1473
+ }
1474
+ }, _callee9);
1475
+ }));
1476
+
1477
+ return function (_x13) {
1478
+ return _ref19.apply(this, arguments);
1479
+ };
1480
+ }();
1481
+
1482
+ newElementHandle.type = /*#__PURE__*/function () {
1483
+ var _ref20 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee10(text, options) {
1484
+ return runtime_1.wrap(function _callee10$(_context10) {
1485
+ while (1) {
1486
+ switch (_context10.prev = _context10.next) {
1487
+ case 0:
1488
+ _context10.next = 2;
1489
+ return scrollIntoView(elementHandle);
1490
+
1491
+ case 2:
1492
+ return _context10.abrupt("return", elementHandle.type(text, options));
1493
+
1494
+ case 3:
1495
+ case "end":
1496
+ return _context10.stop();
1497
+ }
1498
+ }
1499
+ }, _callee10);
1500
+ }));
1501
+
1502
+ return function (_x14, _x15) {
1503
+ return _ref20.apply(this, arguments);
1340
1504
  };
1341
1505
  }();
1342
1506
 
1343
- return _context9.abrupt("return", newElementHandle);
1507
+ newElementHandle.select = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee11() {
1508
+ var _args11 = arguments;
1509
+ return runtime_1.wrap(function _callee11$(_context11) {
1510
+ while (1) {
1511
+ switch (_context11.prev = _context11.next) {
1512
+ case 0:
1513
+ _context11.next = 2;
1514
+ return scrollIntoView(elementHandle);
1515
+
1516
+ case 2:
1517
+ return _context11.abrupt("return", elementHandle.select.apply(elementHandle, _args11));
1518
+
1519
+ case 3:
1520
+ case "end":
1521
+ return _context11.stop();
1522
+ }
1523
+ }
1524
+ }, _callee11);
1525
+ }));
1526
+ return _context12.abrupt("return", newElementHandle);
1344
1527
 
1345
- case 15:
1528
+ case 18:
1346
1529
  case "end":
1347
- return _context9.stop();
1530
+ return _context12.stop();
1348
1531
  }
1349
1532
  }
1350
- }, _callee9);
1533
+ }, _callee12);
1351
1534
  }));
1352
1535
  };
1353
1536
 
@@ -1369,45 +1552,86 @@ var within = function within(element) {
1369
1552
  element: element
1370
1553
  });
1371
1554
  };
1372
- beforeEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee10() {
1373
- return runtime_1.wrap(function _callee10$(_context10) {
1555
+ beforeEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee13() {
1556
+ return runtime_1.wrap(function _callee13$(_context13) {
1374
1557
  while (1) {
1375
- switch (_context10.prev = _context10.next) {
1558
+ switch (_context13.prev = _context13.next) {
1376
1559
  case 0:
1377
- _context10.next = 2;
1378
- return global.jestPuppeteer.resetPage();
1560
+ _context13.next = 2;
1561
+ return getGlobalPage().setRequestInterception(false);
1379
1562
 
1380
1563
  case 2:
1564
+ _context13.next = 4;
1565
+ return global.jestPuppeteer.resetPage();
1566
+
1567
+ case 4:
1381
1568
  case "end":
1382
- return _context10.stop();
1569
+ return _context13.stop();
1383
1570
  }
1384
1571
  }
1385
- }, _callee10);
1572
+ }, _callee13);
1386
1573
  })));
1387
- afterEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee11() {
1388
- return runtime_1.wrap(function _callee11$(_context11) {
1574
+ afterEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee14() {
1575
+ var page;
1576
+ return runtime_1.wrap(function _callee14$(_context14) {
1389
1577
  while (1) {
1390
- switch (_context11.prev = _context11.next) {
1578
+ switch (_context14.prev = _context14.next) {
1391
1579
  case 0:
1392
- _context11.prev = 0;
1393
- _context11.next = 3;
1394
- return getGlobalPage()["goto"]('about:blank');
1580
+ _context14.prev = 0;
1581
+ page = getGlobalPage();
1582
+ requestHandlers = [];
1583
+ needsRequestInterception = false;
1584
+ page.off('request', requestInterceptor); // clear tab, this way we clear the DOM and stop js execution or pending requests
1585
+
1586
+ _context14.next = 7;
1587
+ return page["goto"]('about:blank');
1395
1588
 
1396
- case 3:
1397
- _context11.next = 7;
1589
+ case 7:
1590
+ _context14.next = 11;
1398
1591
  break;
1399
1592
 
1400
- case 5:
1401
- _context11.prev = 5;
1402
- _context11.t0 = _context11["catch"](0);
1593
+ case 9:
1594
+ _context14.prev = 9;
1595
+ _context14.t0 = _context14["catch"](0);
1403
1596
 
1404
- case 7:
1597
+ case 11:
1405
1598
  case "end":
1406
- return _context11.stop();
1599
+ return _context14.stop();
1407
1600
  }
1408
1601
  }
1409
- }, _callee11, null, [[0, 5]]);
1602
+ }, _callee14, null, [[0, 9]]);
1410
1603
  })));
1604
+ /**
1605
+ * Returns a new path to the file that can be used by chromium in acceptance tests
1606
+ *
1607
+ * To be able to use `element.uploadFile()` in a dockerized chromium, the file must exist in the
1608
+ * host and the docker, and both sides must use the same path.
1609
+ *
1610
+ * To workaround this bug or limitation, this function prepares the file by copying it to /tmp in
1611
+ * the host and the container.
1612
+ */
1613
+
1614
+ var prepareFile = function prepareFile(filepath) {
1615
+ var isLocal = !isCi;
1616
+ var isHeadless = !!process.env.HEADLESS;
1617
+ var usesDocker = isLocal && isHeadless;
1618
+ var dockerComposeFile = path.join(__dirname, '..', 'docker-compose.yaml');
1619
+
1620
+ if (usesDocker) {
1621
+ var containerId = execSync("docker-compose -f " + dockerComposeFile + " ps -q").toString().trim();
1622
+
1623
+ if (!containerId) {
1624
+ throw Error('acceptance-testing container not found');
1625
+ }
1626
+
1627
+ execSync("docker cp " + filepath + " " + containerId + ":/tmp");
1628
+ var newPath = path.join('/tmp', path.basename(filepath));
1629
+ fs.copyFileSync(filepath, newPath);
1630
+ return newPath;
1631
+ } else {
1632
+ return filepath;
1633
+ }
1634
+ };
1411
1635
 
1412
- export { getGlobalBrowser, getGlobalPage, getPageApi, getScreen, openPage, screen, serverHostName, serverPort, within };
1636
+ export { createApiEndpointMock, getGlobalBrowser, getGlobalPage, getPageApi, getScreen, interceptRequest, openPage, prepareFile, screen, serverHostName, serverPort, within };
1413
1637
  //# sourceMappingURL=acceptance-testing.esm.js.map