Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2

* fix(sdk-logs): allow AnyValue attributes for logs and handle circular references [#6210](https://github.com/open-telemetry/opentelemetry-js/pull/6210) @david-luna
* based on [#5765](https://github.com/open-telemetry/opentelemetry-js/pull/5765) from @alec2435
* fix(browser-detector): use window feature detection to avoid false positives in Node.js 21+ and Bun [#6271](https://github.com/open-telemetry/opentelemetry-js/pull/6271) @fiyinfoluwa001 @overbalance

### :books: Documentation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ import { BROWSER_ATTRIBUTES, UserAgentData } from './types';
*/
class BrowserDetector implements ResourceDetector {
detect(config?: ResourceDetectionConfig): DetectedResource {
const isBrowser = typeof navigator !== 'undefined';
const isBrowser =
typeof window !== 'undefined' && typeof document !== 'undefined';

if (!isBrowser) {
return emptyResource();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
*/
import * as sinon from 'sinon';
import { browserDetector } from '../src/BrowserDetector';
import { assertEmptyResource, assertResource, describeBrowser } from './util';
import {
assertEmptyResource,
assertResource,
describeBrowser,
describeNode,
} from './util';

describeBrowser('browserDetector()', () => {
afterEach(() => {
Expand Down Expand Up @@ -69,11 +74,28 @@ describeBrowser('browserDetector()', () => {
});
});

it('should return empty resources if user agent is missing', async () => {
it('should return empty resource if userAgent is missing', async () => {
sinon.stub(globalThis, 'navigator').value({
userAgent: '',
});
const resource = browserDetector.detect();
assertEmptyResource(resource);
});
});

describeNode('browserDetector()', () => {
it('should return empty resource even if navigator is present', () => {
// Cannot use sinon.stub for non-existent properties (Node.js <=20)
Object.defineProperty(globalThis, 'navigator', {
value: {
userAgent: 'dddd',
language: 'en-US',
userAgentData: undefined,
},
configurable: true,
});

const resource = browserDetector.detect();
assertEmptyResource(resource);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,20 @@ import * as assert from 'assert';
import { BROWSER_ATTRIBUTES } from '../src/types';
import { DetectedResource } from '@opentelemetry/resources';

const isBrowser =
typeof window !== 'undefined' && typeof document !== 'undefined';

export function describeBrowser(title: string, fn: (this: Suite) => void) {
title = `Browser: ${title}`;
if (typeof process === 'object' && process.release?.name === 'node') {
if (isBrowser) {
return describe(title, fn);
}
return describe.skip(title, fn);
}

export function describeNode(title: string, fn: (this: Suite) => void) {
title = `Node.js: ${title}`;
if (isBrowser) {
return describe.skip(title, fn);
}
return describe(title, fn);
Expand Down