Initial commit: opencode_bridge JupyterLab extension (Slices 1-3.5)
A JupyterLab extension that bridges the cell UI to a local OpenCode Serve process. The extension is a dual package: a Python server extension exposed under /opencode-bridge/*, plus a TypeScript frontend that registers per-cell toolbars. Backend (Python, tornado) - Slice 1: config + auth + OpenCode HTTP client (tornado.httpclient, no aiohttp). 4 settings in schema/plugin.json (url, user, password, request timeout). - Slice 2: handlers for /hello, /health, /providers, /edit. - Slice 2.1 (correction): SessionManager with 1 notebook = 1 session mapping, async-safe via per-path locks, 404 recovery via invalidate(). Two new endpoints: GET /sessions, DELETE /session?notebook=<path>. - 32 pytest tests pass. Frontend (TypeScript, JupyterLab 4.6) - src/types.ts: CellContext, OpenCodeRequest/Response, OpenCodeSettings. - src/context/cell_context.ts: extract CellContext from a CodeCell + its parent NotebookPanel, structured error collection. - src/api/opencode_client.ts: callOpenCodeEdit, callOpenCodeProviders. - src/components/opencode_cell_footer.ts: OpenCodeCellFooter Widget implementing ICellFooter with 3 buttons (optimize / fix / edit), resolved via this.parent instanceof CodeCell. NOT cellToolbar (does not exist in JL 4.6) and NOT Widget.findParent (removed in @lumino/widgets 2.x). - src/components/opencode_cell_factory.ts: Cell.ContentFactory subclass returning the OpenCodeCellFooter. - src/components/opencode_installer.ts: installOpenCodeEverywhere patches every notebook (existing + new) to use the custom factory. - src/index.ts: registers the factory, loads settings, fetches /providers on activation and logs the list to the console. - 23 jest tests pass (mocked JupyterLab boundary, pnpm path safe). Settings - 6 fields: 3 auth (url/user/password) + 1 timeout + 2 model selection (provider/model). Provider list is fetched at startup from /opencode-bridge/providers and printed to the browser console so users can copy values into Settings Editor. Docs - design.md: 6 sections covering architecture, UI flow, API contract, TS skeletons, session management (v0.2.1 correction), and provider/model selection (v0.2.2 addition). - CLAUDE.md: agent guidance for working in this repo. - TODO.md: remaining work for Slices 4-7 + v0.4+ backlog. CI - Gitea release workflow at .github/workflows/build.yml. - Bark notification helper (non-fatal on failure). Generated artefacts ignored: opencode_bridge/labextension/, _version.py, *.tsbuildinfo, junit.xml, test.ipynb scratch notebook.
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
# Integration Testing
|
||||
|
||||
This folder contains the integration tests of the extension.
|
||||
|
||||
They are defined using [Playwright](https://playwright.dev/docs/intro) test runner
|
||||
and [Galata](https://github.com/jupyterlab/jupyterlab/tree/main/galata) helper.
|
||||
|
||||
The Playwright configuration is defined in [playwright.config.js](./playwright.config.js).
|
||||
|
||||
The JupyterLab server configuration to use for the integration test is defined
|
||||
in [jupyter_server_test_config.py](./jupyter_server_test_config.py).
|
||||
|
||||
The default configuration will produce video for failing tests and an HTML report.
|
||||
|
||||
> There is a UI mode that you may like; see [that video](https://www.youtube.com/watch?v=jF0yA-JLQW0).
|
||||
|
||||
## Run the tests
|
||||
|
||||
> All commands are assumed to be executed from the root directory
|
||||
|
||||
To run the tests, you need to:
|
||||
|
||||
1. Compile the extension:
|
||||
|
||||
```sh
|
||||
jlpm install
|
||||
jlpm build:prod
|
||||
```
|
||||
|
||||
> Check the extension is installed in JupyterLab.
|
||||
|
||||
2. Install test dependencies (needed only once):
|
||||
|
||||
```sh
|
||||
cd ./ui-tests
|
||||
jlpm install
|
||||
jlpm playwright install
|
||||
cd ..
|
||||
```
|
||||
|
||||
3. Execute the [Playwright](https://playwright.dev/docs/intro) tests:
|
||||
|
||||
```sh
|
||||
cd ./ui-tests
|
||||
jlpm playwright test
|
||||
```
|
||||
|
||||
Test results will be shown in the terminal. In case of any test failures, the test report
|
||||
will be opened in your browser at the end of the tests execution; see
|
||||
[Playwright documentation](https://playwright.dev/docs/test-reporters#html-reporter)
|
||||
for configuring that behavior.
|
||||
|
||||
## Update the tests snapshots
|
||||
|
||||
> All commands are assumed to be executed from the root directory
|
||||
|
||||
If you are comparing snapshots to validate your tests, you may need to update
|
||||
the reference snapshots stored in the repository. To do that, you need to:
|
||||
|
||||
1. Compile the extension:
|
||||
|
||||
```sh
|
||||
jlpm install
|
||||
jlpm build:prod
|
||||
```
|
||||
|
||||
> Check the extension is installed in JupyterLab.
|
||||
|
||||
2. Install test dependencies (needed only once):
|
||||
|
||||
```sh
|
||||
cd ./ui-tests
|
||||
jlpm install
|
||||
jlpm playwright install
|
||||
cd ..
|
||||
```
|
||||
|
||||
3. Execute the [Playwright](https://playwright.dev/docs/intro) command:
|
||||
|
||||
```sh
|
||||
cd ./ui-tests
|
||||
jlpm playwright test -u
|
||||
```
|
||||
|
||||
> Some discrepancy may occurs between the snapshots generated on your computer and
|
||||
> the one generated on the CI. To ease updating the snapshots on a PR, you can
|
||||
> type `please update playwright snapshots` to trigger the update by a bot on the CI.
|
||||
> Once the bot has computed new snapshots, it will commit them to the PR branch.
|
||||
|
||||
## Create tests
|
||||
|
||||
> All commands are assumed to be executed from the root directory
|
||||
|
||||
To create tests, the easiest way is to use the code generator tool of playwright:
|
||||
|
||||
1. Compile the extension:
|
||||
|
||||
```sh
|
||||
jlpm install
|
||||
jlpm build:prod
|
||||
```
|
||||
|
||||
> Check the extension is installed in JupyterLab.
|
||||
|
||||
2. Install test dependencies (needed only once):
|
||||
|
||||
```sh
|
||||
cd ./ui-tests
|
||||
jlpm install
|
||||
jlpm playwright install
|
||||
cd ..
|
||||
```
|
||||
|
||||
3. Start the server:
|
||||
|
||||
```sh
|
||||
cd ./ui-tests
|
||||
jlpm start
|
||||
```
|
||||
|
||||
4. Execute the [Playwright code generator](https://playwright.dev/docs/codegen) in **another terminal**:
|
||||
|
||||
```sh
|
||||
cd ./ui-tests
|
||||
jlpm playwright codegen localhost:8888
|
||||
```
|
||||
|
||||
## Debug tests
|
||||
|
||||
> All commands are assumed to be executed from the root directory
|
||||
|
||||
To debug tests, a good way is to use the inspector tool of playwright:
|
||||
|
||||
1. Compile the extension:
|
||||
|
||||
```sh
|
||||
jlpm install
|
||||
jlpm build:prod
|
||||
```
|
||||
|
||||
> Check the extension is installed in JupyterLab.
|
||||
|
||||
2. Install test dependencies (needed only once):
|
||||
|
||||
```sh
|
||||
cd ./ui-tests
|
||||
jlpm install
|
||||
jlpm playwright install
|
||||
cd ..
|
||||
```
|
||||
|
||||
3. Execute the Playwright tests in [debug mode](https://playwright.dev/docs/debug):
|
||||
|
||||
```sh
|
||||
cd ./ui-tests
|
||||
jlpm playwright test --debug
|
||||
```
|
||||
|
||||
## Upgrade Playwright and the browsers
|
||||
|
||||
To update the web browser versions, you must update the package `@playwright/test`:
|
||||
|
||||
```sh
|
||||
cd ./ui-tests
|
||||
jlpm up "@playwright/test"
|
||||
jlpm playwright install
|
||||
```
|
||||
@@ -0,0 +1,12 @@
|
||||
"""Server configuration for integration tests.
|
||||
|
||||
!! Never use this configuration in production because it
|
||||
opens the server to the world and provide access to JupyterLab
|
||||
JavaScript objects through the global window variable.
|
||||
"""
|
||||
from jupyterlab.galata import configure_jupyter_server
|
||||
|
||||
configure_jupyter_server(c)
|
||||
|
||||
# Uncomment to set server log level to debug level
|
||||
# c.ServerApp.log_level = "DEBUG"
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "opencode_bridge-ui-tests",
|
||||
"version": "1.0.0",
|
||||
"description": "JupyterLab opencode_bridge Integration Tests",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "jupyter lab --config jupyter_server_test_config.py",
|
||||
"test": "jlpm playwright test",
|
||||
"test:update": "jlpm playwright test --update-snapshots"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@jupyterlab/galata": "^5.0.5",
|
||||
"@playwright/test": "^1.60.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Configuration for Playwright using default from @jupyterlab/galata
|
||||
*/
|
||||
const baseConfig = require('@jupyterlab/galata/lib/playwright-config');
|
||||
|
||||
module.exports = {
|
||||
...baseConfig,
|
||||
webServer: {
|
||||
command: 'jlpm start',
|
||||
url: 'http://localhost:8888/lab',
|
||||
timeout: 120 * 1000,
|
||||
reuseExistingServer: !process.env.CI
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
import { expect, test } from '@jupyterlab/galata';
|
||||
|
||||
/**
|
||||
* Don't load JupyterLab webpage before running the tests.
|
||||
* This is required to ensure we capture all log messages.
|
||||
*/
|
||||
test.use({ autoGoto: false });
|
||||
|
||||
test('should emit an activation console message', async ({ page }) => {
|
||||
const logs: string[] = [];
|
||||
|
||||
page.on('console', message => {
|
||||
logs.push(message.text());
|
||||
});
|
||||
|
||||
await page.goto();
|
||||
|
||||
expect(
|
||||
logs.filter(s => s === 'JupyterLab extension opencode_bridge is activated!')
|
||||
).toHaveLength(1);
|
||||
});
|
||||
Reference in New Issue
Block a user