Skip to content

Commit

Permalink
test: Port onerror tests to playwright (#11666)
Browse files Browse the repository at this point in the history
This ports `packages/browser/test/integration/suites/onerror.js` to
playwright. Because I couldn't throw top level errors without generating
script errors, I elected to simulate `window.onerror` being called.

Co-authored-by: Lukas Stracke <lukas.stracke@sentry.io>
  • Loading branch information
AbhiPrasad and Lms24 authored Apr 18, 2024
1 parent c90048f commit b64b2ae
Show file tree
Hide file tree
Showing 19 changed files with 239 additions and 176 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
function run() {
window.onerror({
type: 'error',
otherKey: 'hi',
});
}

run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';

import { sentryTest } from '../../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers';

sentryTest(
'should catch onerror calls with non-string first argument gracefully',
async ({ getLocalTestPath, page }) => {
const url = await getLocalTestPath({ testDir: __dirname });

const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);

expect(eventData.exception?.values).toHaveLength(1);
expect(eventData.exception?.values?.[0]).toMatchObject({
type: 'Error',
value: 'Object captured as exception with keys: otherKey, type',
mechanism: {
type: 'onerror',
handled: false,
},
stacktrace: {
frames: expect.any(Array),
},
});
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
function run() {
try {
try {
foo();
} catch (e) {
Sentry.captureException(e);
throw e; // intentionally re-throw
}
} catch (e) {
// simulate window.onerror without generating a Script error
window.onerror('error', 'file.js', 1, 1, e);
}
}

run();

Sentry.captureException(new Error('error 2'));
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';

import { sentryTest } from '../../../../../utils/fixtures';
import { getMultipleSentryEnvelopeRequests } from '../../../../../utils/helpers';

sentryTest(
'should NOT catch an exception already caught [but rethrown] via Sentry.captureException',
async ({ getLocalTestPath, page }) => {
const url = await getLocalTestPath({ testDir: __dirname });

const events = await getMultipleSentryEnvelopeRequests<Event>(page, 2, { url });

expect(events[0].exception?.values).toHaveLength(1);
expect(events[0].exception?.values?.[0]).toMatchObject({
type: 'ReferenceError',
// this exact error message varies between browsers, but they should all reference 'foo'
value: expect.stringContaining('foo'),
mechanism: {
type: 'generic',
handled: true,
},
stacktrace: {
frames: expect.any(Array),
},
});

// This is not a refernece error, but another generic error
expect(events[1].exception?.values).toHaveLength(1);
expect(events[1].exception?.values?.[0]).toMatchObject({
type: 'Error',
value: 'error 2',
mechanism: {
type: 'generic',
handled: true,
},
stacktrace: {
frames: expect.any(Array),
},
});
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function run() {
try {
eval('foo{};');
} catch (e) {
// simulate window.onerror without generating a Script error
window.onerror('error', 'file.js', 1, 1, e);
}
}

run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';

import { sentryTest } from '../../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers';

sentryTest('should catch syntax errors', async ({ getLocalTestPath, page }) => {
const url = await getLocalTestPath({ testDir: __dirname });

const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);

expect(eventData.exception?.values).toHaveLength(1);
expect(eventData.exception?.values?.[0]).toMatchObject({
type: 'SyntaxError',
value: "Unexpected token '{'",
mechanism: {
type: 'onerror',
handled: false,
},
stacktrace: {
frames: expect.any(Array),
},
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function run() {
try {
throw new Error('realError');
} catch (e) {
// simulate window.onerror without generating a Script error
window.onerror('error', 'file.js', 1, 1, e);
}
}

run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';

import { sentryTest } from '../../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers';

sentryTest('should catch thrown errors', async ({ getLocalTestPath, page }) => {
const url = await getLocalTestPath({ testDir: __dirname });

const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);

expect(eventData.exception?.values).toHaveLength(1);
expect(eventData.exception?.values?.[0]).toMatchObject({
type: 'Error',
value: 'realError',
mechanism: {
type: 'onerror',
handled: false,
},
stacktrace: {
frames: expect.any(Array),
},
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function run() {
try {
throw { error: 'stuff is broken', somekey: 'ok' };
} catch (e) {
// simulate window.onerror without generating a Script error
window.onerror('error', 'file.js', 1, 1, e);
}
}

run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';

import { sentryTest } from '../../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers';

sentryTest('should catch thrown objects', async ({ getLocalTestPath, page }) => {
const url = await getLocalTestPath({ testDir: __dirname });

const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);

expect(eventData.exception?.values).toHaveLength(1);
expect(eventData.exception?.values?.[0]).toMatchObject({
type: 'Error',
value: 'Object captured as exception with keys: error, somekey',
mechanism: {
type: 'onerror',
handled: false,
},
stacktrace: {
frames: expect.any(Array),
},
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
function run() {
try {
throw 'stringError';
} catch (e) {
// simulate window.onerror without generating a Script error
window.onerror('error', 'file.js', 1, 1, e);
}
}

run();
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';

import { sentryTest } from '../../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers';

sentryTest('should catch thrown strings', async ({ getLocalTestPath, page }) => {
const url = await getLocalTestPath({ testDir: __dirname });

const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);

expect(eventData.exception?.values).toHaveLength(1);
expect(eventData.exception?.values?.[0]).toMatchObject({
type: 'Error',
value: 'stringError',
mechanism: {
type: 'onerror',
handled: false,
},
stacktrace: {
frames: expect.any(Array),
},
});

expect(eventData.exception?.values?.[0].stacktrace?.frames).toHaveLength(1);
});
13 changes: 0 additions & 13 deletions packages/browser/test/integration/subjects/console-logs.js

This file was deleted.

4 changes: 0 additions & 4 deletions packages/browser/test/integration/subjects/throw-error.js

This file was deleted.

7 changes: 0 additions & 7 deletions packages/browser/test/integration/subjects/throw-object.js

This file was deleted.

5 changes: 0 additions & 5 deletions packages/browser/test/integration/subjects/throw-string.js

This file was deleted.

Loading

0 comments on commit b64b2ae

Please sign in to comment.