Skip to content

Commit 6de304e

Browse files
add tests
1 parent ab4a44b commit 6de304e

File tree

1 file changed

+371
-0
lines changed

1 file changed

+371
-0
lines changed

packages/server/test/unit/browsers/chrome_spec.js

Lines changed: 371 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const utils = require(`../../../lib/browsers/utils`)
1010
const chrome = require(`../../../lib/browsers/chrome`)
1111
const { fs } = require(`../../../lib/util/fs`)
1212
const { BrowserCriClient } = require('../../../lib/browsers/browser-cri-client')
13+
const protocol = require(`../../../lib/browsers/protocol`)
1314
const { expect } = require('chai')
1415

1516
const openOpts = {
@@ -994,4 +995,374 @@ describe('lib/browsers/chrome', () => {
994995
})
995996
})
996997
})
998+
999+
context('#_getDefaultChromePreferences', () => {
1000+
it('returns expected default preferences', () => {
1001+
const defaultPrefs = chrome._getDefaultChromePreferences()
1002+
1003+
expect(defaultPrefs).to.be.an('object')
1004+
expect(defaultPrefs).to.have.property('default')
1005+
expect(defaultPrefs).to.have.property('defaultSecure')
1006+
expect(defaultPrefs).to.have.property('localState')
1007+
})
1008+
})
1009+
1010+
context('#_getChromePreferencesWithDefaults', () => {
1011+
beforeEach(() => {
1012+
sinon.stub(fs, 'readJson')
1013+
})
1014+
1015+
afterEach(() => {
1016+
fs.readJson.restore()
1017+
})
1018+
1019+
it('merges defaults with existing preferences', () => {
1020+
const mockDefaults = {
1021+
default: {
1022+
fake_preference: {
1023+
value: 'value',
1024+
},
1025+
},
1026+
defaultSecure: {
1027+
fake_secure_preference: {
1028+
value: 'value',
1029+
},
1030+
},
1031+
localState: {
1032+
fake_local_state: {
1033+
value: 'value',
1034+
},
1035+
},
1036+
}
1037+
1038+
sinon.stub(chrome, '_getDefaultChromePreferences').returns(mockDefaults)
1039+
1040+
fs.readJson.withArgs('/foo/Default/Preferences').resolves({ existing: 'value' })
1041+
fs.readJson.withArgs('/foo/Default/Secure Preferences').resolves({ secure: 'value' })
1042+
fs.readJson.withArgs('/foo/Local State').resolves({ local: 'value' })
1043+
1044+
return chrome._getChromePreferencesWithDefaults('/foo')
1045+
.then((result) => {
1046+
expect(result).to.deep.eq(mockDefaults)
1047+
})
1048+
.finally(() => {
1049+
chrome._getDefaultChromePreferences.restore()
1050+
})
1051+
})
1052+
1053+
it('returns defaults when no existing preferences', () => {
1054+
const mockDefaults = {
1055+
default: { test: 'default' },
1056+
defaultSecure: { secure: 'default' },
1057+
localState: { local: 'default' },
1058+
}
1059+
1060+
sinon.stub(chrome, '_getDefaultChromePreferences').returns(mockDefaults)
1061+
1062+
fs.readJson.withArgs('/foo/Default/Preferences').rejects({ code: 'ENOENT' })
1063+
fs.readJson.withArgs('/foo/Default/Secure Preferences').rejects({ code: 'ENOENT' })
1064+
fs.readJson.withArgs('/foo/Local State').rejects({ code: 'ENOENT' })
1065+
1066+
return chrome._getChromePreferencesWithDefaults('/foo')
1067+
.then((result) => {
1068+
expect(result).to.deep.eq(mockDefaults)
1069+
})
1070+
.finally(() => {
1071+
chrome._getDefaultChromePreferences.restore()
1072+
})
1073+
})
1074+
})
1075+
1076+
context('#_getChromePreferences with IGNORE_CHROME_PREFERENCES', () => {
1077+
beforeEach(() => {
1078+
process.env.IGNORE_CHROME_PREFERENCES = 'true'
1079+
})
1080+
1081+
afterEach(() => {
1082+
delete process.env.IGNORE_CHROME_PREFERENCES
1083+
})
1084+
1085+
it('returns empty preferences when IGNORE_CHROME_PREFERENCES is set', () => {
1086+
return chrome._getChromePreferences('/foo')
1087+
.then((result) => {
1088+
expect(result).to.deep.eq({
1089+
default: {},
1090+
defaultSecure: {},
1091+
localState: {},
1092+
})
1093+
})
1094+
})
1095+
})
1096+
1097+
context('#_writeChromePreferences with IGNORE_CHROME_PREFERENCES', () => {
1098+
beforeEach(() => {
1099+
process.env.IGNORE_CHROME_PREFERENCES = 'true'
1100+
})
1101+
1102+
afterEach(() => {
1103+
delete process.env.IGNORE_CHROME_PREFERENCES
1104+
})
1105+
1106+
it('does not write preferences when IGNORE_CHROME_PREFERENCES is set', () => {
1107+
const outputJson = sinon.stub(fs, 'outputJson')
1108+
1109+
const originalPrefs = { default: {}, defaultSecure: {}, localState: {} }
1110+
const newPrefs = { default: { test: 'value' }, defaultSecure: {}, localState: {} }
1111+
1112+
return chrome._writeChromePreferences('/foo', originalPrefs, newPrefs)
1113+
.then(() => {
1114+
expect(outputJson).to.not.be.called
1115+
})
1116+
})
1117+
})
1118+
1119+
context('#_mergeChromePreferences with user preferences', () => {
1120+
it('merges user preferences with defaults correctly', () => {
1121+
const defaultPrefs = chrome._getDefaultChromePreferences()
1122+
const userPrefs = {
1123+
default: {
1124+
fake_preference: {
1125+
value: 'value',
1126+
},
1127+
newSetting: 'userValue', // User adds new setting
1128+
},
1129+
defaultSecure: {
1130+
fake_secure_preference: {
1131+
value: 'value',
1132+
},
1133+
},
1134+
localState: {
1135+
fake_local_state: {
1136+
value: 'value',
1137+
},
1138+
newLocalSetting: 'userValue', // User adds new setting
1139+
},
1140+
}
1141+
1142+
const result = chrome._mergeChromePreferences(defaultPrefs, userPrefs)
1143+
1144+
expect(result.default).to.deep.eq({
1145+
fake_preference: {
1146+
value: 'value',
1147+
},
1148+
newSetting: 'userValue', // User addition
1149+
})
1150+
1151+
expect(result.localState).to.deep.eq({
1152+
fake_local_state: {
1153+
value: 'value',
1154+
},
1155+
newLocalSetting: 'userValue', // User addition
1156+
})
1157+
})
1158+
1159+
it('handles preference deletion with null values', () => {
1160+
const originalPrefs = {
1161+
default: {
1162+
keepThis: 'value',
1163+
deleteThis: 'value',
1164+
},
1165+
defaultSecure: {
1166+
keepThis: 'value',
1167+
deleteThis: 'value',
1168+
},
1169+
localState: {
1170+
keepThis: 'value',
1171+
deleteThis: 'value',
1172+
},
1173+
}
1174+
1175+
const newPrefs = {
1176+
default: {
1177+
deleteThis: null, // Should be deleted
1178+
addThis: 'newValue',
1179+
},
1180+
defaultSecure: {
1181+
deleteThis: null, // Should be deleted
1182+
},
1183+
localState: {
1184+
deleteThis: null, // Should be deleted
1185+
addThis: 'newValue',
1186+
},
1187+
}
1188+
1189+
const result = chrome._mergeChromePreferences(originalPrefs, newPrefs)
1190+
1191+
expect(result.default).to.deep.eq({
1192+
keepThis: 'value',
1193+
addThis: 'newValue',
1194+
})
1195+
1196+
expect(result.defaultSecure).to.deep.eq({
1197+
keepThis: 'value',
1198+
})
1199+
1200+
expect(result.localState).to.deep.eq({
1201+
keepThis: 'value',
1202+
addThis: 'newValue',
1203+
})
1204+
})
1205+
})
1206+
1207+
context('#_getChromePreferences error handling', () => {
1208+
beforeEach(() => {
1209+
sinon.stub(fs, 'readJson')
1210+
})
1211+
1212+
afterEach(() => {
1213+
fs.readJson.restore()
1214+
})
1215+
1216+
it('handles corrupted preference files gracefully', () => {
1217+
fs.readJson.withArgs('/foo/Default/Preferences').rejects({ code: 'ENOENT' })
1218+
fs.readJson.withArgs('/foo/Default/Secure Preferences').rejects(new Error('Invalid JSON'))
1219+
fs.readJson.withArgs('/foo/Local State').resolves({ valid: 'data' })
1220+
1221+
return chrome._getChromePreferences('/foo')
1222+
.then(() => {
1223+
expect.fail('Should have thrown an error for corrupted file')
1224+
})
1225+
.catch((err) => {
1226+
expect(err.message).to.include('Invalid JSON')
1227+
})
1228+
})
1229+
1230+
it('handles missing files gracefully', () => {
1231+
fs.readJson.withArgs('/foo/Default/Preferences').rejects({ code: 'ENOENT' })
1232+
fs.readJson.withArgs('/foo/Default/Secure Preferences').rejects({ code: 'ENOENT' })
1233+
fs.readJson.withArgs('/foo/Local State').rejects({ code: 'ENOENT' })
1234+
1235+
return chrome._getChromePreferences('/foo')
1236+
.then((result) => {
1237+
expect(result).to.deep.eq({
1238+
default: {},
1239+
defaultSecure: {},
1240+
localState: {},
1241+
})
1242+
})
1243+
})
1244+
})
1245+
1246+
context('#open integration with preferences', () => {
1247+
beforeEach(function () {
1248+
// Mock all the dependencies
1249+
this.pageCriClient = {
1250+
send: sinon.stub().resolves(),
1251+
Page: { screencastFrame: sinon.stub().returns() },
1252+
close: sinon.stub().resolves(),
1253+
on: sinon.stub(),
1254+
}
1255+
1256+
this.browserCriClient = {
1257+
attachToTargetUrl: sinon.stub().resolves(this.pageCriClient),
1258+
close: sinon.stub().resolves(),
1259+
getWebSocketDebuggerUrl: sinon.stub().returns('ws://debugger'),
1260+
resetBrowserTargets: sinon.stub().resolves(),
1261+
}
1262+
1263+
this.automation = {
1264+
push: sinon.stub(),
1265+
use: sinon.stub().returns(),
1266+
onServiceWorkerClientEvent: sinon.stub(),
1267+
}
1268+
1269+
this.launchedBrowser = {
1270+
kill: sinon.stub().returns(),
1271+
}
1272+
1273+
sinon.stub(chrome, '_writeExtension').resolves('/path/to/ext')
1274+
sinon.stub(BrowserCriClient, 'create').resolves(this.browserCriClient)
1275+
sinon.stub(utils, 'getProfileDir').returns('/profile/dir')
1276+
sinon.stub(utils, 'ensureCleanCache').resolves('/profile/dir/CypressCache')
1277+
sinon.stub(utils, 'initializeCDP').resolves()
1278+
sinon.stub(utils, 'getDefaultLaunchOptions').returns({ args: [], preferences: null })
1279+
sinon.stub(utils, 'executeBeforeBrowserLaunch').resolves({ args: [], preferences: null })
1280+
sinon.stub(utils, 'executeAfterBrowserLaunch').resolves()
1281+
sinon.stub(protocol, 'getRemoteDebuggingPort').resolves(50505)
1282+
sinon.stub(launch, 'launch').resolves(this.launchedBrowser)
1283+
1284+
this.readJson = sinon.stub(fs, 'readJson')
1285+
this.readJson.withArgs('/profile/dir/Default/Preferences').rejects({ code: 'ENOENT' })
1286+
this.readJson.withArgs('/profile/dir/Default/Secure Preferences').rejects({ code: 'ENOENT' })
1287+
this.readJson.withArgs('/profile/dir/Local State').rejects({ code: 'ENOENT' })
1288+
1289+
this.outputJson = sinon.stub(fs, 'outputJson')
1290+
this.outputJson.resolves()
1291+
})
1292+
1293+
afterEach(function () {
1294+
launch.launch.restore()
1295+
protocol.getRemoteDebuggingPort.restore()
1296+
fs.readJson.restore()
1297+
fs.outputJson.restore()
1298+
})
1299+
1300+
it('writes default preferences during browser launch', async function () {
1301+
await chrome.open({ isHeadless: true }, 'http://localhost:3000', openOpts, this.automation)
1302+
1303+
// Verify that default preferences were written
1304+
expect(this.outputJson).to.have.been.calledWith(
1305+
'/profile/dir/Default/Preferences',
1306+
sinon.match({
1307+
fake_preference: {
1308+
value: 'value',
1309+
},
1310+
}),
1311+
)
1312+
1313+
expect(this.outputJson).to.have.been.calledWith(
1314+
'/profile/dir/Local State',
1315+
sinon.match({
1316+
fake_local_state: {
1317+
value: 'value',
1318+
},
1319+
}),
1320+
)
1321+
})
1322+
1323+
it('merges user preferences with defaults during launch', async function () {
1324+
const userPreferences = {
1325+
default: {
1326+
fake_preference: {
1327+
value: 'value',
1328+
},
1329+
customSetting: 'userValue',
1330+
},
1331+
localState: {
1332+
fake_local_state: {
1333+
value: 'value',
1334+
},
1335+
},
1336+
}
1337+
1338+
utils.executeBeforeBrowserLaunch.resolves({
1339+
args: [],
1340+
preferences: userPreferences,
1341+
})
1342+
1343+
await chrome.open({ isHeadless: true }, 'http://localhost:3000', openOpts, this.automation)
1344+
1345+
// Verify that merged preferences were written
1346+
expect(this.outputJson).to.have.been.calledWith(
1347+
'/profile/dir/Default/Preferences',
1348+
sinon.match({
1349+
fake_preference: {
1350+
value: 'value',
1351+
},
1352+
customSetting: 'userValue', // User addition
1353+
}),
1354+
)
1355+
1356+
expect(this.outputJson).to.have.been.calledWith(
1357+
'/profile/dir/Local State',
1358+
sinon.match({
1359+
browser: {
1360+
fake_local_state: {
1361+
value: 'value',
1362+
},
1363+
},
1364+
}),
1365+
)
1366+
})
1367+
})
9971368
})

0 commit comments

Comments
 (0)