Skip to content

Commit 0faa8df

Browse files
committed
Enhance browser detection with precise environment information
- Replace hardcoded browser info with navigator.userAgentData API to get real brand, full version (e.g. 122.0.6261.112), OS platform and version - Remove deprecated navigator.platform and raw userAgent dump - Add screen resolution, browser language, timezone and cookies to session data - Make getSystemInfo() async to support high-entropy API values - Update background.js to await getSystemInfo() and use brand for filenames - Update HTML report to display all 8 new fields with backwards compatibility for sessions stored with the old format (browser/browserVersion fields) - Update jest mocks and browserInfo.test.js to match new async API https://claude.ai/code/session_013y1QH2gkj8wg427JpzjdJe
1 parent c170ac4 commit 0faa8df

6 files changed

Lines changed: 138 additions & 50 deletions

File tree

HTMLReport/modules/reportUI.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,41 @@ export function displaySessionInfo(session) {
2020
const browserInfo = session.getBrowserInfo();
2121
const startDateTime = session.getStartDateTime();
2222

23+
const brand = browserInfo.brand || browserInfo.browser || 'N/A';
24+
const model = browserInfo.model || '';
25+
const browserLabel = model ? `${brand} (${model})` : brand;
26+
const os = browserInfo.os || 'N/A';
27+
const osVersion = browserInfo.osVersion || '';
28+
const osLabel = osVersion ? `${os} ${osVersion}` : os;
29+
2330
sessionInfo.innerHTML = `
2431
<div class="info-item">
2532
<span class="info-label">Start Date</span>
2633
<span class="info-value">${startDateTime.toLocaleString()}</span>
2734
</div>
2835
<div class="info-item">
2936
<span class="info-label">Browser</span>
30-
<span class="info-value">${browserInfo.browser} ${browserInfo.browserVersion}</span>
37+
<span class="info-value">${browserLabel}</span>
38+
</div>
39+
<div class="info-item">
40+
<span class="info-label">Version</span>
41+
<span class="info-value">${browserInfo.browserVersion || 'N/A'}</span>
3142
</div>
3243
<div class="info-item">
3344
<span class="info-label">Operating System</span>
34-
<span class="info-value">${browserInfo.os}</span>
45+
<span class="info-value">${osLabel}</span>
46+
</div>
47+
<div class="info-item">
48+
<span class="info-label">Resolution</span>
49+
<span class="info-value">${browserInfo.screenResolution || 'N/A'}</span>
50+
</div>
51+
<div class="info-item">
52+
<span class="info-label">Language</span>
53+
<span class="info-value">${browserInfo.language || 'N/A'}</span>
54+
</div>
55+
<div class="info-item">
56+
<span class="info-label">Timezone</span>
57+
<span class="info-value">${browserInfo.timezone || 'N/A'}</span>
3558
</div>
3659
<div class="info-item">
3760
<span class="info-label">Cookies</span>

background.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ async function addAnnotation(type, name, imageURL) {
504504
}
505505

506506
async function startSession() {
507-
var systemInfo = getSystemInfo();
507+
var systemInfo = await getSystemInfo();
508508
session = new Session(Date.now(), systemInfo);
509509
await saveSession();
510510
}
@@ -521,7 +521,7 @@ function exportSessionCSV() {
521521
var csvData = exportService.getCSVData();
522522

523523
var browserInfo = session.getBrowserInfo();
524-
var browserInfoString = browserInfo.browser + "_" + browserInfo.browserVersion;
524+
var browserInfoString = (browserInfo.brand || browserInfo.browser || 'Chrome') + "_" + browserInfo.browserVersion;
525525

526526
// Formatear la fecha correctamente
527527
const date = new Date(session.getStartDateTime());
@@ -552,7 +552,7 @@ function exportSessionJSon() {
552552
var jsonData = exportJSonService.getJSon(session);
553553

554554
var browserInfo = session.getBrowserInfo();
555-
var browserInfoString = browserInfo.browser + "_" + browserInfo.browserVersion;
555+
var browserInfoString = (browserInfo.brand || browserInfo.browser || 'Chrome') + "_" + browserInfo.browserVersion;
556556

557557
// Formatear la fecha correctamente
558558
const date = new Date(session.getStartDateTime());

jest.setup.js

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,41 @@ global.chrome = {
2222

2323
// Mock navigator properties used in browserInfo.js
2424
global.navigator = {
25-
...global.navigator, // Preserve existing navigator properties if any
25+
...global.navigator,
2626
platform: 'TestPlatform',
2727
userAgent: 'TestUserAgent/1.0',
2828
cookieEnabled: true,
29+
language: 'es-ES',
30+
userAgentData: {
31+
platform: 'Windows',
32+
brands: [
33+
{ brand: 'Google Chrome', version: '122' },
34+
{ brand: 'Chromium', version: '122' },
35+
{ brand: 'Not A;Brand', version: '99' }
36+
],
37+
getHighEntropyValues: jest.fn(() => Promise.resolve({
38+
fullVersionList: [
39+
{ brand: 'Google Chrome', version: '122.0.6261.112' },
40+
{ brand: 'Chromium', version: '122.0.6261.112' },
41+
{ brand: 'Not A;Brand', version: '99.0.0.0' }
42+
],
43+
platformVersion: '10.0',
44+
model: ''
45+
}))
46+
}
47+
};
48+
49+
// Mock screen properties
50+
global.screen = {
51+
width: 1920,
52+
height: 1080
53+
};
54+
55+
// Mock Intl
56+
global.Intl = {
57+
DateTimeFormat: () => ({
58+
resolvedOptions: () => ({ timeZone: 'Europe/Madrid' })
59+
})
2960
};
3061

3162

src/Session.js

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
11
import { Bug, Note, Idea, Question } from './Annotation.js';
2-
import { getSystemInfo } from './browserInfo.js';
3-
42
export class Session {
53
constructor(dateTime, browserInfo) {
6-
// Check if provided browserInfo is sufficiently complete
7-
if (browserInfo && typeof browserInfo.browser === 'string' && browserInfo.browser !== '' &&
8-
typeof browserInfo.browserVersion === 'string' && browserInfo.browserVersion !== '' &&
9-
typeof browserInfo.os === 'string' && browserInfo.os !== '') {
10-
this.BrowserInfo = browserInfo;
11-
} else {
12-
// If browserInfo is missing, null, undefined, or incomplete, get current system info
13-
this.BrowserInfo = getSystemInfo();
14-
}
4+
this.BrowserInfo = (browserInfo && typeof browserInfo === 'object') ? browserInfo : {};
155
this.StartDateTime = dateTime || Date.now(); // Provide a fallback for dateTime
166
this.annotations = [];
177
}

src/browserInfo.js

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,52 @@
1-
export function getSystemInfo() {
1+
export async function getSystemInfo() {
2+
let brand = 'Chrome';
3+
let model = '';
4+
let browserVersion = '';
5+
let os = '';
6+
let osVersion = '';
7+
8+
if (navigator.userAgentData) {
9+
os = navigator.userAgentData.platform || '';
10+
11+
try {
12+
const highEntropy = await navigator.userAgentData.getHighEntropyValues([
13+
'fullVersionList',
14+
'platformVersion',
15+
'model'
16+
]);
17+
18+
const brands = highEntropy.fullVersionList || navigator.userAgentData.brands || [];
19+
const significantBrand = brands.find(b =>
20+
!b.brand.includes('Not A') && b.brand !== 'Chromium'
21+
);
22+
if (significantBrand) {
23+
brand = significantBrand.brand;
24+
browserVersion = significantBrand.version;
25+
}
26+
27+
osVersion = highEntropy.platformVersion || '';
28+
model = highEntropy.model || '';
29+
} catch (e) {
30+
const brands = navigator.userAgentData.brands || [];
31+
const significantBrand = brands.find(b =>
32+
!b.brand.includes('Not A') && b.brand !== 'Chromium'
33+
);
34+
if (significantBrand) {
35+
brand = significantBrand.brand;
36+
browserVersion = significantBrand.version;
37+
}
38+
}
39+
}
40+
241
return {
3-
browser: "Chrome",
4-
browserVersion: chrome.runtime.getManifest().version,
5-
os: navigator.platform,
6-
osVersion: navigator.userAgent,
7-
cookies: navigator.cookieEnabled,
8-
flashVersion: "N/A" // Flash ya no se usa en navegadores modernos
42+
brand,
43+
model,
44+
browserVersion,
45+
os,
46+
osVersion,
47+
screenResolution: `${screen.width} × ${screen.height}`,
48+
language: navigator.language,
49+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
50+
cookies: navigator.cookieEnabled
951
};
10-
}
52+
}

test/spec/browserInfo.test.js

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@ import { getSystemInfo } from '../../src/browserInfo';
33
describe('getSystemInfo', () => {
44
let systemInfo;
55

6-
beforeAll(() => {
7-
// getSystemInfo relies on global mocks set in jest.setup.js
8-
// We can call it once if the global mocks are static for these tests
9-
systemInfo = getSystemInfo();
6+
beforeAll(async () => {
7+
systemInfo = await getSystemInfo();
108
});
119

1210
it('should return an object', () => {
@@ -15,42 +13,46 @@ describe('getSystemInfo', () => {
1513
});
1614

1715
it('should contain all expected keys', () => {
18-
expect(systemInfo).toHaveProperty('browser');
16+
expect(systemInfo).toHaveProperty('brand');
17+
expect(systemInfo).toHaveProperty('model');
1918
expect(systemInfo).toHaveProperty('browserVersion');
2019
expect(systemInfo).toHaveProperty('os');
2120
expect(systemInfo).toHaveProperty('osVersion');
21+
expect(systemInfo).toHaveProperty('screenResolution');
22+
expect(systemInfo).toHaveProperty('language');
23+
expect(systemInfo).toHaveProperty('timezone');
2224
expect(systemInfo).toHaveProperty('cookies');
23-
expect(systemInfo).toHaveProperty('flashVersion');
2425
});
2526

26-
it('should retrieve browser name correctly', () => {
27-
expect(systemInfo.browser).toBe('Chrome'); // Hardcoded in function
27+
it('should retrieve browser brand from userAgentData', () => {
28+
expect(systemInfo.brand).toBe('Google Chrome');
2829
});
2930

30-
it('should retrieve browser version from chrome.runtime.getManifest', () => {
31-
// Assuming jest.setup.js mocks chrome.runtime.getManifest().version to '1.0.0'
32-
expect(systemInfo.browserVersion).toBe('1.0.0');
31+
it('should retrieve full browser version from userAgentData', () => {
32+
expect(systemInfo.browserVersion).toBe('122.0.6261.112');
3333
});
3434

35-
it('should retrieve OS platform from navigator.platform', () => {
36-
// Assuming jest.setup.js mocks navigator.platform to 'TestPlatform'
37-
expect(systemInfo.os).toBe('TestPlatform');
35+
it('should retrieve OS platform from userAgentData', () => {
36+
expect(systemInfo.os).toBe('Windows');
3837
});
3938

40-
it('should retrieve OS version from navigator.userAgent', () => {
41-
// Assuming jest.setup.js mocks navigator.userAgent to 'TestUserAgent/1.0'
42-
// The function extracts this specifically, so the test should reflect that.
43-
// If getSystemInfo is more complex, this might need adjustment.
44-
// For now, assuming it directly uses navigator.userAgent for osVersion.
45-
expect(systemInfo.osVersion).toBe('TestUserAgent/1.0');
39+
it('should retrieve OS version from userAgentData high entropy values', () => {
40+
expect(systemInfo.osVersion).toBe('10.0');
4641
});
4742

48-
it('should retrieve cookie status from navigator.cookieEnabled', () => {
49-
// Assuming jest.setup.js mocks navigator.cookieEnabled to true
50-
expect(systemInfo.cookies).toBe(true);
43+
it('should retrieve screen resolution from screen dimensions', () => {
44+
expect(systemInfo.screenResolution).toBe('1920 × 1080');
45+
});
46+
47+
it('should retrieve language from navigator.language', () => {
48+
expect(systemInfo.language).toBe('es-ES');
5149
});
5250

53-
it('should report Flash version as N/A', () => {
54-
expect(systemInfo.flashVersion).toBe('N/A'); // Hardcoded in function
51+
it('should retrieve timezone from Intl', () => {
52+
expect(systemInfo.timezone).toBe('Europe/Madrid');
53+
});
54+
55+
it('should retrieve cookie status from navigator.cookieEnabled', () => {
56+
expect(systemInfo.cookies).toBe(true);
5557
});
5658
});

0 commit comments

Comments
 (0)