@tramvai/test-puppeteer 2.47.1 → 2.47.3

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/lib/index.d.ts CHANGED
@@ -2,3 +2,4 @@ export * from 'puppeteer';
2
2
  export * from './constants';
3
3
  export { initPuppeteer } from './launch';
4
4
  export { wrapPuppeteerPage } from './wrapper';
5
+ export * from './utils';
package/lib/index.es.js CHANGED
@@ -3,6 +3,7 @@ export * from 'puppeteer';
3
3
  import isEmpty from '@tinkoff/utils/is/empty';
4
4
  import { stderr } from 'supports-color';
5
5
  import consoleWithStyle from 'console-with-style';
6
+ import { sleep } from '@tramvai/test-integration';
6
7
 
7
8
  const PUPPETEER_DEFAULT_LAUNCH_OPTIONS = {
8
9
  args: [
@@ -43,6 +44,17 @@ const wrapRouter = (page) => {
43
44
  };
44
45
  };
45
46
 
47
+ // reference: https://github.com/vercel/next.js/blob/canary/packages/next/client/app-index.tsx#L162
48
+ const waitHydrated = (page) => {
49
+ return Promise.race([
50
+ page.waitForFunction(() => {
51
+ return (window.contextExternal &&
52
+ window.contextExternal.di.get({ token: '__TRAMVAI_HYDRATED', optional: true }));
53
+ }, { polling: 100 }),
54
+ sleep(10000),
55
+ ]);
56
+ };
57
+
46
58
  const checkSsrErrors = (text) => {
47
59
  if (text.indexOf('Server: "%s" Client: "%s"%s') !== -1) {
48
60
  throw new Error(`SSR breaking error: ${text}`);
@@ -54,6 +66,17 @@ const wrapPuppeteerPage = (page) => {
54
66
  if (page.url() && page.url() !== 'about:blank') {
55
67
  throw new Error(`You should wrap blank page before navigation, but page already has url "${page.url()}"`);
56
68
  }
69
+ const originalGoto = page.goto;
70
+ // wait for page loading and hydration, because selective hydration ends later
71
+ // eslint-disable-next-line no-param-reassign
72
+ page.goto = async function goto(...args) {
73
+ const [response] = await Promise.all([
74
+ originalGoto.apply(page, args),
75
+ page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
76
+ ]);
77
+ await waitHydrated(page);
78
+ return response;
79
+ };
57
80
  page.on('requestfailed', (request) => nativeConsole.error('[PAGE REQUEST FAILED]', {
58
81
  error: request.failure(),
59
82
  url: request.url(),
@@ -84,6 +107,11 @@ const wrapPuppeteerPage = (page) => {
84
107
  reset: (url = 'about:blank') => {
85
108
  return page.goto(url);
86
109
  },
110
+ waitForUrl: (url) => {
111
+ return page.waitForFunction((expectedUrl) => {
112
+ return window.location.href === expectedUrl;
113
+ }, {}, url);
114
+ },
87
115
  router: wrapRouter(page),
88
116
  close: () => {
89
117
  return page.close();
@@ -147,4 +175,4 @@ const initPuppeteer = async (serverUrl, { enableLogging = true, ...options } = {
147
175
  };
148
176
  };
149
177
 
150
- export { PUPPETEER_DEFAULT_LAUNCH_OPTIONS, initPuppeteer, wrapPuppeteerPage };
178
+ export { PUPPETEER_DEFAULT_LAUNCH_OPTIONS, initPuppeteer, waitHydrated, wrapPuppeteerPage };
package/lib/index.js CHANGED
@@ -6,6 +6,7 @@ var puppeteer = require('puppeteer');
6
6
  var isEmpty = require('@tinkoff/utils/is/empty');
7
7
  var supportsColor = require('supports-color');
8
8
  var consoleWithStyle = require('console-with-style');
9
+ var testIntegration = require('@tramvai/test-integration');
9
10
 
10
11
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11
12
 
@@ -52,6 +53,17 @@ const wrapRouter = (page) => {
52
53
  };
53
54
  };
54
55
 
56
+ // reference: https://github.com/vercel/next.js/blob/canary/packages/next/client/app-index.tsx#L162
57
+ const waitHydrated = (page) => {
58
+ return Promise.race([
59
+ page.waitForFunction(() => {
60
+ return (window.contextExternal &&
61
+ window.contextExternal.di.get({ token: '__TRAMVAI_HYDRATED', optional: true }));
62
+ }, { polling: 100 }),
63
+ testIntegration.sleep(10000),
64
+ ]);
65
+ };
66
+
55
67
  const checkSsrErrors = (text) => {
56
68
  if (text.indexOf('Server: "%s" Client: "%s"%s') !== -1) {
57
69
  throw new Error(`SSR breaking error: ${text}`);
@@ -63,6 +75,17 @@ const wrapPuppeteerPage = (page) => {
63
75
  if (page.url() && page.url() !== 'about:blank') {
64
76
  throw new Error(`You should wrap blank page before navigation, but page already has url "${page.url()}"`);
65
77
  }
78
+ const originalGoto = page.goto;
79
+ // wait for page loading and hydration, because selective hydration ends later
80
+ // eslint-disable-next-line no-param-reassign
81
+ page.goto = async function goto(...args) {
82
+ const [response] = await Promise.all([
83
+ originalGoto.apply(page, args),
84
+ page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
85
+ ]);
86
+ await waitHydrated(page);
87
+ return response;
88
+ };
66
89
  page.on('requestfailed', (request) => nativeConsole.error('[PAGE REQUEST FAILED]', {
67
90
  error: request.failure(),
68
91
  url: request.url(),
@@ -93,6 +116,11 @@ const wrapPuppeteerPage = (page) => {
93
116
  reset: (url = 'about:blank') => {
94
117
  return page.goto(url);
95
118
  },
119
+ waitForUrl: (url) => {
120
+ return page.waitForFunction((expectedUrl) => {
121
+ return window.location.href === expectedUrl;
122
+ }, {}, url);
123
+ },
96
124
  router: wrapRouter(page),
97
125
  close: () => {
98
126
  return page.close();
@@ -158,6 +186,7 @@ const initPuppeteer = async (serverUrl, { enableLogging = true, ...options } = {
158
186
 
159
187
  exports.PUPPETEER_DEFAULT_LAUNCH_OPTIONS = PUPPETEER_DEFAULT_LAUNCH_OPTIONS;
160
188
  exports.initPuppeteer = initPuppeteer;
189
+ exports.waitHydrated = waitHydrated;
161
190
  exports.wrapPuppeteerPage = wrapPuppeteerPage;
162
191
  Object.keys(puppeteer).forEach(function (k) {
163
192
  if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
package/lib/launch.d.ts CHANGED
@@ -9,6 +9,7 @@ export declare const initPuppeteer: (serverUrl: string, { enableLogging, ...opti
9
9
  getPageWrapper: (url?: string) => Promise<{
10
10
  page: puppeteer.Page;
11
11
  reset: (url?: string) => Promise<puppeteer.HTTPResponse | null>;
12
+ waitForUrl: (url: string) => Promise<puppeteer.JSHandle<false> | puppeteer.JSHandle<true>>;
12
13
  router: {
13
14
  navigate: (options: string | import("@tinkoff/router").NavigateOptions) => Promise<any>;
14
15
  navigateThenWaitForReload: (options: string | import("@tinkoff/router").NavigateOptions) => Promise<[void, puppeteer.HTTPResponse | null]>;
package/lib/utils.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { Page } from 'puppeteer';
2
+ export declare const waitHydrated: (page: Page) => Promise<unknown>;
package/lib/wrapper.d.ts CHANGED
@@ -5,6 +5,7 @@ declare global {
5
5
  export declare const wrapPuppeteerPage: (page: Page) => {
6
6
  page: Page;
7
7
  reset: (url?: string) => Promise<import("puppeteer").HTTPResponse | null>;
8
+ waitForUrl: (url: string) => Promise<import("puppeteer").JSHandle<false> | import("puppeteer").JSHandle<true>>;
8
9
  router: {
9
10
  navigate: (options: string | import("@tinkoff/router").NavigateOptions) => Promise<any>;
10
11
  navigateThenWaitForReload: (options: string | import("@tinkoff/router").NavigateOptions) => Promise<[void, import("puppeteer").HTTPResponse | null]>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tramvai/test-puppeteer",
3
- "version": "2.47.1",
3
+ "version": "2.47.3",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -19,7 +19,8 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@tinkoff/utils": "^2.1.2",
22
- "@tramvai/tokens-router": "2.47.1",
22
+ "@tramvai/tokens-router": "2.47.3",
23
+ "@tramvai/test-integration": "2.47.3",
23
24
  "console-with-style": "^1.1.0",
24
25
  "supports-color": "8.1.1",
25
26
  "tslib": "^2.4.0"