api-browser-window-affinity-spec.ts 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import { expect } from 'chai';
  2. import * as path from 'path';
  3. import { ipcMain, BrowserWindow, WebPreferences, app } from 'electron/main';
  4. import { closeWindow } from './window-helpers';
  5. import { emittedOnce } from './events-helpers';
  6. describe('BrowserWindow with affinity module', () => {
  7. const fixtures = path.resolve(__dirname, '..', 'spec', 'fixtures');
  8. const myAffinityName = 'myAffinity';
  9. const myAffinityNameUpper = 'MYAFFINITY';
  10. const anotherAffinityName = 'anotherAffinity';
  11. before(() => {
  12. app.allowRendererProcessReuse = false;
  13. });
  14. after(() => {
  15. app.allowRendererProcessReuse = true;
  16. });
  17. async function createWindowWithWebPrefs (webPrefs: WebPreferences) {
  18. const w = new BrowserWindow({
  19. show: false,
  20. width: 400,
  21. height: 400,
  22. webPreferences: webPrefs || {}
  23. });
  24. await w.loadFile(path.join(fixtures, 'api', 'blank.html'));
  25. return w;
  26. }
  27. function testAffinityProcessIds (name: string, webPreferences: WebPreferences = {}) {
  28. describe(name, () => {
  29. let mAffinityWindow: BrowserWindow;
  30. before(async () => {
  31. mAffinityWindow = await createWindowWithWebPrefs({ affinity: myAffinityName, ...webPreferences });
  32. });
  33. after(async () => {
  34. await closeWindow(mAffinityWindow, { assertNotWindows: false });
  35. mAffinityWindow = null as unknown as BrowserWindow;
  36. });
  37. it('should have a different process id than a default window', async () => {
  38. const w = await createWindowWithWebPrefs({ ...webPreferences });
  39. const affinityID = mAffinityWindow.webContents.getOSProcessId();
  40. const wcID = w.webContents.getOSProcessId();
  41. expect(affinityID).to.not.equal(wcID, 'Should have different OS process IDs');
  42. await closeWindow(w, { assertNotWindows: false });
  43. });
  44. it(`should have a different process id than a window with a different affinity '${anotherAffinityName}'`, async () => {
  45. const w = await createWindowWithWebPrefs({ affinity: anotherAffinityName, ...webPreferences });
  46. const affinityID = mAffinityWindow.webContents.getOSProcessId();
  47. const wcID = w.webContents.getOSProcessId();
  48. expect(affinityID).to.not.equal(wcID, 'Should have different OS process IDs');
  49. await closeWindow(w, { assertNotWindows: false });
  50. });
  51. it(`should have the same OS process id than a window with the same affinity '${myAffinityName}'`, async () => {
  52. const w = await createWindowWithWebPrefs({ affinity: myAffinityName, ...webPreferences });
  53. const affinityID = mAffinityWindow.webContents.getOSProcessId();
  54. const wcID = w.webContents.getOSProcessId();
  55. expect(affinityID).to.equal(wcID, 'Should have the same OS process ID');
  56. await closeWindow(w, { assertNotWindows: false });
  57. });
  58. it(`should have the same OS process id than a window with an equivalent affinity '${myAffinityNameUpper}' (case insensitive)`, async () => {
  59. const w = await createWindowWithWebPrefs({ affinity: myAffinityNameUpper, ...webPreferences });
  60. const affinityID = mAffinityWindow.webContents.getOSProcessId();
  61. const wcID = w.webContents.getOSProcessId();
  62. expect(affinityID).to.equal(wcID, 'Should have the same OS process ID');
  63. await closeWindow(w, { assertNotWindows: false });
  64. });
  65. });
  66. }
  67. testAffinityProcessIds(`BrowserWindow with an affinity '${myAffinityName}'`);
  68. testAffinityProcessIds(`BrowserWindow with an affinity '${myAffinityName}' and sandbox enabled`, { sandbox: true });
  69. testAffinityProcessIds(`BrowserWindow with an affinity '${myAffinityName}' and nativeWindowOpen enabled`, { nativeWindowOpen: true });
  70. describe('BrowserWindow with an affinity : nodeIntegration=false', () => {
  71. const preload = path.join(fixtures, 'module', 'send-later.js');
  72. const affinityWithNodeTrue = 'affinityWithNodeTrue';
  73. const affinityWithNodeFalse = 'affinityWithNodeFalse';
  74. async function testNodeIntegration (present: boolean) {
  75. const [, typeofProcess, typeofBuffer] = await emittedOnce(ipcMain, 'answer');
  76. if (present) {
  77. expect(typeofProcess).to.not.equal('undefined');
  78. expect(typeofBuffer).to.not.equal('undefined');
  79. } else {
  80. expect(typeofProcess).to.equal('undefined');
  81. expect(typeofBuffer).to.equal('undefined');
  82. }
  83. }
  84. it('disables node integration when specified to false', async () => {
  85. const [, w] = await Promise.all([
  86. testNodeIntegration(false),
  87. createWindowWithWebPrefs({
  88. affinity: affinityWithNodeTrue,
  89. preload,
  90. nodeIntegration: false,
  91. contextIsolation: false
  92. })
  93. ]);
  94. await closeWindow(w, { assertNotWindows: false });
  95. });
  96. it('allows nodeIntegration to enable in second window with the same affinity', async () => {
  97. const [, w1] = await Promise.all([
  98. testNodeIntegration(false),
  99. createWindowWithWebPrefs({
  100. affinity: affinityWithNodeTrue,
  101. preload,
  102. nodeIntegration: false,
  103. contextIsolation: false
  104. })
  105. ]);
  106. const [, w2] = await Promise.all([
  107. testNodeIntegration(true),
  108. createWindowWithWebPrefs({
  109. affinity: affinityWithNodeTrue,
  110. preload,
  111. nodeIntegration: true,
  112. contextIsolation: false
  113. })
  114. ]);
  115. await Promise.all([
  116. closeWindow(w1, { assertNotWindows: false }),
  117. closeWindow(w2, { assertNotWindows: false })
  118. ]);
  119. });
  120. it('enables node integration when specified to true', async () => {
  121. const [, w] = await Promise.all([
  122. testNodeIntegration(true),
  123. createWindowWithWebPrefs({
  124. affinity: affinityWithNodeFalse,
  125. preload,
  126. nodeIntegration: true,
  127. contextIsolation: false
  128. })
  129. ]);
  130. await closeWindow(w, { assertNotWindows: false });
  131. });
  132. it('allows nodeIntegration to disable in second window with the same affinity', async () => {
  133. const [, w1] = await Promise.all([
  134. testNodeIntegration(true),
  135. createWindowWithWebPrefs({
  136. affinity: affinityWithNodeFalse,
  137. preload,
  138. nodeIntegration: true,
  139. contextIsolation: false
  140. })
  141. ]);
  142. const [, w2] = await Promise.all([
  143. testNodeIntegration(false),
  144. createWindowWithWebPrefs({
  145. affinity: affinityWithNodeFalse,
  146. preload,
  147. nodeIntegration: false,
  148. contextIsolation: false
  149. })
  150. ]);
  151. await Promise.all([
  152. closeWindow(w1, { assertNotWindows: false }),
  153. closeWindow(w2, { assertNotWindows: false })
  154. ]);
  155. });
  156. });
  157. });