@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.
package/README.md CHANGED
@@ -106,3 +106,63 @@ 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.
158
+
159
+ ## Uploading files
160
+
161
+ Due to a puppeteer bug or limitation, when the chromium is dockerized, the file to upload must exist in the
162
+ host and the container with the same path.
163
+
164
+ A helper function `prepareFile` is provided to facilitate this:
165
+
166
+ ```js
167
+ await elementHandle.uploadFile(prepareFile('/path/to/file'));
168
+ ```
@@ -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 {
@@ -812,6 +813,9 @@ var _excluded = ["captureBeyondViewport"],
812
813
  _excluded2 = ["userAgent", "isDarkMode", "viewport", "cookies"];
813
814
 
814
815
  var _pkg$acceptanceTests, _ref;
816
+
817
+ var execSync = /*#__PURE__*/require('child_process').execSync;
818
+
815
819
  var getGlobalBrowser = function getGlobalBrowser() {
816
820
  return global.browser;
817
821
  };
@@ -961,6 +965,18 @@ var normalizeSreenshotOptions = function normalizeSreenshotOptions(_temp2) {
961
965
  return _extends({}, options, {
962
966
  captureBeyondViewport: captureBeyondViewport
963
967
  });
968
+ }; // Puppeteer already calls scrollIntoViewIfNeeded before clicking an element. But it doesn't work in all situations
969
+ // For example, when there is a fixed footer in the page and the element to click is under it, the browser won't scroll
970
+ // because the element is already in the viewport (the ifNeeded part is important here). By forcing the scroll to the
971
+ // center, we manage to fix these edge cases.
972
+
973
+
974
+ var scrollIntoView = function scrollIntoView(el) {
975
+ return el.evaluate(function (e) {
976
+ return e.scrollIntoView({
977
+ block: 'center'
978
+ });
979
+ });
964
980
  };
965
981
 
966
982
  var getPageApi = function getPageApi(page) {
@@ -972,9 +988,13 @@ var getPageApi = function getPageApi(page) {
972
988
  while (1) {
973
989
  switch (_context2.prev = _context2.next) {
974
990
  case 0:
991
+ _context2.next = 2;
992
+ return scrollIntoView(elementHandle);
993
+
994
+ case 2:
975
995
  return _context2.abrupt("return", elementHandle.type(text, options));
976
996
 
977
- case 1:
997
+ case 3:
978
998
  case "end":
979
999
  return _context2.stop();
980
1000
  }
@@ -993,9 +1013,13 @@ var getPageApi = function getPageApi(page) {
993
1013
  while (1) {
994
1014
  switch (_context3.prev = _context3.next) {
995
1015
  case 0:
1016
+ _context3.next = 2;
1017
+ return scrollIntoView(elementHandle);
1018
+
1019
+ case 2:
996
1020
  return _context3.abrupt("return", elementHandle.click(options));
997
1021
 
998
- case 1:
1022
+ case 3:
999
1023
  case "end":
1000
1024
  return _context3.stop();
1001
1025
  }
@@ -1019,13 +1043,17 @@ var getPageApi = function getPageApi(page) {
1019
1043
  while (1) {
1020
1044
  switch (_context4.prev = _context4.next) {
1021
1045
  case 0:
1046
+ _context4.next = 2;
1047
+ return scrollIntoView(elementHandle);
1048
+
1049
+ case 2:
1022
1050
  for (_len = _args4.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1023
1051
  values[_key - 1] = _args4[_key];
1024
1052
  }
1025
1053
 
1026
1054
  return _context4.abrupt("return", elementHandle.select.apply(elementHandle, values));
1027
1055
 
1028
- case 2:
1056
+ case 4:
1029
1057
  case "end":
1030
1058
  return _context4.stop();
1031
1059
  }
@@ -1115,14 +1143,88 @@ var getPageApi = function getPageApi(page) {
1115
1143
 
1116
1144
  return api;
1117
1145
  };
1146
+ var needsRequestInterception = false;
1147
+ var requestHandlers = [];
1148
+
1149
+ var requestInterceptor = function requestInterceptor(req) {
1150
+ var _requestHandlers$find;
1151
+
1152
+ var _ref11 = (_requestHandlers$find = requestHandlers.find(function (_ref12) {
1153
+ var matcher = _ref12.matcher;
1154
+ return matcher(req);
1155
+ })) != null ? _requestHandlers$find : {
1156
+ handler: null
1157
+ },
1158
+ handler = _ref11.handler;
1159
+
1160
+ if (!handler) {
1161
+ req["continue"]();
1162
+ return;
1163
+ }
1164
+
1165
+ var response = handler(req);
1166
+ req.respond(response);
1167
+ };
1168
+
1169
+ var interceptRequest = function interceptRequest(matcher) {
1170
+ needsRequestInterception = true;
1171
+ var spy = jest.fn();
1172
+ requestHandlers.push({
1173
+ matcher: matcher,
1174
+ handler: spy
1175
+ });
1176
+ return spy;
1177
+ };
1178
+ var createApiEndpointMock = function createApiEndpointMock(_ref13) {
1179
+ var baseUrl = _ref13.baseUrl;
1180
+ interceptRequest(function (req) {
1181
+ return req.method() === 'OPTIONS' && req.url().startsWith(baseUrl);
1182
+ }).mockImplementation(function () {
1183
+ return {
1184
+ status: 204,
1185
+ headers: {
1186
+ 'Access-Control-Allow-Origin': '*',
1187
+ 'Access-Control-Allow-Methods': 'POST,PATCH,PUT,GET,OPTIONS',
1188
+ 'Access-Control-Allow-Headers': 'Content-Type,Authorization'
1189
+ }
1190
+ };
1191
+ });
1192
+ return {
1193
+ spyOn: function spyOn(path, method) {
1194
+ if (method === void 0) {
1195
+ method = 'GET';
1196
+ }
1197
+
1198
+ var matcher = function matcher(req) {
1199
+ var url = req.url();
1200
+ var urlPath = url.substring(baseUrl.length);
1201
+ return req.method() === method && url.startsWith(baseUrl) && !!urlPath.match(globToRegExp(path));
1202
+ };
1203
+
1204
+ var spy = jest.fn();
1205
+ interceptRequest(matcher).mockImplementation(function (req) {
1206
+ var resBody = spy(req);
1207
+ return {
1208
+ status: 200,
1209
+ headers: {
1210
+ 'Access-Control-Allow-Origin': '*'
1211
+ },
1212
+ contentType: 'application/json',
1213
+ body: JSON.stringify(resBody)
1214
+ };
1215
+ });
1216
+ return spy;
1217
+ }
1218
+ };
1219
+ };
1118
1220
  var openPage = /*#__PURE__*/function () {
1119
- var _ref12 = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(_ref11) {
1221
+ var _ref15 = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(_ref14) {
1120
1222
  var userAgent, isDarkMode, viewport, cookies, urlConfig, url, currentUserAgent, page, connectionError;
1121
1223
  return runtime_1.wrap(function _callee7$(_context7) {
1122
1224
  while (1) {
1123
1225
  switch (_context7.prev = _context7.next) {
1124
1226
  case 0:
1125
- userAgent = _ref11.userAgent, isDarkMode = _ref11.isDarkMode, viewport = _ref11.viewport, cookies = _ref11.cookies, urlConfig = /*#__PURE__*/_objectWithoutPropertiesLoose(_ref11, _excluded2);
1227
+ userAgent = _ref14.userAgent, isDarkMode = _ref14.isDarkMode, viewport = _ref14.viewport, cookies = _ref14.cookies, urlConfig = /*#__PURE__*/_objectWithoutPropertiesLoose(_ref14, _excluded2);
1126
1228
 
1127
1229
  url = function () {
1128
1230
  if (urlConfig.url !== undefined) {
@@ -1206,20 +1308,32 @@ var openPage = /*#__PURE__*/function () {
1206
1308
  });
1207
1309
 
1208
1310
  case 23:
1209
- _context7.prev = 23;
1311
+ if (!needsRequestInterception) {
1312
+ _context7.next = 27;
1313
+ break;
1314
+ }
1315
+
1210
1316
  _context7.next = 26;
1211
- return page["goto"](url);
1317
+ return page.setRequestInterception(true);
1212
1318
 
1213
1319
  case 26:
1214
- _context7.next = 37;
1320
+ page.on('request', requestInterceptor);
1321
+
1322
+ case 27:
1323
+ _context7.prev = 27;
1324
+ _context7.next = 30;
1325
+ return page["goto"](url);
1326
+
1327
+ case 30:
1328
+ _context7.next = 41;
1215
1329
  break;
1216
1330
 
1217
- case 28:
1218
- _context7.prev = 28;
1219
- _context7.t1 = _context7["catch"](23);
1331
+ case 32:
1332
+ _context7.prev = 32;
1333
+ _context7.t1 = _context7["catch"](27);
1220
1334
 
1221
1335
  if (!_context7.t1.message.includes('net::ERR_CONNECTION_REFUSED')) {
1222
- _context7.next = 36;
1336
+ _context7.next = 40;
1223
1337
  break;
1224
1338
  }
1225
1339
 
@@ -1227,33 +1341,33 @@ var openPage = /*#__PURE__*/function () {
1227
1341
  Error.captureStackTrace(connectionError, openPage);
1228
1342
  throw connectionError;
1229
1343
 
1230
- case 36:
1344
+ case 40:
1231
1345
  throw _context7.t1;
1232
1346
 
1233
- case 37:
1234
- _context7.next = 39;
1347
+ case 41:
1348
+ _context7.next = 43;
1235
1349
  return page.waitForFunction('document.fonts.status === "loaded"');
1236
1350
 
1237
- case 39:
1351
+ case 43:
1238
1352
  return _context7.abrupt("return", getPageApi(page));
1239
1353
 
1240
- case 40:
1354
+ case 44:
1241
1355
  case "end":
1242
1356
  return _context7.stop();
1243
1357
  }
1244
1358
  }
1245
- }, _callee7, null, [[23, 28]]);
1359
+ }, _callee7, null, [[27, 32]]);
1246
1360
  }));
1247
1361
 
1248
1362
  return function openPage(_x11) {
1249
- return _ref12.apply(this, arguments);
1363
+ return _ref15.apply(this, arguments);
1250
1364
  };
1251
1365
  }();
1252
1366
 
1253
1367
  var buildQueryMethods = function buildQueryMethods(_temp3) {
1254
- var _ref13 = _temp3 === void 0 ? {} : _temp3,
1255
- page = _ref13.page,
1256
- element = _ref13.element;
1368
+ var _ref16 = _temp3 === void 0 ? {} : _temp3,
1369
+ page = _ref16.page,
1370
+ element = _ref16.element;
1257
1371
 
1258
1372
  var boundQueries = {};
1259
1373
 
@@ -1261,7 +1375,7 @@ var buildQueryMethods = function buildQueryMethods(_temp3) {
1261
1375
  var _Object$entries$_i = _Object$entries[_i],
1262
1376
  queryName = _Object$entries$_i[0],
1263
1377
  queryFn = _Object$entries$_i[1];
1264
- boundQueries[queryName] = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9() {
1378
+ boundQueries[queryName] = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee12() {
1265
1379
  var doc,
1266
1380
  body,
1267
1381
  _len2,
@@ -1270,25 +1384,25 @@ var buildQueryMethods = function buildQueryMethods(_temp3) {
1270
1384
  queryArgs,
1271
1385
  elementHandle,
1272
1386
  newElementHandle,
1273
- _args9 = arguments;
1387
+ _args12 = arguments;
1274
1388
 
1275
- return runtime_1.wrap(function _callee9$(_context9) {
1389
+ return runtime_1.wrap(function _callee12$(_context12) {
1276
1390
  while (1) {
1277
- switch (_context9.prev = _context9.next) {
1391
+ switch (_context12.prev = _context12.next) {
1278
1392
  case 0:
1279
- _context9.next = 2;
1393
+ _context12.next = 2;
1280
1394
  return pptrTestingLibrary.getDocument(page != null ? page : getGlobalPage());
1281
1395
 
1282
1396
  case 2:
1283
- doc = _context9.sent;
1284
- _context9.next = 5;
1397
+ doc = _context12.sent;
1398
+ _context12.next = 5;
1285
1399
  return doc.$('body');
1286
1400
 
1287
1401
  case 5:
1288
- body = _context9.sent;
1402
+ body = _context12.sent;
1289
1403
 
1290
- for (_len2 = _args9.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
1291
- args[_key2] = _args9[_key2];
1404
+ for (_len2 = _args12.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
1405
+ args[_key2] = _args12[_key2];
1292
1406
  }
1293
1407
 
1294
1408
  queryArgs = [].concat(args);
@@ -1303,15 +1417,15 @@ var buildQueryMethods = function buildQueryMethods(_temp3) {
1303
1417
  });
1304
1418
  }
1305
1419
 
1306
- _context9.next = 11;
1420
+ _context12.next = 11;
1307
1421
  return queryFn.apply(void 0, [element != null ? element : body].concat(queryArgs));
1308
1422
 
1309
1423
  case 11:
1310
- elementHandle = _context9.sent;
1424
+ elementHandle = _context12.sent;
1311
1425
  newElementHandle = Object.create(elementHandle);
1312
1426
 
1313
1427
  newElementHandle.screenshot = /*#__PURE__*/function () {
1314
- var _ref15 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(options) {
1428
+ var _ref18 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(options) {
1315
1429
  return runtime_1.wrap(function _callee8$(_context8) {
1316
1430
  while (1) {
1317
1431
  switch (_context8.prev = _context8.next) {
@@ -1342,18 +1456,87 @@ var buildQueryMethods = function buildQueryMethods(_temp3) {
1342
1456
  }));
1343
1457
 
1344
1458
  return function (_x12) {
1345
- return _ref15.apply(this, arguments);
1459
+ return _ref18.apply(this, arguments);
1460
+ };
1461
+ }();
1462
+
1463
+ newElementHandle.click = /*#__PURE__*/function () {
1464
+ var _ref19 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9(options) {
1465
+ return runtime_1.wrap(function _callee9$(_context9) {
1466
+ while (1) {
1467
+ switch (_context9.prev = _context9.next) {
1468
+ case 0:
1469
+ _context9.next = 2;
1470
+ return scrollIntoView(elementHandle);
1471
+
1472
+ case 2:
1473
+ return _context9.abrupt("return", elementHandle.click(options));
1474
+
1475
+ case 3:
1476
+ case "end":
1477
+ return _context9.stop();
1478
+ }
1479
+ }
1480
+ }, _callee9);
1481
+ }));
1482
+
1483
+ return function (_x13) {
1484
+ return _ref19.apply(this, arguments);
1485
+ };
1486
+ }();
1487
+
1488
+ newElementHandle.type = /*#__PURE__*/function () {
1489
+ var _ref20 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee10(text, options) {
1490
+ return runtime_1.wrap(function _callee10$(_context10) {
1491
+ while (1) {
1492
+ switch (_context10.prev = _context10.next) {
1493
+ case 0:
1494
+ _context10.next = 2;
1495
+ return scrollIntoView(elementHandle);
1496
+
1497
+ case 2:
1498
+ return _context10.abrupt("return", elementHandle.type(text, options));
1499
+
1500
+ case 3:
1501
+ case "end":
1502
+ return _context10.stop();
1503
+ }
1504
+ }
1505
+ }, _callee10);
1506
+ }));
1507
+
1508
+ return function (_x14, _x15) {
1509
+ return _ref20.apply(this, arguments);
1346
1510
  };
1347
1511
  }();
1348
1512
 
1349
- return _context9.abrupt("return", newElementHandle);
1513
+ newElementHandle.select = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee11() {
1514
+ var _args11 = arguments;
1515
+ return runtime_1.wrap(function _callee11$(_context11) {
1516
+ while (1) {
1517
+ switch (_context11.prev = _context11.next) {
1518
+ case 0:
1519
+ _context11.next = 2;
1520
+ return scrollIntoView(elementHandle);
1521
+
1522
+ case 2:
1523
+ return _context11.abrupt("return", elementHandle.select.apply(elementHandle, _args11));
1524
+
1525
+ case 3:
1526
+ case "end":
1527
+ return _context11.stop();
1528
+ }
1529
+ }
1530
+ }, _callee11);
1531
+ }));
1532
+ return _context12.abrupt("return", newElementHandle);
1350
1533
 
1351
- case 15:
1534
+ case 18:
1352
1535
  case "end":
1353
- return _context9.stop();
1536
+ return _context12.stop();
1354
1537
  }
1355
1538
  }
1356
- }, _callee9);
1539
+ }, _callee12);
1357
1540
  }));
1358
1541
  };
1359
1542
 
@@ -1375,51 +1558,95 @@ var within = function within(element) {
1375
1558
  element: element
1376
1559
  });
1377
1560
  };
1378
- beforeEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee10() {
1379
- return runtime_1.wrap(function _callee10$(_context10) {
1561
+ beforeEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee13() {
1562
+ return runtime_1.wrap(function _callee13$(_context13) {
1380
1563
  while (1) {
1381
- switch (_context10.prev = _context10.next) {
1564
+ switch (_context13.prev = _context13.next) {
1382
1565
  case 0:
1383
- _context10.next = 2;
1384
- return global.jestPuppeteer.resetPage();
1566
+ _context13.next = 2;
1567
+ return getGlobalPage().setRequestInterception(false);
1385
1568
 
1386
1569
  case 2:
1570
+ _context13.next = 4;
1571
+ return global.jestPuppeteer.resetPage();
1572
+
1573
+ case 4:
1387
1574
  case "end":
1388
- return _context10.stop();
1575
+ return _context13.stop();
1389
1576
  }
1390
1577
  }
1391
- }, _callee10);
1578
+ }, _callee13);
1392
1579
  })));
1393
- afterEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee11() {
1394
- return runtime_1.wrap(function _callee11$(_context11) {
1580
+ afterEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee14() {
1581
+ var page;
1582
+ return runtime_1.wrap(function _callee14$(_context14) {
1395
1583
  while (1) {
1396
- switch (_context11.prev = _context11.next) {
1584
+ switch (_context14.prev = _context14.next) {
1397
1585
  case 0:
1398
- _context11.prev = 0;
1399
- _context11.next = 3;
1400
- return getGlobalPage()["goto"]('about:blank');
1586
+ _context14.prev = 0;
1587
+ page = getGlobalPage();
1588
+ requestHandlers = [];
1589
+ needsRequestInterception = false;
1590
+ page.off('request', requestInterceptor); // clear tab, this way we clear the DOM and stop js execution or pending requests
1591
+
1592
+ _context14.next = 7;
1593
+ return page["goto"]('about:blank');
1401
1594
 
1402
- case 3:
1403
- _context11.next = 7;
1595
+ case 7:
1596
+ _context14.next = 11;
1404
1597
  break;
1405
1598
 
1406
- case 5:
1407
- _context11.prev = 5;
1408
- _context11.t0 = _context11["catch"](0);
1599
+ case 9:
1600
+ _context14.prev = 9;
1601
+ _context14.t0 = _context14["catch"](0);
1409
1602
 
1410
- case 7:
1603
+ case 11:
1411
1604
  case "end":
1412
- return _context11.stop();
1605
+ return _context14.stop();
1413
1606
  }
1414
1607
  }
1415
- }, _callee11, null, [[0, 5]]);
1608
+ }, _callee14, null, [[0, 9]]);
1416
1609
  })));
1610
+ /**
1611
+ * Returns a new path to the file that can be used by chromium in acceptance tests
1612
+ *
1613
+ * To be able to use `element.uploadFile()` in a dockerized chromium, the file must exist in the
1614
+ * host and the docker, and both sides must use the same path.
1615
+ *
1616
+ * To workaround this bug or limitation, this function prepares the file by copying it to /tmp in
1617
+ * the host and the container.
1618
+ */
1619
+
1620
+ var prepareFile = function prepareFile(filepath) {
1621
+ var isLocal = !isCi;
1622
+ var isHeadless = !!process.env.HEADLESS;
1623
+ var usesDocker = isLocal && isHeadless;
1624
+ var dockerComposeFile = path.join(__dirname, '..', 'docker-compose.yaml');
1625
+
1626
+ if (usesDocker) {
1627
+ var containerId = execSync("docker-compose -f " + dockerComposeFile + " ps -q").toString().trim();
1628
+
1629
+ if (!containerId) {
1630
+ throw Error('acceptance-testing container not found');
1631
+ }
1632
+
1633
+ execSync("docker cp " + filepath + " " + containerId + ":/tmp");
1634
+ var newPath = path.join('/tmp', path.basename(filepath));
1635
+ fs.copyFileSync(filepath, newPath);
1636
+ return newPath;
1637
+ } else {
1638
+ return filepath;
1639
+ }
1640
+ };
1417
1641
 
1642
+ exports.createApiEndpointMock = createApiEndpointMock;
1418
1643
  exports.getGlobalBrowser = getGlobalBrowser;
1419
1644
  exports.getGlobalPage = getGlobalPage;
1420
1645
  exports.getPageApi = getPageApi;
1421
1646
  exports.getScreen = getScreen;
1647
+ exports.interceptRequest = interceptRequest;
1422
1648
  exports.openPage = openPage;
1649
+ exports.prepareFile = prepareFile;
1423
1650
  exports.screen = screen;
1424
1651
  exports.serverHostName = serverHostName;
1425
1652
  exports.serverPort = serverPort;