File size: 6,623 Bytes
b91e262 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | import { FileRef } from 'e2e-utils'
import { Playwright } from 'next-webdriver'
import { nextTestSetup } from 'e2e-utils'
import { join } from 'path'
import { waitForDevToolsIndicator, retry } from 'next-test-utils'
describe('client-dev-overlay', () => {
const { next, isTurbopack } = nextTestSetup({
files: {
pages: new FileRef(join(__dirname, 'pages')),
},
env: {
// Disable the cooldown period for the dev indicator so that hiding the indicator in a test doesn't
// impact subsequent tests.
__NEXT_DEV_INDICATOR_COOLDOWN_MS: '0',
},
})
// The `Playwright.hasElementByCssSelector` cannot be used for elements inside a shadow DOM.
function elementExistsInNextJSPortalShadowDOM(
browser: Playwright,
selector: string
) {
return browser.eval(
`!!document.querySelector('nextjs-portal').shadowRoot.querySelector('${selector}')`
) as any
}
const selectors = {
fullScreenDialog: '[data-nextjs-dialog]',
toast: '[data-nextjs-toast]',
popover: '[data-nextjs-dev-tools-button]',
indicator: '[data-next-badge-root]',
minimizeButton: 'body',
preferencesButton: '[data-preferences]',
hideButton: '[data-hide-dev-tools]',
}
function getToast(browser: Playwright) {
return browser.elementByCss(selectors.toast)
}
function getPopover(browser: Playwright) {
return browser.elementByCss(selectors.popover)
}
function getMinimizeButton(browser: Playwright) {
return browser.elementByCss(selectors.minimizeButton)
}
function getHideButton(browser: Playwright) {
return browser.elementByCss(selectors.hideButton)
}
function getPreferencesButton(browser: Playwright) {
return browser.elementByCss(selectors.preferencesButton)
}
it('should be able to fullscreen the minimized overlay', async () => {
const browser = await next.browser('/')
await getMinimizeButton(browser).click()
await getToast(browser).click()
await retry(async () => {
expect(
await elementExistsInNextJSPortalShadowDOM(
browser,
selectors.fullScreenDialog
)
).toBe(true)
})
})
it('should be able to minimize the fullscreen overlay', async () => {
const browser = await next.browser('/')
await getMinimizeButton(browser).click()
expect(
await elementExistsInNextJSPortalShadowDOM(browser, selectors.toast)
).toBe(true)
})
it('should keep the error indicator visible when there are errors', async () => {
const browser = await next.browser('/')
await getMinimizeButton(browser).click()
await getPopover(browser).click()
await getPreferencesButton(browser).click()
await getHideButton(browser).click()
await retry(async () => {
const display = await browser.eval(
`getComputedStyle(document.querySelector('nextjs-portal').shadowRoot.querySelector('${selectors.indicator}')).display`
)
expect(display).toBe('block')
})
})
it('should be possible to hide the minimized overlay when there are no errors', async () => {
const browser = await next.browser('/')
const originalContent = await next.readFile('pages/index.js')
try {
await next.patchFile('pages/index.js', (content) => {
return content.replace(`throw Error('example runtime error')`, '')
})
await getMinimizeButton(browser).click()
await getPopover(browser).click()
await getPreferencesButton(browser).click()
await getHideButton(browser).click()
await retry(async () => {
const display = await browser.eval(
`getComputedStyle(document.querySelector('nextjs-portal').shadowRoot.querySelector('${selectors.indicator}')).display`
)
expect(display).toBe('none')
})
} finally {
await next.patchFile('pages/index.js', originalContent)
}
})
it('should have a role of "dialog" if the page is focused', async () => {
const browser = await next.browser('/')
await retry(async () => {
expect(
await elementExistsInNextJSPortalShadowDOM(browser, '[role="dialog"]')
).toBe(true)
})
})
it('should nudge to use Turbopack unless Turbopack is disabled', async () => {
const browser = await next.browser('/')
// Don't use toggleDevToolsIndicatorPopover because this is asserting something in the old dev tools menu which isn't preset yet in the new UI.
const devToolsIndicator = await waitForDevToolsIndicator(browser)
try {
await devToolsIndicator.click()
} catch (cause) {
const error = new Error('No DevTools Indicator to open.', { cause })
throw error
}
const devtoolsMenu = await browser.elementByCss('#nextjs-dev-tools-menu')
if (isTurbopack) {
expect(await devtoolsMenu.innerText()).toMatchInlineSnapshot(`
"Issues
1
Route
Static
Bundler
Turbopack
Preferences"
`)
} else {
expect(await devtoolsMenu.innerText()).toMatchInlineSnapshot(`
"Issues
1
Route
Static
Bundler
Webpack
Preferences"
`)
}
})
})
describe('client-dev-overlay with Cache Components', () => {
const { next, isTurbopack } = nextTestSetup({
files: {
pages: new FileRef(join(__dirname, 'pages')),
'next.config.js': `
module.exports = {
cacheComponents: true,
}
`,
},
env: {
__NEXT_DEV_INDICATOR_COOLDOWN_MS: '0',
},
})
it('should show Cache Components as enabled in the devtools menu', async () => {
const browser = await next.browser('/')
const devToolsIndicator = await waitForDevToolsIndicator(browser)
try {
await devToolsIndicator.click()
} catch (cause) {
const error = new Error('No DevTools Indicator to open.', { cause })
throw error
}
const devtoolsMenu = await browser.elementByCss('#nextjs-dev-tools-menu')
const menuText = await devtoolsMenu.innerText()
// Should include Cache Components
expect(menuText).toContain('Cache Components')
expect(menuText).toContain('Enabled')
// Should also include Turbopack info
if (isTurbopack) {
expect(menuText).toMatchInlineSnapshot(`
"Issues
1
Route
Static
Bundler
Turbopack
Cache Components
Enabled
Preferences"
`)
} else {
expect(menuText).toMatchInlineSnapshot(`
"Issues
1
Route
Static
Bundler
Webpack
Cache Components
Enabled
Preferences"
`)
}
})
})
|