content-script-spec.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. const { expect } = require('chai')
  2. const { remote } = require('electron')
  3. const path = require('path')
  4. const { closeWindow } = require('./window-helpers')
  5. const { emittedNTimes } = require('./events-helpers')
  6. const { BrowserWindow, ipcMain } = remote
  7. describe('chrome extension content scripts', () => {
  8. const fixtures = path.resolve(__dirname, 'fixtures')
  9. const extensionPath = path.resolve(fixtures, 'extensions')
  10. const addExtension = (name) => BrowserWindow.addExtension(path.resolve(extensionPath, name))
  11. const removeAllExtensions = () => {
  12. Object.keys(BrowserWindow.getExtensions()).map(extName => {
  13. BrowserWindow.removeExtension(extName)
  14. })
  15. }
  16. let responseIdCounter = 0
  17. const executeJavaScriptInFrame = (webContents, frameRoutingId, code) => {
  18. return new Promise(resolve => {
  19. const responseId = responseIdCounter++
  20. ipcMain.once(`executeJavaScriptInFrame_${responseId}`, (event, result) => {
  21. resolve(result)
  22. })
  23. webContents.send('executeJavaScriptInFrame', frameRoutingId, code, responseId)
  24. })
  25. }
  26. const generateTests = (sandboxEnabled, contextIsolationEnabled) => {
  27. describe(`with sandbox ${sandboxEnabled ? 'enabled' : 'disabled'} and context isolation ${contextIsolationEnabled ? 'enabled' : 'disabled'}`, () => {
  28. let w
  29. describe('supports "run_at" option', () => {
  30. beforeEach(async () => {
  31. await closeWindow(w)
  32. w = new BrowserWindow({
  33. show: false,
  34. width: 400,
  35. height: 400,
  36. webPreferences: {
  37. contextIsolation: contextIsolationEnabled,
  38. sandbox: sandboxEnabled
  39. }
  40. })
  41. })
  42. afterEach(() => {
  43. removeAllExtensions()
  44. return closeWindow(w).then(() => { w = null })
  45. })
  46. it('should run content script at document_start', () => {
  47. addExtension('content-script-document-start')
  48. w.webContents.once('dom-ready', async () => {
  49. const result = await w.webContents.executeJavaScript('document.documentElement.style.backgroundColor')
  50. expect(result).to.equal('red')
  51. })
  52. w.loadURL('about:blank')
  53. })
  54. it('should run content script at document_idle', async () => {
  55. addExtension('content-script-document-idle')
  56. w.loadURL('about:blank')
  57. const result = await w.webContents.executeJavaScript('document.body.style.backgroundColor')
  58. expect(result).to.equal('red')
  59. })
  60. it('should run content script at document_end', () => {
  61. addExtension('content-script-document-end')
  62. w.webContents.once('did-finish-load', async () => {
  63. const result = await w.webContents.executeJavaScript('document.documentElement.style.backgroundColor')
  64. expect(result).to.equal('red')
  65. })
  66. w.loadURL('about:blank')
  67. })
  68. })
  69. describe('supports "all_frames" option', () => {
  70. const contentScript = path.resolve(fixtures, 'extensions/content-script')
  71. // Computed style values
  72. const COLOR_RED = `rgb(255, 0, 0)`
  73. const COLOR_BLUE = `rgb(0, 0, 255)`
  74. const COLOR_TRANSPARENT = `rgba(0, 0, 0, 0)`
  75. before(() => {
  76. BrowserWindow.addExtension(contentScript)
  77. })
  78. after(() => {
  79. BrowserWindow.removeExtension('content-script-test')
  80. })
  81. beforeEach(() => {
  82. w = new BrowserWindow({
  83. show: false,
  84. webPreferences: {
  85. // enable content script injection in subframes
  86. nodeIntegrationInSubFrames: true,
  87. preload: path.join(contentScript, 'all_frames-preload.js')
  88. }
  89. })
  90. })
  91. afterEach(() =>
  92. closeWindow(w).then(() => {
  93. w = null
  94. })
  95. )
  96. it('applies matching rules in subframes', async () => {
  97. const detailsPromise = emittedNTimes(w.webContents, 'did-frame-finish-load', 2)
  98. w.loadFile(path.join(contentScript, 'frame-with-frame.html'))
  99. const frameEvents = await detailsPromise
  100. await Promise.all(
  101. frameEvents.map(async frameEvent => {
  102. const [, isMainFrame, , frameRoutingId] = frameEvent
  103. const result = await executeJavaScriptInFrame(
  104. w.webContents,
  105. frameRoutingId,
  106. `(() => {
  107. const a = document.getElementById('all_frames_enabled')
  108. const b = document.getElementById('all_frames_disabled')
  109. return {
  110. enabledColor: getComputedStyle(a).backgroundColor,
  111. disabledColor: getComputedStyle(b).backgroundColor
  112. }
  113. })()`
  114. )
  115. expect(result.enabledColor).to.equal(COLOR_RED)
  116. if (isMainFrame) {
  117. expect(result.disabledColor).to.equal(COLOR_BLUE)
  118. } else {
  119. expect(result.disabledColor).to.equal(COLOR_TRANSPARENT) // null color
  120. }
  121. })
  122. )
  123. })
  124. })
  125. })
  126. }
  127. generateTests(false, false)
  128. generateTests(false, true)
  129. generateTests(true, false)
  130. generateTests(true, true)
  131. })