grafana / grafana/plugin-tools

Bug: Scaffolded jest config's canvas stub crashes @grafana/ui components (Combobox); IntersectionObserver isn't polyfilled

Open Beginner friendly
#2,850 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
89
Forks
57
Avg merge
3d 17h
Merged PRs (30d)
37

Description

### Which package(s) does this bug affect?

- [x] Create Plugin
- [ ] ESLint Config
- [ ] Plugin Docs CLI
- [ ] Plugin Docs Parser
- [ ] Plugin E2E
- [ ] Plugin ESLint Rules
- [ ] Plugin Meta Extractor
- [ ] Plugin Types Bundler
- [ ] React detect
- [ ] Sign Plugin
- [ ] TS Config

### Package versions

```shell
7.10.0
```

### What happened?

The scaffolded `.config/jest-setup.js` sets:

`HTMLCanvasElement.prototype.getContext = () => {};`

This returns `undefined` instead of a usable canvas context. `@grafana/ui`'s `measureText` utility (used internally by `Combobox` to size its dropdown) calls `document.createElement('canvas').getContext('2d')` and then does `context.font = ...` / `context.measureText(text)`. With the scaffolded stub, `context` is `undefined`, so this throws:

`TypeError: Cannot read properties of undefined (reading 'measureText')`

Separately, jsdom doesn't implement `IntersectionObserver`, and the scaffolded setup doesn't polyfill it either. Opening a `Combobox`'s dropdown mounts its `ScrollIndicators`, which uses `IntersectionObserver`, throwing:

`ReferenceError: IntersectionObserver is not defined`

### What you expected to happen

Rendering and interacting with a `@grafana/ui` `Combobox` (and any component that uses it) inside a test using the scaffolded jest config should work out of the box, without needing to hand-roll these stubs in every plugin.

### How to reproduce it (as minimally and precisely as possible)

1. Scaffold a new plugin with `@grafana/create-plugin` (default jest config).
2. Add a test that renders any component containing a `@grafana/ui` ``, using `@testing-library/react`'s `render`.
3. Run pnpm test:ci (or jest).
4. See `TypeError: Cannot read properties of undefined (reading 'measureText')` on render, and `ReferenceError: IntersectionObserver is not defined` if the dropdown is opened.

### Environment

```shell
System:
OS: macOS 15.7.7
CPU: (14) arm64 Apple M4 Pro
Memory: 570.22 MB / 24.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 24.16.0 - ~/.nvm/versions/node/v24.16.0/bin/node
npm: 11.13.0 - ~/.nvm/versions/node/v24.16.0/bin/npm
pnpm: 11.22.0 - ~/.nvm/versions/node/v24.16.0/bin/pnpm
Browsers:
Chrome: 151.0.7922.170
Firefox: 148.0.2
Safari: 26.5.2
npmPackages:
@grafana/assistant: ^0.1.33 => 0.1.33
@grafana/data: ^13.1.1 => 13.1.1
@grafana/eslint-config: ^10.0.0 => 10.0.0
@grafana/google-sdk: ^0.6.1 => 0.6.1
@grafana/plugin-e2e: ^3.10.0 => 3.10.0
@grafana/runtime: ^13.1.1 => 13.1.1
@grafana/schema: ^13.1.1 => 13.1.1
@grafana/sign-plugin: ^3.3.3 => 3.3.3
@grafana/tsconfig: ^2.2.0 => 2.2.0
@grafana/ui: ^13.1.1 => 13.1.1
```

### Additional context

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the scaffolded .config/jest-setup.js and reproduce the issue using a minimal test that renders and opens a @grafana/ui Combobox, then run pnpm test:ci. Done means the scaffolded Jest setup supports the canvas-dependent rendering and dropdown interaction without the reported TypeError or ReferenceError.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend, testing, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.