Skip to content

Commit

Permalink
test: Port captureException and captureMessage tests from karma runner (
Browse files Browse the repository at this point in the history
getsentry#11412)

I want to remove the karma/mocha based tests in the browser package. To
accomplish this, I'll be porting 1 test suite a day from the old
integration tests to playwright. Today is Day 1:
`packages/browser/test/integration/suites/api.js`

We have decent coverage around singular calls to these methods, so I
just added the tests that validate calling `captureException` and
`captureMessage` multiple times.

I also fixed a spelling mistake with
`dev-packages/browser-integration-tests/suites/public-api/captureException/linkedErrors/subject.js`,
`linkedErrrors` -> `linkedErrors`

ref getsentry#11084
  • Loading branch information
AbhiPrasad authored and cadesalaberry committed Apr 19, 2024
1 parent de4d8c5 commit 1f40194
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 163 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
function bar() {
baz();
}

function foo() {
bar();
}

function foo2() {
// identical to foo, but meant for testing
// different stack frame fns w/ same stack length
bar();
}
// same error message, but different stacks means that these are considered
// different errors

// stack:
// bar
try {
bar();
} catch (e) {
Sentry.captureException(e);
}

// stack (different # frames):
// bar
// foo
try {
foo();
} catch (e) {
Sentry.captureException(e);
}

// stack (same # frames, different frames):
// bar
// foo2
try {
foo2();
} catch (e) {
Sentry.captureException(e);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';

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

sentryTest('should not reject back-to-back errors with different stack traces', async ({ getLocalTestPath, page }) => {
const url = await getLocalTestPath({ testDir: __dirname });

const eventData = await getMultipleSentryEnvelopeRequests<Event>(page, 3, { url });

// NOTE: regex because exact error message differs per-browser
expect(eventData[0].exception?.values?.[0].value).toMatch(/baz/);
expect(eventData[0].exception?.values?.[0].type).toMatch('ReferenceError');
expect(eventData[1].exception?.values?.[0].value).toMatch(/baz/);
expect(eventData[1].exception?.values?.[0].type).toMatch('ReferenceError');
expect(eventData[2].exception?.values?.[0].value).toMatch(/baz/);
expect(eventData[2].exception?.values?.[0].type).toMatch('ReferenceError');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
function throwError(message) {
// eslint-disable-next-line no-param-reassign
message = message || 'foo';
try {
throw new Error(message);
} catch (o_O) {
Sentry.captureException(o_O);
}
}

function throwRandomError() {
try {
throw new Error('Exception no ' + (Date.now() + Math.random()));
} catch (o_O) {
Sentry.captureException(o_O);
}
}

function createError() {
function nestedFunction() {
return new Error('created');
}

return nestedFunction();
}

function throwSameConsecutiveErrors(message) {
throwError(message);
throwError(message);
}

// Different exceptions, don't dedupe
for (var i = 0; i < 2; i++) {
throwRandomError();
}

// Same exceptions and same stacktrace, dedupe
for (var j = 0; j < 2; j++) {
throwError();
}

const syntheticError = createError();

// Same exception, with transaction in between, dedupe
Sentry.captureException(syntheticError);
Sentry.captureEvent({
event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2',
message: 'someMessage',
transaction: 'wat',
type: 'transaction',
});
Sentry.captureException(syntheticError);

// Same exceptions, different stacktrace (different line number), don't dedupe
throwSameConsecutiveErrors('bar');
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';

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

sentryTest('should reject duplicate, back-to-back errors from captureException', async ({ getLocalTestPath, page }) => {
const url = await getLocalTestPath({ testDir: __dirname });

const eventData = await getMultipleSentryEnvelopeRequests<Event>(page, 7, { url });

// NOTE: regex because exact error message differs per-browser
expect(eventData[0].exception?.values?.[0].value).toMatch(/Exception no \d+/);
expect(eventData[1].exception?.values?.[0].value).toMatch(/Exception no \d+/);
expect(eventData[2].exception?.values?.[0].value).toEqual('foo');
// transaction so undefined
expect(eventData[3].exception?.values?.[0].value).toEqual('created');
expect(eventData[4].exception?.values?.[0].value).toEqual(undefined);
expect(eventData[5].exception?.values?.[0].value).toEqual('bar');
expect(eventData[6].exception?.values?.[0].value).toEqual('bar');
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
attachStacktrace: true,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
function captureMessage(message) {
// eslint-disable-next-line no-param-reassign
message = message || 'message';
Sentry.captureMessage(message);
}

function captureRandomMessage() {
Sentry.captureMessage('Message no ' + (Date.now() + Math.random()));
}

function captureSameConsecutiveMessages(message) {
captureMessage(message);
captureMessage(message);
}

// Different messages, don't dedupe
for (var i = 0; i < 2; i++) {
captureRandomMessage();
}

// Same messages and same stacktrace, dedupe
for (var j = 0; j < 3; j++) {
captureMessage('same message, same stacktrace');
}

// Same messages, different stacktrace (different line number), don't dedupe
captureSameConsecutiveMessages('same message, different stacktrace');
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';

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

sentryTest(
'should reject duplicate, back-to-back messages from captureMessage when it has stacktrace',
async ({ getLocalTestPath, page }) => {
const url = await getLocalTestPath({ testDir: __dirname });

const eventData = await getMultipleSentryEnvelopeRequests<Event>(page, 5, { url });

expect(eventData[0].message).toMatch(/Message no \d+/);
expect(eventData[1].message).toMatch(/Message no \d+/);
expect(eventData[2].message).toMatch('same message, same stacktrace');
expect(eventData[3].message).toMatch('same message, different stacktrace');
expect(eventData[4].message).toMatch('same message, different stacktrace');
},
);
162 changes: 0 additions & 162 deletions packages/browser/test/integration/suites/api.js

This file was deleted.

1 change: 0 additions & 1 deletion packages/browser/test/integration/suites/shell.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ function runVariant(variant) {
* The test runner will replace each of these placeholders with the contents of the corresponding file.
*/
{{ suites/config.js }} // biome-ignore format: No trailing commas
{{ suites/api.js }} // biome-ignore format: No trailing commas
{{ suites/onerror.js }} // biome-ignore format: No trailing commas
{{ suites/onunhandledrejection.js }} // biome-ignore format: No trailing commas
{{ suites/builtins.js }} // biome-ignore format: No trailing commas
Expand Down

0 comments on commit 1f40194

Please sign in to comment.