diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ed83fe6ef..4c487267d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,6 +10,9 @@ on: jobs: build: + permissions: + contents: read + strategy: matrix: os: [macos-14] @@ -19,6 +22,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + persist-credentials: false - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: @@ -28,5 +33,12 @@ jobs: - run: npm install - run: npm run eslint - run: npm run build - - uses: microsoft/playwright-github-action@v1 - - run: npm run test:ci + env: + GITHUB_API_PREFIX: http://localhost:8080/api/github + - name: Install snapshot test dependencies + working-directory: tests + run: npm ci && npx playwright install --with-deps + - name: Run snapshot tests + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: npx start-server-and-test watch:dev-server http://localhost:8080 "env -u GITHUB_TOKEN npm --prefix tests test" diff --git a/.github/workflows/test-wtih-vscode-build.yml b/.github/workflows/test-wtih-vscode-build.yml index d04876a72..2d35e02a9 100644 --- a/.github/workflows/test-wtih-vscode-build.yml +++ b/.github/workflows/test-wtih-vscode-build.yml @@ -37,5 +37,12 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: npm run build - run: npm run link && npm run build - - uses: microsoft/playwright-github-action@v1 - - run: npm run test:ci + env: + GITHUB_API_PREFIX: http://localhost:8080/api/github + - name: Install snapshot test dependencies + working-directory: tests + run: npm ci && npx playwright install --with-deps + - name: Run snapshot tests + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: npx start-server-and-test watch:dev-server http://localhost:8080 "env -u GITHUB_TOKEN npm --prefix tests test" diff --git a/.gitignore b/.gitignore index 7f61e2ee3..14ab9cbcc 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ dist out node_modules .worktrees/ +tests/__tests__/__image_snapshots__/__diff_output__/ diff --git a/docs/deployment.md b/docs/deployment.md index 0f74e4b4f..6ee4a85df 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -93,7 +93,7 @@ npm run build npx wrangler pages dev dist ``` -Omit the OAuth configuration and export for a preview without GitHub OAuth. Open `http://localhost:8788/conwnet/github1s`. This differs from `npm run watch`, whose webpack server runs on port `8080` and only proxies GitHub code search. See [Pages local development](https://developers.cloudflare.com/pages/functions/local-development/) and [local secrets](https://developers.cloudflare.com/pages/functions/bindings/#local-development-with-secrets). +Omit the OAuth configuration and export for a preview without GitHub OAuth. Open `http://localhost:8788/conwnet/github1s`. See [Pages local development](https://developers.cloudflare.com/pages/functions/local-development/) and [local secrets](https://developers.cloudflare.com/pages/functions/bindings/#local-development-with-secrets). ## Other static hosts diff --git a/docs/development.md b/docs/development.md index b66663f99..7512f4710 100644 --- a/docs/development.md +++ b/docs/development.md @@ -25,7 +25,7 @@ The install step also installs dependencies for the local extensions. Watch mode Wait for the application and both extensions to finish compiling, then open [localhost:8080/conwnet/github1s](http://localhost:8080/conwnet/github1s). The development server uses port `8080` and writes generated assets to `dist/`. -GitHub code search is proxied by the development server. OAuth callback Functions are not run by `npm run watch`; use a manually supplied token for repository authentication or follow the [Pages development instructions](deployment.md#preview-pages-functions-locally). +OAuth callback Functions are not run by `npm run watch`; use a manually supplied token for repository authentication or follow the [Pages development instructions](deployment.md#preview-pages-functions-locally). ## Build the application diff --git a/tests/__tests__/__image_snapshots__/index-test-ts-should-load-successfully-1-snap.png b/tests/__tests__/__image_snapshots__/index-test-ts-should-load-successfully-1-snap.png index eb2358883..271d4ad03 100644 Binary files a/tests/__tests__/__image_snapshots__/index-test-ts-should-load-successfully-1-snap.png and b/tests/__tests__/__image_snapshots__/index-test-ts-should-load-successfully-1-snap.png differ diff --git a/tests/__tests__/__image_snapshots__/index-test-ts-should-open-file-correctly-1-snap.png b/tests/__tests__/__image_snapshots__/index-test-ts-should-open-file-correctly-1-snap.png index 4b239f696..1056d3f3c 100644 Binary files a/tests/__tests__/__image_snapshots__/index-test-ts-should-open-file-correctly-1-snap.png and b/tests/__tests__/__image_snapshots__/index-test-ts-should-open-file-correctly-1-snap.png differ diff --git a/tests/__tests__/index.test.ts b/tests/__tests__/index.test.ts index e1fd01bf5..bf9210dd5 100644 --- a/tests/__tests__/index.test.ts +++ b/tests/__tests__/index.test.ts @@ -62,10 +62,11 @@ it('should load successfully', async () => { it('should open file correctly', async () => { await page.goto(`${BASE_URL}/conwnet/github1s`); - await page.waitForTimeout(3000); + await page.waitForSelector('iframe.webview.ready'); await page.click('[aria-label="~/tsconfig.json"]'); await page.click('[data-resource-name="tsconfig.json"]'); - await page.waitForTimeout(3000); + await page.waitForSelector('[role="tab"][aria-selected="true"][data-resource-name="tsconfig.json"]'); + await page.waitForSelector('.monaco-editor[data-uri="github1s:/tsconfig.json"] .view-lines'); const image = await page.screenshot(); expect(image).toMatchImageSnapshot(matchImageSnapshotOptions); diff --git a/webpack.config.js b/webpack.config.js index cab06fade..1edba9575 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -46,6 +46,7 @@ const devVscodeStatic = [ export default (env, argv) => { const devMode = argv.mode === 'development'; const devVscode = !!process.env.DEV_VSCODE; + const ciGithubProxy = devMode && process.env.CI === 'true' && !!process.env.GITHUB_TOKEN; const minifyCSS = (code) => (devMode ? code : new CleanCSS().minify(code).styles); const minifyJS = (code) => (devMode ? code : UglifyJS.minify(code).code); const availableLanguages = devVscode ? [] : fs.readdirSync(path.join(vscodeWebPath, 'nls')); @@ -94,24 +95,31 @@ export default (env, argv) => { ], performance: false, devServer: { + host: ciGithubProxy ? 'localhost' : undefined, port: 8080, proxy: [ { - context: ['/api/github/search/code'], + // Used by code search and by CI builds that point GITHUB_API_PREFIX here. + context: (pathname, req) => pathname.startsWith('/api/github/'), target: 'https://api.github.com', changeOrigin: true, + followRedirects: false, pathRewrite: { '^/api/github': '' }, headers: { 'user-agent': 'GitHub1s' }, on: { proxyReq: (proxyReq) => { proxyReq.removeHeader('cookie'); proxyReq.removeHeader('origin'); + if (ciGithubProxy) { + // Set up credentials for the CI environment to avoid GitHub API rate limits. + proxyReq.setHeader('authorization', `Bearer ${process.env.GITHUB_TOKEN}`); + } }, }, }, ], liveReload: false, - allowedHosts: 'all', + allowedHosts: ciGithubProxy ? 'auto' : 'all', client: { overlay: false }, devMiddleware: { writeToDisk: true }, static: devVscode ? devVscodeStatic : [],