@telefonica/acceptance-testing 2.8.0 → 2.10.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.
- package/README.md +49 -0
- package/dist/acceptance-testing.cjs.development.js +148 -39
- package/dist/acceptance-testing.cjs.development.js.map +1 -1
- package/dist/acceptance-testing.cjs.production.min.js +1 -1
- package/dist/acceptance-testing.cjs.production.min.js.map +1 -1
- package/dist/acceptance-testing.esm.js +147 -40
- package/dist/acceptance-testing.esm.js.map +1 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js.flow +10 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -106,3 +106,52 @@ you need a different jest config file name you can manually setup some scripts i
|
|
|
106
106
|
|
|
107
107
|
Just take into account that the `jest-environment-puppeteer` must always be configured in your jest config
|
|
108
108
|
file. Also note that tests run in UI mode by default, unless you set the `HEADLESS=1` env var.
|
|
109
|
+
|
|
110
|
+
## Intercepting requests
|
|
111
|
+
|
|
112
|
+
If you can intercept and mock requests in your acceptance tests you can use the `interceptRequest` function:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
import {openPage, screen, interceptRequest} from '@telefonica/acceptance-testing';
|
|
116
|
+
|
|
117
|
+
test('example screenshot test', async () => {
|
|
118
|
+
const imageSpy = interceptRequest((req) => req.url().endsWith('.jpg'));
|
|
119
|
+
|
|
120
|
+
imageSpy.mockReturnValue({
|
|
121
|
+
status: 200,
|
|
122
|
+
contentType: 'image/jpeg',
|
|
123
|
+
body: myMockedJpeg,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const page = await openPage({path: '/foo'});
|
|
127
|
+
|
|
128
|
+
expect(imageSpy).toHaveBeenCalled();
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
To mock JSON api endpoints you can use `interceptRequest` too, but we also provide a more conveninent api
|
|
133
|
+
wrapper over `interceptRequest`: `createApiEndpointMock`
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import {openPage, screen, createApiEndpointMock} from '@telefonica/acceptance-testing';
|
|
137
|
+
|
|
138
|
+
test('example screenshot test', async () => {
|
|
139
|
+
const api = createApiEndpointMock({basePath: 'https://my-api-endpoint.com'});
|
|
140
|
+
|
|
141
|
+
const getSpy = api.spyOn('/some-path').mockReturnValue({a: 1, b: 2});
|
|
142
|
+
const postSpy = api.spyOn('/other-path', 'POST').mockReturnValue({c: 3});
|
|
143
|
+
|
|
144
|
+
const page = await openPage({path: '/foo'});
|
|
145
|
+
|
|
146
|
+
expect(getSpy).toHaveBeenCalled();
|
|
147
|
+
|
|
148
|
+
await page.click(await screen.findByRole('button', {name: 'Send'}));
|
|
149
|
+
|
|
150
|
+
expect(postSpy).toHaveBeenCalled();
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`createApiEndpointMock` automatically mocks CORS response headers and preflight (`OPTIONS`) requests for you.
|
|
155
|
+
|
|
156
|
+
You can also use globs for paths if you need: `api.spyOn('/some/*/path')`. We use the
|
|
157
|
+
[`glob-to-regexp`](https://www.npmjs.com/package/glob-to-regexp) lib internally.
|
|
@@ -9,6 +9,7 @@ var fs = _interopDefault(require('fs'));
|
|
|
9
9
|
var findRoot = _interopDefault(require('find-root'));
|
|
10
10
|
var pptrTestingLibrary = require('pptr-testing-library');
|
|
11
11
|
var jestImageSnapshot = require('jest-image-snapshot');
|
|
12
|
+
var globToRegExp = _interopDefault(require('glob-to-regexp'));
|
|
12
13
|
|
|
13
14
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
14
15
|
try {
|
|
@@ -1044,17 +1045,22 @@ var getPageApi = function getPageApi(page) {
|
|
|
1044
1045
|
while (1) {
|
|
1045
1046
|
switch (_context5.prev = _context5.next) {
|
|
1046
1047
|
case 0:
|
|
1047
|
-
|
|
1048
|
+
if (options != null && options.skipNetworkWait) {
|
|
1049
|
+
_context5.next = 3;
|
|
1050
|
+
break;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
_context5.next = 3;
|
|
1048
1054
|
return page.waitForNetworkIdle();
|
|
1049
1055
|
|
|
1050
|
-
case
|
|
1051
|
-
_context5.next =
|
|
1056
|
+
case 3:
|
|
1057
|
+
_context5.next = 5;
|
|
1052
1058
|
return waitForPaintEnd(page, options);
|
|
1053
1059
|
|
|
1054
|
-
case
|
|
1060
|
+
case 5:
|
|
1055
1061
|
return _context5.abrupt("return", page.screenshot(normalizeSreenshotOptions(options)));
|
|
1056
1062
|
|
|
1057
|
-
case
|
|
1063
|
+
case 6:
|
|
1058
1064
|
case "end":
|
|
1059
1065
|
return _context5.stop();
|
|
1060
1066
|
}
|
|
@@ -1110,14 +1116,88 @@ var getPageApi = function getPageApi(page) {
|
|
|
1110
1116
|
|
|
1111
1117
|
return api;
|
|
1112
1118
|
};
|
|
1119
|
+
var needsRequestInterception = false;
|
|
1120
|
+
var requestHandlers = [];
|
|
1121
|
+
|
|
1122
|
+
var requestInterceptor = function requestInterceptor(req) {
|
|
1123
|
+
var _requestHandlers$find;
|
|
1124
|
+
|
|
1125
|
+
var _ref11 = (_requestHandlers$find = requestHandlers.find(function (_ref12) {
|
|
1126
|
+
var matcher = _ref12.matcher;
|
|
1127
|
+
return matcher(req);
|
|
1128
|
+
})) != null ? _requestHandlers$find : {
|
|
1129
|
+
handler: null
|
|
1130
|
+
},
|
|
1131
|
+
handler = _ref11.handler;
|
|
1132
|
+
|
|
1133
|
+
if (!handler) {
|
|
1134
|
+
req["continue"]();
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
var response = handler(req);
|
|
1139
|
+
req.respond(response);
|
|
1140
|
+
};
|
|
1141
|
+
|
|
1142
|
+
var interceptRequest = function interceptRequest(matcher) {
|
|
1143
|
+
needsRequestInterception = true;
|
|
1144
|
+
var spy = jest.fn();
|
|
1145
|
+
requestHandlers.push({
|
|
1146
|
+
matcher: matcher,
|
|
1147
|
+
handler: spy
|
|
1148
|
+
});
|
|
1149
|
+
return spy;
|
|
1150
|
+
};
|
|
1151
|
+
var createApiEndpointMock = function createApiEndpointMock(_ref13) {
|
|
1152
|
+
var baseUrl = _ref13.baseUrl;
|
|
1153
|
+
interceptRequest(function (req) {
|
|
1154
|
+
return req.method() === 'OPTIONS' && req.url().startsWith(baseUrl);
|
|
1155
|
+
}).mockImplementation(function () {
|
|
1156
|
+
return {
|
|
1157
|
+
status: 204,
|
|
1158
|
+
headers: {
|
|
1159
|
+
'Access-Control-Allow-Origin': '*',
|
|
1160
|
+
'Access-Control-Allow-Methods': 'POST,PATCH,PUT,GET,OPTIONS',
|
|
1161
|
+
'Access-Control-Allow-Headers': 'Content-Type,Authorization'
|
|
1162
|
+
}
|
|
1163
|
+
};
|
|
1164
|
+
});
|
|
1165
|
+
return {
|
|
1166
|
+
spyOn: function spyOn(path, method) {
|
|
1167
|
+
if (method === void 0) {
|
|
1168
|
+
method = 'GET';
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
var matcher = function matcher(req) {
|
|
1172
|
+
var url = req.url();
|
|
1173
|
+
var urlPath = url.substring(baseUrl.length);
|
|
1174
|
+
return req.method() === method && url.startsWith(baseUrl) && !!urlPath.match(globToRegExp(path));
|
|
1175
|
+
};
|
|
1176
|
+
|
|
1177
|
+
var spy = jest.fn();
|
|
1178
|
+
interceptRequest(matcher).mockImplementation(function (req) {
|
|
1179
|
+
var resBody = spy(req);
|
|
1180
|
+
return {
|
|
1181
|
+
status: 200,
|
|
1182
|
+
headers: {
|
|
1183
|
+
'Access-Control-Allow-Origin': '*'
|
|
1184
|
+
},
|
|
1185
|
+
contentType: 'application/json',
|
|
1186
|
+
body: JSON.stringify(resBody)
|
|
1187
|
+
};
|
|
1188
|
+
});
|
|
1189
|
+
return spy;
|
|
1190
|
+
}
|
|
1191
|
+
};
|
|
1192
|
+
};
|
|
1113
1193
|
var openPage = /*#__PURE__*/function () {
|
|
1114
|
-
var
|
|
1194
|
+
var _ref15 = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(_ref14) {
|
|
1115
1195
|
var userAgent, isDarkMode, viewport, cookies, urlConfig, url, currentUserAgent, page, connectionError;
|
|
1116
1196
|
return runtime_1.wrap(function _callee7$(_context7) {
|
|
1117
1197
|
while (1) {
|
|
1118
1198
|
switch (_context7.prev = _context7.next) {
|
|
1119
1199
|
case 0:
|
|
1120
|
-
userAgent =
|
|
1200
|
+
userAgent = _ref14.userAgent, isDarkMode = _ref14.isDarkMode, viewport = _ref14.viewport, cookies = _ref14.cookies, urlConfig = /*#__PURE__*/_objectWithoutPropertiesLoose(_ref14, _excluded2);
|
|
1121
1201
|
|
|
1122
1202
|
url = function () {
|
|
1123
1203
|
if (urlConfig.url !== undefined) {
|
|
@@ -1201,20 +1281,32 @@ var openPage = /*#__PURE__*/function () {
|
|
|
1201
1281
|
});
|
|
1202
1282
|
|
|
1203
1283
|
case 23:
|
|
1204
|
-
|
|
1284
|
+
if (!needsRequestInterception) {
|
|
1285
|
+
_context7.next = 27;
|
|
1286
|
+
break;
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1205
1289
|
_context7.next = 26;
|
|
1206
|
-
return page
|
|
1290
|
+
return page.setRequestInterception(true);
|
|
1207
1291
|
|
|
1208
1292
|
case 26:
|
|
1209
|
-
|
|
1293
|
+
page.on('request', requestInterceptor);
|
|
1294
|
+
|
|
1295
|
+
case 27:
|
|
1296
|
+
_context7.prev = 27;
|
|
1297
|
+
_context7.next = 30;
|
|
1298
|
+
return page["goto"](url);
|
|
1299
|
+
|
|
1300
|
+
case 30:
|
|
1301
|
+
_context7.next = 41;
|
|
1210
1302
|
break;
|
|
1211
1303
|
|
|
1212
|
-
case
|
|
1213
|
-
_context7.prev =
|
|
1214
|
-
_context7.t1 = _context7["catch"](
|
|
1304
|
+
case 32:
|
|
1305
|
+
_context7.prev = 32;
|
|
1306
|
+
_context7.t1 = _context7["catch"](27);
|
|
1215
1307
|
|
|
1216
1308
|
if (!_context7.t1.message.includes('net::ERR_CONNECTION_REFUSED')) {
|
|
1217
|
-
_context7.next =
|
|
1309
|
+
_context7.next = 40;
|
|
1218
1310
|
break;
|
|
1219
1311
|
}
|
|
1220
1312
|
|
|
@@ -1222,33 +1314,33 @@ var openPage = /*#__PURE__*/function () {
|
|
|
1222
1314
|
Error.captureStackTrace(connectionError, openPage);
|
|
1223
1315
|
throw connectionError;
|
|
1224
1316
|
|
|
1225
|
-
case
|
|
1317
|
+
case 40:
|
|
1226
1318
|
throw _context7.t1;
|
|
1227
1319
|
|
|
1228
|
-
case
|
|
1229
|
-
_context7.next =
|
|
1320
|
+
case 41:
|
|
1321
|
+
_context7.next = 43;
|
|
1230
1322
|
return page.waitForFunction('document.fonts.status === "loaded"');
|
|
1231
1323
|
|
|
1232
|
-
case
|
|
1324
|
+
case 43:
|
|
1233
1325
|
return _context7.abrupt("return", getPageApi(page));
|
|
1234
1326
|
|
|
1235
|
-
case
|
|
1327
|
+
case 44:
|
|
1236
1328
|
case "end":
|
|
1237
1329
|
return _context7.stop();
|
|
1238
1330
|
}
|
|
1239
1331
|
}
|
|
1240
|
-
}, _callee7, null, [[
|
|
1332
|
+
}, _callee7, null, [[27, 32]]);
|
|
1241
1333
|
}));
|
|
1242
1334
|
|
|
1243
1335
|
return function openPage(_x11) {
|
|
1244
|
-
return
|
|
1336
|
+
return _ref15.apply(this, arguments);
|
|
1245
1337
|
};
|
|
1246
1338
|
}();
|
|
1247
1339
|
|
|
1248
1340
|
var buildQueryMethods = function buildQueryMethods(_temp3) {
|
|
1249
|
-
var
|
|
1250
|
-
page =
|
|
1251
|
-
element =
|
|
1341
|
+
var _ref16 = _temp3 === void 0 ? {} : _temp3,
|
|
1342
|
+
page = _ref16.page,
|
|
1343
|
+
element = _ref16.element;
|
|
1252
1344
|
|
|
1253
1345
|
var boundQueries = {};
|
|
1254
1346
|
|
|
@@ -1306,24 +1398,29 @@ var buildQueryMethods = function buildQueryMethods(_temp3) {
|
|
|
1306
1398
|
newElementHandle = Object.create(elementHandle);
|
|
1307
1399
|
|
|
1308
1400
|
newElementHandle.screenshot = /*#__PURE__*/function () {
|
|
1309
|
-
var
|
|
1401
|
+
var _ref18 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(options) {
|
|
1310
1402
|
return runtime_1.wrap(function _callee8$(_context8) {
|
|
1311
1403
|
while (1) {
|
|
1312
1404
|
switch (_context8.prev = _context8.next) {
|
|
1313
1405
|
case 0:
|
|
1314
|
-
|
|
1406
|
+
if (options != null && options.skipNetworkWait) {
|
|
1407
|
+
_context8.next = 3;
|
|
1408
|
+
break;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
_context8.next = 3;
|
|
1315
1412
|
return (page != null ? page : getGlobalPage()).waitForNetworkIdle();
|
|
1316
1413
|
|
|
1317
|
-
case
|
|
1318
|
-
_context8.next =
|
|
1414
|
+
case 3:
|
|
1415
|
+
_context8.next = 5;
|
|
1319
1416
|
return waitForPaintEnd(elementHandle, _extends({}, options, {
|
|
1320
1417
|
fullPage: false
|
|
1321
1418
|
}));
|
|
1322
1419
|
|
|
1323
|
-
case
|
|
1420
|
+
case 5:
|
|
1324
1421
|
return _context8.abrupt("return", elementHandle.screenshot(normalizeSreenshotOptions(options)));
|
|
1325
1422
|
|
|
1326
|
-
case
|
|
1423
|
+
case 6:
|
|
1327
1424
|
case "end":
|
|
1328
1425
|
return _context8.stop();
|
|
1329
1426
|
}
|
|
@@ -1332,7 +1429,7 @@ var buildQueryMethods = function buildQueryMethods(_temp3) {
|
|
|
1332
1429
|
}));
|
|
1333
1430
|
|
|
1334
1431
|
return function (_x12) {
|
|
1335
|
-
return
|
|
1432
|
+
return _ref18.apply(this, arguments);
|
|
1336
1433
|
};
|
|
1337
1434
|
}();
|
|
1338
1435
|
|
|
@@ -1371,9 +1468,13 @@ beforeEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function
|
|
|
1371
1468
|
switch (_context10.prev = _context10.next) {
|
|
1372
1469
|
case 0:
|
|
1373
1470
|
_context10.next = 2;
|
|
1374
|
-
return
|
|
1471
|
+
return getGlobalPage().setRequestInterception(false);
|
|
1375
1472
|
|
|
1376
1473
|
case 2:
|
|
1474
|
+
_context10.next = 4;
|
|
1475
|
+
return global.jestPuppeteer.resetPage();
|
|
1476
|
+
|
|
1477
|
+
case 4:
|
|
1377
1478
|
case "end":
|
|
1378
1479
|
return _context10.stop();
|
|
1379
1480
|
}
|
|
@@ -1381,34 +1482,42 @@ beforeEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function
|
|
|
1381
1482
|
}, _callee10);
|
|
1382
1483
|
})));
|
|
1383
1484
|
afterEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee11() {
|
|
1485
|
+
var page;
|
|
1384
1486
|
return runtime_1.wrap(function _callee11$(_context11) {
|
|
1385
1487
|
while (1) {
|
|
1386
1488
|
switch (_context11.prev = _context11.next) {
|
|
1387
1489
|
case 0:
|
|
1388
1490
|
_context11.prev = 0;
|
|
1389
|
-
|
|
1390
|
-
|
|
1491
|
+
page = getGlobalPage();
|
|
1492
|
+
requestHandlers = [];
|
|
1493
|
+
needsRequestInterception = false;
|
|
1494
|
+
page.off('request', requestInterceptor); // clear tab, this way we clear the DOM and stop js execution or pending requests
|
|
1391
1495
|
|
|
1392
|
-
case 3:
|
|
1393
1496
|
_context11.next = 7;
|
|
1497
|
+
return page["goto"]('about:blank');
|
|
1498
|
+
|
|
1499
|
+
case 7:
|
|
1500
|
+
_context11.next = 11;
|
|
1394
1501
|
break;
|
|
1395
1502
|
|
|
1396
|
-
case
|
|
1397
|
-
_context11.prev =
|
|
1503
|
+
case 9:
|
|
1504
|
+
_context11.prev = 9;
|
|
1398
1505
|
_context11.t0 = _context11["catch"](0);
|
|
1399
1506
|
|
|
1400
|
-
case
|
|
1507
|
+
case 11:
|
|
1401
1508
|
case "end":
|
|
1402
1509
|
return _context11.stop();
|
|
1403
1510
|
}
|
|
1404
1511
|
}
|
|
1405
|
-
}, _callee11, null, [[0,
|
|
1512
|
+
}, _callee11, null, [[0, 9]]);
|
|
1406
1513
|
})));
|
|
1407
1514
|
|
|
1515
|
+
exports.createApiEndpointMock = createApiEndpointMock;
|
|
1408
1516
|
exports.getGlobalBrowser = getGlobalBrowser;
|
|
1409
1517
|
exports.getGlobalPage = getGlobalPage;
|
|
1410
1518
|
exports.getPageApi = getPageApi;
|
|
1411
1519
|
exports.getScreen = getScreen;
|
|
1520
|
+
exports.interceptRequest = interceptRequest;
|
|
1412
1521
|
exports.openPage = openPage;
|
|
1413
1522
|
exports.screen = screen;
|
|
1414
1523
|
exports.serverHostName = serverHostName;
|