Example electron test (#3408)
* example test mostly working * add electron test to CI
This commit is contained in:
		
							
								
								
									
										161
									
								
								.github/workflows/playwright.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										161
									
								
								.github/workflows/playwright.yml
									
									
									
									
										vendored
									
									
								
							@ -171,7 +171,7 @@ jobs:
 | 
			
		||||
        if [[ ! -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
            # if no last run artifact, than run plawright normally
 | 
			
		||||
            echo "run playwright normally"
 | 
			
		||||
            yarn playwright test --project="Google Chrome" --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep-invert=@snapshot || true
 | 
			
		||||
            yarn playwright test --project="Google Chrome" --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep-invert='@(snapshot|electron)' || true
 | 
			
		||||
            # # send to axiom
 | 
			
		||||
            node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
 | 
			
		||||
        fi
 | 
			
		||||
@ -186,7 +186,7 @@ jobs:
 | 
			
		||||
                if [[ $failed_tests -gt 0 ]]; then
 | 
			
		||||
                    echo "retried=true" >>$GITHUB_OUTPUT
 | 
			
		||||
                    echo "run playwright with last failed tests and retry $retry"
 | 
			
		||||
                    yarn playwright test --project="Google Chrome" --last-failed --grep-invert=@snapshot || true
 | 
			
		||||
                    yarn playwright test --project="Google Chrome" --last-failed --grep-invert='@(snapshot|electron)' || true
 | 
			
		||||
                    # send to axiom
 | 
			
		||||
                    node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
 | 
			
		||||
                    retry=$((retry + 1))
 | 
			
		||||
@ -233,6 +233,159 @@ jobs:
 | 
			
		||||
        retention-days: 30
 | 
			
		||||
        overwrite: true
 | 
			
		||||
 | 
			
		||||
  playwright-electron:
 | 
			
		||||
    timeout-minutes: 30
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        shardIndex: [1]
 | 
			
		||||
        shardTotal: [1]
 | 
			
		||||
    needs: check-rust-changes
 | 
			
		||||
    steps:
 | 
			
		||||
    - name: Tune GitHub-hosted runner network
 | 
			
		||||
      uses: smorimoto/tune-github-hosted-runner-network@v1
 | 
			
		||||
    - uses: actions/checkout@v4
 | 
			
		||||
    - uses: actions/setup-node@v4
 | 
			
		||||
      with:
 | 
			
		||||
        node-version-file: '.nvmrc'
 | 
			
		||||
        cache: 'yarn'
 | 
			
		||||
    - uses: KittyCAD/action-install-cli@main
 | 
			
		||||
    - name: Install dependencies
 | 
			
		||||
      run: yarn
 | 
			
		||||
    - name: Cache Playwright Browsers
 | 
			
		||||
      uses: actions/cache@v4
 | 
			
		||||
      with:
 | 
			
		||||
        path: |
 | 
			
		||||
          ~/.cache/ms-playwright/
 | 
			
		||||
        key: ${{ runner.os }}-playwright-${{ hashFiles('yarn.lock') }}
 | 
			
		||||
    - name: Install Playwright Browsers
 | 
			
		||||
      run: yarn playwright install chromium --with-deps
 | 
			
		||||
      # run: yarn playwright install --with-deps
 | 
			
		||||
    - name: Download Wasm Cache
 | 
			
		||||
      id: download-wasm
 | 
			
		||||
      if: needs.check-rust-changes.outputs.rust-changed == 'false'
 | 
			
		||||
      uses: dawidd6/action-download-artifact@v6
 | 
			
		||||
      continue-on-error: true
 | 
			
		||||
      with:
 | 
			
		||||
        github_token: ${{secrets.GITHUB_TOKEN}}
 | 
			
		||||
        name: wasm-bundle
 | 
			
		||||
        workflow: build-and-store-wasm.yml
 | 
			
		||||
        branch: main
 | 
			
		||||
        path: src/wasm-lib/pkg
 | 
			
		||||
    - name: copy wasm blob
 | 
			
		||||
      if: needs.check-rust-changes.outputs.rust-changed == 'false'
 | 
			
		||||
      run: cp src/wasm-lib/pkg/wasm_lib_bg.wasm public
 | 
			
		||||
      continue-on-error: true
 | 
			
		||||
    - name: Setup Rust
 | 
			
		||||
      uses: dtolnay/rust-toolchain@stable
 | 
			
		||||
    - name: Cache Wasm (because rust diff)
 | 
			
		||||
      if: needs.check-rust-changes.outputs.rust-changed == 'true'
 | 
			
		||||
      uses: Swatinem/rust-cache@v2
 | 
			
		||||
      with:
 | 
			
		||||
        workspaces: './src/wasm-lib'
 | 
			
		||||
    - name: OR Cache Wasm (because wasm cache failed)
 | 
			
		||||
      if: steps.download-wasm.outcome == 'failure'
 | 
			
		||||
      uses: Swatinem/rust-cache@v2
 | 
			
		||||
      with:
 | 
			
		||||
        workspaces: './src/wasm-lib'
 | 
			
		||||
    - name: Install vector
 | 
			
		||||
      run: |
 | 
			
		||||
        curl --proto '=https' --tlsv1.2 -sSfL https://sh.vector.dev > /tmp/vector.sh
 | 
			
		||||
        chmod +x /tmp/vector.sh
 | 
			
		||||
        /tmp/vector.sh -y -no-modify-path
 | 
			
		||||
        mkdir -p /tmp/vector
 | 
			
		||||
        cp .github/workflows/vector.toml /tmp/vector.toml
 | 
			
		||||
        sed -i "s#GITHUB_WORKFLOW#${GITHUB_WORKFLOW}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "s#GITHUB_REPOSITORY#${GITHUB_REPOSITORY}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "s#GITHUB_SHA#${GITHUB_SHA}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "s#GITHUB_REF_NAME#${GITHUB_REF_NAME}#g" /tmp/vector.toml
 | 
			
		||||
        sed -i "s#GH_ACTIONS_AXIOM_TOKEN#${{secrets.GH_ACTIONS_AXIOM_TOKEN}}#g" /tmp/vector.toml
 | 
			
		||||
        cat /tmp/vector.toml
 | 
			
		||||
        ${HOME}/.vector/bin/vector --config /tmp/vector.toml &
 | 
			
		||||
    - name: Build Wasm (because rust diff)
 | 
			
		||||
      if: needs.check-rust-changes.outputs.rust-changed == 'true'
 | 
			
		||||
      run: yarn build:wasm
 | 
			
		||||
    - name: OR Build Wasm (because wasm cache failed)
 | 
			
		||||
      if: steps.download-wasm.outcome == 'failure'
 | 
			
		||||
      run: yarn build:wasm
 | 
			
		||||
    - name: build web
 | 
			
		||||
      run: yarn build:local
 | 
			
		||||
    - uses: actions/download-artifact@v4
 | 
			
		||||
      if: always()
 | 
			
		||||
      continue-on-error: true
 | 
			
		||||
      with:
 | 
			
		||||
        name: test-results-ubuntu-${{ matrix.shardIndex }}-${{ github.sha }}
 | 
			
		||||
        path: test-results/
 | 
			
		||||
    - name: Run ubuntu/chrome flow (with retries)
 | 
			
		||||
      id: retry
 | 
			
		||||
      if: always()
 | 
			
		||||
      run: |
 | 
			
		||||
        if [[ ! -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
            # if no last run artifact, than run plawright normally
 | 
			
		||||
            echo "run playwright normally"
 | 
			
		||||
                        yarn playwright test --project="Google Chrome" --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep=@electron || true
 | 
			
		||||
            # # send to axiom
 | 
			
		||||
            node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
 | 
			
		||||
        fi
 | 
			
		||||
 | 
			
		||||
        retry=1
 | 
			
		||||
        max_retrys=4
 | 
			
		||||
 | 
			
		||||
        # retry failed tests, doing our own retries because using inbuilt playwright retries causes connection issues
 | 
			
		||||
        while [[ $retry -le $max_retrys ]]; do
 | 
			
		||||
            if [[ -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
                failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
 | 
			
		||||
                if [[ $failed_tests -gt 0 ]]; then
 | 
			
		||||
                    echo "retried=true" >>$GITHUB_OUTPUT
 | 
			
		||||
                    echo "run playwright with last failed tests and retry $retry"
 | 
			
		||||
                    yarn playwright test --project="Google Chrome" --last-failed --grep=@electron || true
 | 
			
		||||
                    # send to axiom
 | 
			
		||||
                    node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
 | 
			
		||||
                    retry=$((retry + 1))
 | 
			
		||||
                else
 | 
			
		||||
                    echo "retried=false" >>$GITHUB_OUTPUT
 | 
			
		||||
                    exit 0
 | 
			
		||||
                fi
 | 
			
		||||
            else
 | 
			
		||||
                echo "retried=false" >>$GITHUB_OUTPUT
 | 
			
		||||
                exit 0
 | 
			
		||||
            fi
 | 
			
		||||
        done
 | 
			
		||||
 | 
			
		||||
        echo "retried=false" >>$GITHUB_OUTPUT
 | 
			
		||||
 | 
			
		||||
        if [[ -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
            failed_tests=$(jq '.failedTests | length' test-results/.last-run.json)
 | 
			
		||||
            if [[ $failed_tests -gt 0 ]]; then
 | 
			
		||||
                # if it still fails after 3 retrys, then fail the job
 | 
			
		||||
                exit 1
 | 
			
		||||
            fi
 | 
			
		||||
        fi
 | 
			
		||||
        exit 0
 | 
			
		||||
      env:
 | 
			
		||||
        CI: true
 | 
			
		||||
        token: ${{ secrets.KITTYCAD_API_TOKEN_DEV }}
 | 
			
		||||
    - name: send to axiom
 | 
			
		||||
      if: always()
 | 
			
		||||
      shell: bash
 | 
			
		||||
      run: |
 | 
			
		||||
        node playwrightProcess.mjs | tee /tmp/github-actions.log
 | 
			
		||||
    - uses: actions/upload-artifact@v4
 | 
			
		||||
      if: always()
 | 
			
		||||
      with:
 | 
			
		||||
        name: test-results-electron-${{ matrix.shardIndex }}-${{ github.sha }}
 | 
			
		||||
        path: test-results/
 | 
			
		||||
        retention-days: 30
 | 
			
		||||
        overwrite: true
 | 
			
		||||
    - uses: actions/upload-artifact@v4
 | 
			
		||||
      if: always()
 | 
			
		||||
      with:
 | 
			
		||||
        name: playwright-report-electron-${{ matrix.shardIndex }}-${{ github.sha }}
 | 
			
		||||
        path: playwright-report/
 | 
			
		||||
        retention-days: 30
 | 
			
		||||
        overwrite: true
 | 
			
		||||
 | 
			
		||||
  playwright-macos:
 | 
			
		||||
    timeout-minutes: 30
 | 
			
		||||
    runs-on: macos-14
 | 
			
		||||
@ -325,7 +478,7 @@ jobs:
 | 
			
		||||
        if [[ ! -f "test-results/.last-run.json" ]]; then
 | 
			
		||||
            # if no last run artifact, than run plawright normally
 | 
			
		||||
            echo "run playwright normally"
 | 
			
		||||
            yarn playwright test --project="webkit" --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep-invert=@snapshot || true
 | 
			
		||||
            yarn playwright test --project="webkit" --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --grep-invert='@(snapshot|electron)' || true
 | 
			
		||||
            # # send to axiom
 | 
			
		||||
            node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
 | 
			
		||||
        fi
 | 
			
		||||
@ -340,7 +493,7 @@ jobs:
 | 
			
		||||
                if [[ $failed_tests -gt 0 ]]; then
 | 
			
		||||
                    echo "retried=true" >>$GITHUB_OUTPUT
 | 
			
		||||
                    echo "run playwright with last failed tests and retry $retry"
 | 
			
		||||
                    yarn playwright test --project="webkit" --last-failed --grep-invert=@snapshot || true
 | 
			
		||||
                    yarn playwright test --project="webkit" --last-failed --grep-invert='@(snapshot|electron)' || true
 | 
			
		||||
                    # send to axiom
 | 
			
		||||
                    node playwrightProcess.mjs | tee /tmp/github-actions.log > /dev/null 2>&1
 | 
			
		||||
                    retry=$((retry + 1))
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -65,4 +65,7 @@ venv
 | 
			
		||||
.vite/
 | 
			
		||||
 | 
			
		||||
# electron
 | 
			
		||||
out/
 | 
			
		||||
out/
 | 
			
		||||
 | 
			
		||||
src-tauri/target
 | 
			
		||||
electron-test-projects-dir
 | 
			
		||||
@ -1,40 +1,102 @@
 | 
			
		||||
import { _electron as electron, test } from '@playwright/test';
 | 
			
		||||
import { _electron as electron, test, expect } from '@playwright/test'
 | 
			
		||||
import {
 | 
			
		||||
  getUtils,
 | 
			
		||||
  TEST_COLORS,
 | 
			
		||||
  setup,
 | 
			
		||||
  tearDown,
 | 
			
		||||
  commonPoints,
 | 
			
		||||
  PERSIST_MODELING_CONTEXT,
 | 
			
		||||
} from './test-utils'
 | 
			
		||||
import fs from 'node:fs'
 | 
			
		||||
import { secrets } from './secrets'
 | 
			
		||||
 | 
			
		||||
test.describe("when a project", async () => {
 | 
			
		||||
 | 
			
		||||
  // This was the very test created. It provides the foundation for the
 | 
			
		||||
  // rest of the tests we have to write.
 | 
			
		||||
  test('is created', async ({ page }) => {
 | 
			
		||||
      // Launch Electron app.
 | 
			
		||||
      const electronApp = await electron.launch({ args: ['.'] })
 | 
			
		||||
 | 
			
		||||
      // Evaluation expression in the Electron context.
 | 
			
		||||
      const appPath = await electronApp.evaluate(async ({ app }) => {
 | 
			
		||||
        // This runs in the main Electron process, parameter here is always
 | 
			
		||||
        // the result of the require('electron') in the main app script.
 | 
			
		||||
        return app.getAppPath();
 | 
			
		||||
      });
 | 
			
		||||
      console.log(appPath);
 | 
			
		||||
 | 
			
		||||
      // Get the first window that the app opens, wait if necessary.
 | 
			
		||||
      const window = await electronApp.firstWindow();
 | 
			
		||||
      // Print the title.
 | 
			
		||||
      console.log(await window.title());
 | 
			
		||||
      // Capture a screenshot.
 | 
			
		||||
      await window.screenshot({ path: 'intro.png' });
 | 
			
		||||
      // Direct Electron console to Node terminal.
 | 
			
		||||
      window.on('console', console.log);
 | 
			
		||||
      // Click button.
 | 
			
		||||
      await window.click('text=Click me');
 | 
			
		||||
      // Exit app.
 | 
			
		||||
      await electronApp.close();
 | 
			
		||||
  })
 | 
			
		||||
test.afterEach(async ({ page }, testInfo) => {
 | 
			
		||||
  await tearDown(page, testInfo)
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
test('When the project folder is empty, user can create new project and open it.', { tag: '@electron' }, async () => {
 | 
			
		||||
  // create or otherwise clear the folder ./electron-test-projects-dir
 | 
			
		||||
  const fileName = './electron-test-projects-dir'
 | 
			
		||||
  try {
 | 
			
		||||
    fs.rmdirSync(fileName, { recursive: true })
 | 
			
		||||
  } catch (e) {
 | 
			
		||||
    console.error(e)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  fs.mkdirSync(fileName)
 | 
			
		||||
 | 
			
		||||
  // get full path for ./electron-test-projects-dir
 | 
			
		||||
  const fullPath = fs.realpathSync(fileName)
 | 
			
		||||
 | 
			
		||||
  const electronApp = await electron.launch({
 | 
			
		||||
    args: ['.'],
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  await electronApp.evaluate(async ({ app }) => {
 | 
			
		||||
    return app.getAppPath()
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  const page = await electronApp.firstWindow()
 | 
			
		||||
 | 
			
		||||
  // Set local storage directly using evaluate
 | 
			
		||||
  await page.evaluate(
 | 
			
		||||
    (token) => localStorage.setItem('TOKEN_PERSIST_KEY', token),
 | 
			
		||||
    secrets.token
 | 
			
		||||
  )
 | 
			
		||||
  await page.evaluate((fullPath) =>
 | 
			
		||||
    localStorage.setItem(
 | 
			
		||||
      'APP_SETTINGS_OVERRIDE',
 | 
			
		||||
      JSON.stringify({
 | 
			
		||||
        projectDirectory: fullPath,
 | 
			
		||||
      })
 | 
			
		||||
    ), fullPath
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
  const u = await getUtils(page)
 | 
			
		||||
  await page.setViewportSize({ width: 1200, height: 500 })
 | 
			
		||||
 | 
			
		||||
  page.on('console', console.log)
 | 
			
		||||
 | 
			
		||||
  // expect to see text "No Projects found"
 | 
			
		||||
  await expect(page.getByText('No Projects found')).toBeVisible()
 | 
			
		||||
 | 
			
		||||
  await page.getByRole('button', { name: 'New project' }).click()
 | 
			
		||||
 | 
			
		||||
  await expect(page.getByText('Successfully created')).toBeVisible()
 | 
			
		||||
  await expect(page.getByText('Successfully created')).not.toBeVisible()
 | 
			
		||||
 | 
			
		||||
  await expect(page.getByText('project-000')).toBeVisible()
 | 
			
		||||
 | 
			
		||||
  await page.getByText('project-000').click()
 | 
			
		||||
 | 
			
		||||
  await expect(page.getByTestId('loading')).toBeAttached()
 | 
			
		||||
  await expect(page.getByTestId('loading')).not.toBeAttached({
 | 
			
		||||
    timeout: 20_000,
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  await expect(page.getByRole('button', { name: 'Start Sketch' })).toBeEnabled({
 | 
			
		||||
    timeout: 20_000,
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  await page.locator('.cm-content').fill(`const sketch001 = startSketchOn('XZ')
 | 
			
		||||
  |> startProfileAt([-87.4, 282.92], %)
 | 
			
		||||
  |> line([324.07, 27.199], %, $seg01)
 | 
			
		||||
  |> line([118.328, -291.754], %)
 | 
			
		||||
  |> line([-180.04, -202.08], %)
 | 
			
		||||
  |> lineTo([profileStartX(%), profileStartY(%)], %)
 | 
			
		||||
  |> close(%)
 | 
			
		||||
const extrude001 = extrude(200, sketch001)`)
 | 
			
		||||
 | 
			
		||||
  const pointOnModel = { x: 660, y: 250 }
 | 
			
		||||
 | 
			
		||||
  // check the model loaded by checking it's grey
 | 
			
		||||
  await expect
 | 
			
		||||
    .poll(() => u.getGreatestPixDiff(pointOnModel, [132, 132, 132]), {
 | 
			
		||||
      timeout: 10_000,
 | 
			
		||||
    })
 | 
			
		||||
    .toBeLessThan(10)
 | 
			
		||||
 | 
			
		||||
  await page.mouse.click(pointOnModel.x, pointOnModel.y)
 | 
			
		||||
  // check user can interact with model by checking it turns yellow
 | 
			
		||||
  await expect
 | 
			
		||||
    .poll(() => u.getGreatestPixDiff(pointOnModel, [176, 180, 132]))
 | 
			
		||||
    .toBeLessThan(10)
 | 
			
		||||
 | 
			
		||||
  await electronApp.close()
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
@ -441,6 +441,15 @@ export const readAppSettingsFile = async () => {
 | 
			
		||||
  }
 | 
			
		||||
  const configToml = await window.electron.readFile(settingsPath)
 | 
			
		||||
  const configObj = parseAppSettings(configToml)
 | 
			
		||||
  const overrideJSON = localStorage.getItem('APP_SETTINGS_OVERRIDE')
 | 
			
		||||
  if (overrideJSON) {
 | 
			
		||||
    try {
 | 
			
		||||
      const override = JSON.parse(overrideJSON)
 | 
			
		||||
      configObj.app = { ...configObj.app, ...override }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      console.error('Error parsing APP_SETTINGS_OVERRIDE:', e)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return configObj
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								src/main.ts
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								src/main.ts
									
									
									
									
									
								
							@ -2,7 +2,15 @@
 | 
			
		||||
// template that ElectronJS provides.
 | 
			
		||||
 | 
			
		||||
import { Configuration } from 'wasm-lib/kcl/bindings/Configuration'
 | 
			
		||||
import { app, BrowserWindow, ipcMain, dialog, shell, protocol, net } from 'electron'
 | 
			
		||||
import {
 | 
			
		||||
  app,
 | 
			
		||||
  BrowserWindow,
 | 
			
		||||
  ipcMain,
 | 
			
		||||
  dialog,
 | 
			
		||||
  shell,
 | 
			
		||||
  protocol,
 | 
			
		||||
  net,
 | 
			
		||||
} from 'electron'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
import url from 'url'
 | 
			
		||||
import fs from 'node:fs/promises'
 | 
			
		||||
@ -41,7 +49,7 @@ const createWindow = () => {
 | 
			
		||||
  // Open the DevTools.
 | 
			
		||||
  // mainWindow.webContents.openDevTools()
 | 
			
		||||
 | 
			
		||||
    mainWindow.show()
 | 
			
		||||
  mainWindow.show()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Quit when all windows are closed, except on macOS. There, it's common
 | 
			
		||||
@ -153,8 +161,12 @@ app.whenReady().then(() => {
 | 
			
		||||
    const maybeAbsolutePath = path.join(__dirname, filePath)
 | 
			
		||||
    const bypassCustomProtocolHandlers = true
 | 
			
		||||
    if (fss.existsSync(maybeAbsolutePath)) {
 | 
			
		||||
      console.log(`Intercepted local-asbolute path ${filePath}, rebuilt it as ${maybeAbsolutePath}`)
 | 
			
		||||
      return net.fetch(url.pathToFileURL(maybeAbsolutePath).toString(), { bypassCustomProtocolHandlers })
 | 
			
		||||
      console.log(
 | 
			
		||||
        `Intercepted local-asbolute path ${filePath}, rebuilt it as ${maybeAbsolutePath}`
 | 
			
		||||
      )
 | 
			
		||||
      return net.fetch(url.pathToFileURL(maybeAbsolutePath).toString(), {
 | 
			
		||||
        bypassCustomProtocolHandlers,
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    console.log(`Default fetch to ${filePath}`)
 | 
			
		||||
    return net.fetch(request.url, { bypassCustomProtocolHandlers })
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user