Fix #812 - Add support for chaining withClientHints() & withFeatureCheck()

This commit is contained in:
Faisal Salman
2025-11-28 14:39:13 +07:00
parent f1b9a12bda
commit 96e3518e2e
3 changed files with 75 additions and 17 deletions

View File

@@ -1143,25 +1143,25 @@
};
}
if (!NAVIGATOR_UADATA) {
IData.prototype.then = function (cb) {
var that = this;
var IDataResolve = function () {
for (var prop in that) {
if (that.hasOwnProperty(prop)) {
this[prop] = that[prop];
}
IData.prototype.then = function (cb) {
var that = this;
var IDataResolve = function () {
for (var prop in that) {
if (that.hasOwnProperty(prop)) {
this[prop] = that[prop];
}
};
IDataResolve.prototype = {
is : IData.prototype.is,
toString : IData.prototype.toString
};
var resolveData = new IDataResolve();
cb(resolveData);
return resolveData;
}
};
}
IDataResolve.prototype = {
is : IData.prototype.is,
toString : IData.prototype.toString,
withClientHints : IData.prototype.withClientHints,
withFeatureCheck : IData.prototype.withFeatureCheck
};
var resolveData = new IDataResolve();
cb(resolveData);
return resolveData;
};
return new IData();
};

View File

@@ -152,3 +152,45 @@ test.describe('request.headers can be passed in form of a Headers object', () =>
expect(uap.ua).toBe('myBrowser/1.0');
});
});
test.describe('Chaining withFeatureCheck() & withClientHints() in client-side development', () => {
test('Chain', async ({ page, browserName }) => {
await page.addInitScript((browserName) => {
Object.defineProperty(navigator, 'userAgent', {
value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15'
});
Object.defineProperty(navigator, 'standalone', {
value: true
});
Object.defineProperty(navigator, 'maxTouchPoints', {
value: 3
});
if (browserName == 'chromium') {
Object.defineProperty(navigator, 'userAgentData', {
value: {
brands: [],
platform: '',
mobile: false,
getHighEntropyValues: () => {
return Promise.resolve({
formFactors: 'VR'
});
}
}
});
}
}, browserName);
await page.goto(localHtml);
// @ts-ignore
const fc2ch = await page.evaluate(async () => await UAParser().withFeatureCheck().then(res => res.withClientHints()));
const ch2fc = await page.evaluate(async () => await UAParser().withClientHints().then(res => res.withFeatureCheck()));
if (browserName == 'chromium') {
expect(fc2ch).toHaveProperty('device.type', 'xr'); // overwrite by client hints
expect(ch2fc).toHaveProperty('device.type', 'tablet'); // overwrite by feature check
} else {
expect(fc2ch).toHaveProperty('device.type', 'tablet'); // no client hints found
expect(ch2fc).toHaveProperty('device.type', 'tablet');
}
});
});

View File

@@ -413,4 +413,20 @@ describe('Identify vendor & type of device from given model name', () => {
assert.strictEqual(device.type, test.expect.type);
});
});
});
describe('Chaining withClientHints() & withFeatureCheck() in server-side development', () => {
const headers = {
'user-agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15',
'sec-ch-ua-form-factors' : '"VR"'
};
const device = new UAParser(headers).getDevice();
it('Chain order: withFeatureCheck().withClientHints()', () => {
const fc2ch = device.withFeatureCheck().withClientHints();
assert.strictEqual(fc2ch.type, "xr");
});
it('Chain order: withClientHints().withFeatureCheck()', () => {
const ch2fc = device.withClientHints().withFeatureCheck();
assert.strictEqual(ch2fc.type, "xr");
});
});