Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 8 additions & 55 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ on:
- main

jobs:
pr:
runs-on: ${{ matrix.os }}
reproduce-markdown-preview-side-by-side:
name: markdown-preview-side-by-side (attempt ${{ matrix.attempt }})
runs-on: ubuntu-24.04
strategy:
fail-fast: false
max-parallel: 1
matrix:
os: [ubuntu-24.04, macos-26, windows-2022]
attempt: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
timeout-minutes: 240
steps:
- uses: actions/checkout@v7
Expand All @@ -34,66 +36,17 @@ jobs:
**/.vscode-ffmpeg
**/.vscode-resolve-source-map-cache
key: ${{ runner.os }}-cacheNodeModules-${{ steps.nodeModulesCacheKey.outputs.value }}
- name: Compute source maps cache key
id: sourceMapsCacheKey
run: echo "value=$(node packages/build/src/computeSourceMapsCacheKey.ts)" >> $GITHUB_OUTPUT
shell: bash
- uses: actions/cache@v6
id: source-maps-cache
with:
path: |
**/.vscode-source-maps
**/.vscode-sources
key: ${{ runner.os }}-cacheSourceMaps-${{ steps.sourceMapsCacheKey.outputs.value }}
- name: npm ci
run: npm ci --ignore-scripts && npm run postinstall
if: steps.npm-cache.outputs.cache-hit != 'true'
- run: npm run type-check
- run: npm run lint
- run: npm run build
- run: npx lerna run test --since origin/main
- name: Run headless test (with videos)
if: matrix.os != 'macos-26'
uses: coactions/setup-xvfb@v1
with:
run: node packages/cli/bin/test.js --cwd packages/e2e --record-video
- name: Run headless test
uses: coactions/setup-xvfb@v1
with:
run: npm run e2e
- name: Run headless test (flakyness check)
if: matrix.os != 'macos-26'
uses: coactions/setup-xvfb@v1
with:
run: npm run e2e:check-flakyness
- name: Run headless test (second flakyness check)
if: matrix.os != 'macos-26'
uses: coactions/setup-xvfb@v1
with:
run: npm run e2e:check-flakyness
- name: Run headless test (check leaks, event listener count)
if: matrix.os != 'macos-26'
uses: coactions/setup-xvfb@v1
with:
run: node packages/cli/bin/test.js --cwd packages/e2e --check-leaks --measure-after
- name: Run headless test (check leaks, event listeners)
if: matrix.os == 'ubuntu-24.04'
uses: coactions/setup-xvfb@v1
with:
run: node packages/cli/bin/test.js --cwd packages/e2e --check-leaks --measure event-listeners
- name: Run Memory City smoke test
if: matrix.os == 'ubuntu-24.04'
- name: Run markdown-preview-side-by-side
uses: coactions/setup-xvfb@v1
with:
run: node packages/cli/bin/test.js --cwd packages/e2e --check-leaks --measure memory-city --only ^editor-open.ts --workers 1
- name: Generate charts
run: node packages/charts/src/main.ts
- name: Validate Memory City artifact
if: matrix.os == 'ubuntu-24.04'
run: node packages/visualizations/src/validate.ts
run: node packages/cli/bin/test.js --cwd packages/e2e --record-video --only ^markdown-preview-side-by-side.ts --workers 1 --run-skipped-tests-anyway
- uses: actions/upload-artifact@v7
if: always()
with:
name: vscode-videos-${{ runner.os }}
name: markdown-preview-side-by-side-attempt-${{ matrix.attempt }}
path: ./.vscode-videos
include-hidden-files: true
2 changes: 1 addition & 1 deletion packages/e2e/src/markdown-preview-side-by-side.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const run = async ({ Editor, MarkdownPreview, QuickPick, WellKnownCommand
await Editor.focusBottomEditorGroup()
await Editor.open('second.md')
await QuickPick.executeCommand(WellKnownCommands.MarkdownOpenPreviewToTheSide)
const subFrame2 = await MarkdownPreview.shouldBeVisible()
const subFrame2 = await MarkdownPreview.shouldBeVisible(1)
await MarkdownPreview.shouldHaveHeading(subFrame2, 'second-document')

await Editor.closeAll()
Expand Down
2 changes: 1 addition & 1 deletion packages/e2e/types/pageobject-api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ export interface LanguageModelEditor {
open(): Promise<void>
}
export interface MarkdownPreview {
shouldBeVisible(): Promise<void>
shouldBeVisible(iframeIndex?: any): Promise<void>
shouldHaveCodeBlocks(subFrame: any, count: any): Promise<void>
shouldHaveCodeBlockWithLanguage(subFrame: any, language: any): Promise<void>
shouldHaveHeading(subFrame: any, id: any): Promise<void>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { CreateParams } from '../CreateParams/CreateParams.ts'

export const create = ({ expect, page, VError }: CreateParams) => {
return {
async shouldBeVisible() {
async shouldBeVisible(iframeIndex = 0) {
try {
await page.waitForIdle()
const webView = page.locator('.webview')
Expand All @@ -11,6 +11,7 @@ export const create = ({ expect, page, VError }: CreateParams) => {
await expect(webView).toHaveClass('ready')
await page.waitForIdle()
const childPage = await page.waitForIframe({
iframeIndex,
injectUtilityScript: false,
url: /extensionId=vscode.markdown-language-features/,
})
Expand Down
3 changes: 2 additions & 1 deletion packages/test-worker/src/parts/ElectronApp/ElectronApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@ export const create = ({ browserRpc, electronObjectId, electronRpc, firstWindow,
currentSessionRpc = sessionRpc
},
rpc: electronRpc,
waitForIframe({ injectUtilityScript = true, url }) {
waitForIframe({ iframeIndex = 0, injectUtilityScript = true, url }) {
return WaitForIframe.waitForIframe({
browserRpc,
createPage: Page.create,
electronObjectId,
electronRpc,
idleTimeout,
iframeIndex,
injectUtilityScript,
sessionRpc: currentSessionRpc,
url,
Expand Down
3 changes: 2 additions & 1 deletion packages/test-worker/src/parts/Page/Page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,14 @@ export const create = ({
async waitForIdle() {
return PageWaitForIdle.waitForIdle(this.rpc, this.electronRpc.canUseIdleCallback, idleTimeout)
},
waitForIframe({ injectUtilityScript = true, url }) {
waitForIframe({ iframeIndex = 0, injectUtilityScript = true, url }) {
return WaitForIframe.waitForIframe({
browserRpc,
createPage: create,
electronObjectId,
electronRpc,
idleTimeout,
iframeIndex,
injectUtilityScript,
sessionRpc,
url,
Expand Down
14 changes: 10 additions & 4 deletions packages/test-worker/src/parts/WaitForIframe/WaitForIframe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,28 @@ interface TargetInfo {
readonly url: string
}

const findMatchingIframe = (targets, expectedUrl) => {
const findMatchingIframe = (targets, expectedUrl, iframeIndex) => {
let matchingIndex = 0
for (const target of targets) {
if (expectedUrl.test(target.url) || expectedUrl.test(target.title)) {
return target
if (matchingIndex === iframeIndex) {
return target
}
matchingIndex++
}
}
return undefined
}

const waitForMatchingIframe = async (sessionRpc, url, timeout = 30_000) => {
const waitForMatchingIframe = async (sessionRpc, url, iframeIndex, timeout = 30_000) => {
const deadline = performance.now() + timeout
let targets: readonly TargetInfo[] = []
while (performance.now() < deadline) {
targets = (await DevtoolsProtocolTarget.getTargets(sessionRpc)) as readonly TargetInfo[]
const matchingIframe = findMatchingIframe(
targets.filter((target) => target.type === 'iframe'),
url,
iframeIndex,
)
if (matchingIframe) {
return matchingIframe
Expand All @@ -42,6 +47,7 @@ export const waitForIframe = async ({
electronObjectId,
electronRpc,
idleTimeout,
iframeIndex = 0,
injectUtilityScript,
sessionRpc,
url,
Expand All @@ -53,7 +59,7 @@ export const waitForIframe = async ({
// 4. resolve promise with execution context id and frame Id, clean up listeners

// TODO ask browser rpc for targets / add target change listener
const matchingIframe = await waitForMatchingIframe(sessionRpc, url)
const matchingIframe = await waitForMatchingIframe(sessionRpc, url, iframeIndex)

const iframeSessionId = await DevtoolsProtocolTarget.attachToTarget(sessionRpc, {
flatten: true,
Expand Down
Loading