Skip to content

Commit

Permalink
test and snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
c298lee committed Jan 15, 2024
1 parent 155715f commit 301dbf4
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;
window.Replay = new Sentry.Replay({
flushMinDelay: 50,
flushMaxDelay: 50,
minReplayDuration: 0,
});

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
sampleRate: 0,
replaysSessionSampleRate: 1.0,
replaysOnErrorSampleRate: 0.0,
debug: true,

integrations: [window.Replay, new Sentry.ReplayCanvas({ enableManualSnapshot: true })],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<canvas id="canvas" width="150" height="150"></canvas>
<button id="draw">Draw</button>
</body>


<script>
function draw() {
const canvas = document.getElementById("canvas");
if (canvas.getContext) {
console.log('has canvas')
const ctx = canvas.getContext("2d");

ctx.fillRect(25, 25, 100, 100);
ctx.clearRect(45, 45, 60, 60);
ctx.strokeRect(50, 50, 50, 50);
}
}
document.getElementById('draw').addEventListener('click', draw);
</script>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../../../utils/fixtures';
import { getReplayRecordingContent, shouldSkipReplayTest, waitForReplayRequest } from '../../../../utils/replayHelpers';

sentryTest('can manually snapshot canvas', async ({ getLocalTestUrl, page, browserName }) => {
if (shouldSkipReplayTest() || browserName === 'webkit') {
sentryTest.skip();
}

const reqPromise0 = waitForReplayRequest(page, 0);
const reqPromise1 = waitForReplayRequest(page, 1);
const reqPromise2 = waitForReplayRequest(page, 2);
const reqPromise3 = waitForReplayRequest(page, 3);

await page.route('https://dsn.ingest.sentry.io/**/*', route => {
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ id: 'test-id' }),
});
});

const url = await getLocalTestUrl({ testDir: __dirname });

await page.goto(url);
await reqPromise0;
await Promise.all([page.click('#draw'), reqPromise1]);

const { incrementalSnapshots } = getReplayRecordingContent(await reqPromise2);
expect(incrementalSnapshots).toEqual([]);

await page.evaluate(() => {
(window as any).Sentry.getClient().getIntegrationById('ReplayCanvas').snapshot();
});

const { incrementalSnapshots:incrementalSnapshotsManual } = getReplayRecordingContent(await reqPromise3);
expect(incrementalSnapshotsManual).toEqual(
expect.arrayContaining([
{
data: {
commands: [
{
args: [0, 0, 150, 150],
property: 'clearRect',
},
{
args: [
{
args: [
{
data: [
{
base64: expect.any(String),
rr_type: 'ArrayBuffer',
},
],
rr_type: 'Blob',
type: 'image/webp',
},
],
rr_type: 'ImageBitmap',
},
0,
0,
],
property: 'drawImage',
},
],
id: 9,
source: 9,
type: 0,
},
timestamp: 0,
type: 3,
},
]),
);
});
17 changes: 9 additions & 8 deletions packages/replay-canvas/src/canvas.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { CanvasManager } from '@sentry-internal/rrweb';
import { convertIntegrationFnToClass } from '@sentry/core';
import type { CanvasManagerInterface, CanvasManagerOptions } from '@sentry/replay';
import type { CanvasManagerOptions } from '@sentry/replay';
import type { IntegrationFn } from '@sentry/types';

interface ReplayCanvasOptions {
enableManualSnapshot?: boolean;
quality: 'low' | 'medium' | 'high';
}

type GetCanvasManager = (options: CanvasManagerOptions) => CanvasManagerInterface;
type GetCanvasManager = (options: CanvasManagerOptions) => void;
export interface ReplayCanvasIntegrationOptions {
enableManualSnapshot?: boolean;
recordCanvas: true;
Expand Down Expand Up @@ -60,27 +60,28 @@ const INTEGRATION_NAME = 'ReplayCanvas';
const replayCanvasIntegration = ((options: Partial<ReplayCanvasOptions> = {}) => {
const _canvasOptions = {
quality: options.quality || 'medium',
enableManualSnapshot: options.enableManualSnapshot,
};

let _canvasManager: CanvasManager;
let canvasManagerResolve: (value: CanvasManager) => void;
const _canvasManager: Promise<CanvasManager> = new Promise((resolve) => canvasManagerResolve = resolve);

return {
name: INTEGRATION_NAME,
// eslint-disable-next-line @typescript-eslint/no-empty-function
setupOnce() {},
getOptions(): ReplayCanvasIntegrationOptions {
const { quality } = _canvasOptions;
const { quality, enableManualSnapshot } = _canvasOptions;

return {
enableManualSnapshot: options.enableManualSnapshot,
recordCanvas: true,
getCanvasManager: (options: CanvasManagerOptions) => (_canvasManager = new CanvasManager(options)),
getCanvasManager: (options: CanvasManagerOptions) => (canvasManagerResolve(new CanvasManager({ ...options, isManualSnapshot: enableManualSnapshot } ))),
...(CANVAS_QUALITY[quality || 'medium'] || CANVAS_QUALITY.medium),
};
},
async snapshot(canvasElement?: HTMLCanvasElement) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
_canvasManager.snapshot(canvasElement);
const canvasManager = await _canvasManager;
canvasManager.snapshot(canvasElement);
},
};
}) satisfies IntegrationFn;
Expand Down
1 change: 0 additions & 1 deletion packages/replay/src/replay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,6 @@ export class ReplayContainer implements ReplayContainerInterface {
onMutation: this._onMutationHandler,
...(canvasOptions
? {
isManualSnapshot: canvasOptions.enableManualSnapshot,
recordCanvas: canvasOptions.recordCanvas,
getCanvasManager: canvasOptions.getCanvasManager,
sampling: canvasOptions.sampling,
Expand Down

0 comments on commit 301dbf4

Please sign in to comment.