next-page-tester
Version:
Enable DOM integration testing on Next.js pages
113 lines (112 loc) • 5.02 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importDefault(require("react"));
const fetchDocumentData_1 = __importDefault(require("./fetchDocumentData"));
const constants_1 = require("../constants");
const server_1 = require("react-dom/server");
const head_manager_context_1 = require("next/dist/shared/lib/head-manager-context");
const _app_1 = require("../_app");
const server_2 = require("../server");
// Copied from next.js
// https://github.com/vercel/next.js/blob/b944b06f30322076ceb9020c10cb9bf3448d2659/packages/next/next-server/server/render.tsx#L127
// Now in: https://github.com/vercel/next.js/blob/v11.1.0/packages/next/server/render.tsx#L138
function enhanceComponents(options, App, Component) {
// For backwards compatibility
if (typeof options === 'function') {
return {
App,
Component: options(Component),
};
}
return {
App: options.enhanceApp ? options.enhanceApp(App) : App,
Component: options.enhanceComponent
? options.enhanceComponent(Component)
: Component,
};
}
async function serverRenderDocument({ options, appProps, pageProps, pageObject, wrapWithRouter, }) {
return (0, server_2.executeAsIfOnServer)(async () => {
const { useDocument } = options;
const { documentFile: { default: DocumentComponent }, appFile: { default: AppComponent }, pageFile: { default: PageComponent }, wrappersFile, } = pageObject.files.server;
const wrappers = {
appWrapper: wrappersFile === null || wrappersFile === void 0 ? void 0 : wrappersFile.App,
pageWrapper: wrappersFile === null || wrappersFile === void 0 ? void 0 : wrappersFile.Page,
};
const render = (App, Page) => {
return (0, _app_1.renderEnhancedApp)({
App,
Page,
appProps,
pageProps,
wrappers,
});
};
// Return an empty dummy document if useDocument is not enabled
if (!useDocument) {
return (react_1.default.createElement("html", null,
react_1.default.createElement("head", null),
react_1.default.createElement("body", null,
react_1.default.createElement("div", { id: constants_1.NEXT_ROOT_ELEMENT_ID }, wrapWithRouter(render(AppComponent, PageComponent))))));
}
const renderPage = (options = {}) => {
const { App: EnhancedApp, Component: EnhancedComponent, } = enhanceComponents(options, AppComponent, PageComponent);
let head = [];
const html = (0, server_1.renderToString)(
// @NOTE: implemented from:
// https://github.com/vercel/next.js/blob/v10.0.3/packages/next/next-server/server/render.tsx#L561
// Now in: https://github.com/vercel/next.js/blob/v11.1.0/packages/next/server/render.tsx#L639
react_1.default.createElement(head_manager_context_1.HeadManagerContext.Provider, { value: {
updateHead: (state) => {
head = state;
},
mountedInstances: new Set(),
} }, wrapWithRouter(render(EnhancedApp, EnhancedComponent))));
return { html, head };
};
const initialProps = await (0, fetchDocumentData_1.default)({
Document: DocumentComponent,
renderPage,
pageObject,
});
const documentProps = {
...initialProps,
buildManifest: {
ampDevFiles: [],
ampFirstPages: [],
devFiles: [],
lowPriorityFiles: [],
polyfillFiles: [],
pages: {
[constants_1.APP_PATH]: [],
[pageObject.pagePath]: [],
},
},
__NEXT_DATA__: {
page: pageObject.pagePath,
query: pageObject.query,
buildId: 'next-page-tester',
props: { pageProps },
},
scriptLoader: {},
docComponentsRendered: {},
dangerousAsPath: '',
ampPath: '',
inAmpMode: false,
dynamicImports: [],
isDevelopment: false,
hybridAmp: false,
canonicalBase: '',
headTags: [],
devOnlyCacheBusterQueryString: '',
// @ts-expect-error We don't expect to use this method
useMaybeDeferContent: () => { },
};
// @ts-expect-error this method doesn't exist since Next.js v11.1.2 and useDocument option is currently disabled
return DocumentComponent.renderDocument(DocumentComponent, documentProps);
});
}
exports.default = serverRenderDocument;