mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
727a3ffa86
The hypothesis is that this is just installing some font stuff that isn't actually needed for Chromium to work: ``` The following additional packages will be installed: libnss3-tools xfonts-encodings xfonts-utils Recommended packages: fonts-ipafont-mincho fonts-liberation-sans-narrow fonts-tlwg-loma The following NEW packages will be installed: fonts-freefont-ttf fonts-ipafont-gothic fonts-liberation fonts-tlwg-loma-otf fonts-unifont fonts-wqy-zenhei xfonts-cyrillic xfonts-encodings xfonts-scalable xfonts-utils The following packages will be upgraded: libnss3 libnss3-tools 2 upgraded, 10 newly installed, 0 to remove and 35 not upgraded. ``` `apt` is very slow, so skipping this step should significantly reduce setup time per test shard. It seems like this isn't always true for other browsers, so only skip this for Chromium (that's fine, that's what most of our jobs use anyways). On 16 core arm runners, "Install Playwright Browsers" typically took 18-24 seconds. Now it takes 5-6s. Let's estimate that saves about 15s per Linux job that installs Chromium. Claude estimates that there are 73 chromium-only Linux jobs on this PR: <img width="891" height="148" alt="Screenshot 2026-07-06 at 10 30 16 PM" src="https://github.com/user-attachments/assets/725893fa-9f6f-4806-a3b4-9858ab0ebe66" /> So that's 15*73/60=18.25 minutes saved per PR push (the average PR gets many pushes). At the public (before any volume discounts) price of $0.026/minute for the 16 core arm runners, that comes out to $0.4745 per PR push saved. This workflow has had 3,894 runs in the last 30 days, so that could be $1,847/mo saved, but many of those workflow runs were canceled, and some likely failed before getting to these jobs, so the actual savings are probably somewhere around half of that -- scroll through https://github.com/vercel/next.js/actions/workflows/.github/workflows/build_and_test.yml and see that a little less than half of the workflow runs end up canceled.
107 lines
3.5 KiB
TypeScript
107 lines
3.5 KiB
TypeScript
/* eslint-env jest */
|
|
|
|
import { check } from 'next-test-utils'
|
|
import path from 'path'
|
|
import { nextTestSetup } from 'e2e-utils'
|
|
import { expectScrolledTo } from './scroll-position.util'
|
|
|
|
describe('Client navigation scroll', () => {
|
|
const { next } = nextTestSetup({
|
|
files: path.join(__dirname, 'fixture'),
|
|
env: {
|
|
TEST_STRICT_NEXT_HEAD: String(true),
|
|
},
|
|
})
|
|
|
|
describe('resets scroll at the correct time', () => {
|
|
it('should reset scroll before the new page runs its lifecycles (<Link />)', async () => {
|
|
const browser = await next.browser('/nav/long-page-to-snap-scroll')
|
|
|
|
// Scrolls to item 400 on the page
|
|
await browser
|
|
.waitForElementByCss('#long-page-to-snap-scroll')
|
|
.elementByCss('#scroll-to-item-400')
|
|
.click()
|
|
|
|
await expectScrolledTo(browser, "document.getElementById('item-400')")
|
|
|
|
// Go to snap scroll page
|
|
await browser
|
|
.elementByCss('#goto-snap-scroll-position')
|
|
.click()
|
|
.waitForElementByCss('#scroll-pos-y')
|
|
|
|
const snappedScrollPosition = await browser.eval(
|
|
'document.getElementById("scroll-pos-y").innerText'
|
|
)
|
|
expect(snappedScrollPosition).toBe('0')
|
|
})
|
|
|
|
it('should reset scroll before the new page runs its lifecycles (Router#push)', async () => {
|
|
const browser = await next.browser('/nav/long-page-to-snap-scroll')
|
|
|
|
// Scrolls to item 400 on the page
|
|
await browser
|
|
.waitForElementByCss('#long-page-to-snap-scroll')
|
|
.elementByCss('#scroll-to-item-400')
|
|
.click()
|
|
|
|
await expectScrolledTo(browser, "document.getElementById('item-400')")
|
|
|
|
// Go to snap scroll page
|
|
await browser
|
|
.elementByCss('#goto-snap-scroll-position-imperative')
|
|
.click()
|
|
.waitForElementByCss('#scroll-pos-y')
|
|
|
|
const snappedScrollPosition = await browser.eval(
|
|
'document.getElementById("scroll-pos-y").innerText'
|
|
)
|
|
expect(snappedScrollPosition).toBe('0')
|
|
})
|
|
|
|
it('should intentionally not reset scroll before the new page runs its lifecycles (Router#push)', async () => {
|
|
const browser = await next.browser('/nav/long-page-to-snap-scroll')
|
|
|
|
// Scrolls to item 400 on the page
|
|
await browser
|
|
.waitForElementByCss('#long-page-to-snap-scroll')
|
|
.elementByCss('#scroll-to-item-400')
|
|
.click()
|
|
|
|
await expectScrolledTo(browser, "document.getElementById('item-400')")
|
|
const scrollPosition = await browser.eval('window.pageYOffset')
|
|
|
|
// Go to snap scroll page
|
|
await browser
|
|
.elementByCss('#goto-snap-scroll-position-imperative-noscroll')
|
|
.click()
|
|
.waitForElementByCss('#scroll-pos-y')
|
|
|
|
const snappedScrollPosition = await browser.eval(
|
|
'document.getElementById("scroll-pos-y").innerText'
|
|
)
|
|
expect(snappedScrollPosition).not.toBe('0')
|
|
expect(Number(snappedScrollPosition)).toBeGreaterThanOrEqual(
|
|
scrollPosition
|
|
)
|
|
})
|
|
})
|
|
|
|
it('should scroll to top when the scroll option is set to true', async () => {
|
|
const browser = await next.browser('/nav/shallow-routing')
|
|
await browser.eval(() =>
|
|
document.querySelector('#increaseWithScroll').scrollIntoView()
|
|
)
|
|
const scrollPosition = await browser.eval('window.pageYOffset')
|
|
|
|
expect(scrollPosition).toBeGreaterThan(3000)
|
|
|
|
await browser.elementByCss('#increaseWithScroll').click()
|
|
await check(async () => {
|
|
const newScrollPosition = await browser.eval('window.pageYOffset')
|
|
return newScrollPosition === 0 ? 'success' : 'fail'
|
|
}, 'success')
|
|
})
|
|
})
|