api-debugger-spec.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. const chai = require('chai')
  2. const dirtyChai = require('dirty-chai')
  3. const http = require('http')
  4. const path = require('path')
  5. const {closeWindow} = require('./window-helpers')
  6. const {BrowserWindow} = require('electron').remote
  7. const {expect} = chai
  8. chai.use(dirtyChai)
  9. describe('debugger module', () => {
  10. const fixtures = path.resolve(__dirname, 'fixtures')
  11. let w = null
  12. beforeEach(() => {
  13. w = new BrowserWindow({
  14. show: false,
  15. width: 400,
  16. height: 400
  17. })
  18. })
  19. afterEach(() => closeWindow(w).then(() => { w = null }))
  20. describe('debugger.attach', () => {
  21. it('succeeds when devtools is already open', done => {
  22. w.webContents.on('did-finish-load', () => {
  23. w.webContents.openDevTools()
  24. try {
  25. w.webContents.debugger.attach()
  26. } catch (err) {
  27. done(`unexpected error : ${err}`)
  28. }
  29. expect(w.webContents.debugger.isAttached()).to.be.true()
  30. done()
  31. })
  32. w.webContents.loadURL(`file://${path.join(fixtures, 'pages', 'a.html')}`)
  33. })
  34. it('fails when protocol version is not supported', done => {
  35. try {
  36. w.webContents.debugger.attach('2.0')
  37. } catch (err) {
  38. expect(w.webContents.debugger.isAttached()).to.be.false()
  39. done()
  40. }
  41. })
  42. it('attaches when no protocol version is specified', done => {
  43. try {
  44. w.webContents.debugger.attach()
  45. } catch (err) {
  46. done(`unexpected error : ${err}`)
  47. }
  48. expect(w.webContents.debugger.isAttached()).to.be.true()
  49. done()
  50. })
  51. })
  52. describe('debugger.detach', () => {
  53. it('fires detach event', (done) => {
  54. w.webContents.debugger.on('detach', (e, reason) => {
  55. expect(reason).to.equal('target closed')
  56. expect(w.webContents.debugger.isAttached()).to.be.false()
  57. done()
  58. })
  59. try {
  60. w.webContents.debugger.attach()
  61. } catch (err) {
  62. done(`unexpected error : ${err}`)
  63. }
  64. w.webContents.debugger.detach()
  65. })
  66. it('doesn\'t disconnect an active devtools session', done => {
  67. w.webContents.loadURL('about:blank')
  68. try {
  69. w.webContents.debugger.attach()
  70. } catch (err) {
  71. return done(`unexpected error : ${err}`)
  72. }
  73. w.webContents.openDevTools()
  74. w.webContents.once('devtools-opened', () => {
  75. w.webContents.debugger.detach()
  76. })
  77. w.webContents.debugger.on('detach', (e, reason) => {
  78. expect(w.webContents.debugger.isAttached()).to.be.false()
  79. expect(w.devToolsWebContents.isDestroyed()).to.be.false()
  80. done()
  81. })
  82. })
  83. })
  84. describe('debugger.sendCommand', () => {
  85. let server
  86. afterEach(() => {
  87. if (server != null) {
  88. server.close()
  89. server = null
  90. }
  91. })
  92. it('returns response', done => {
  93. w.webContents.loadURL('about:blank')
  94. try {
  95. w.webContents.debugger.attach()
  96. } catch (err) {
  97. return done(`unexpected error : ${err}`)
  98. }
  99. const callback = (err, res) => {
  100. expect(err.message).to.be.undefined()
  101. expect(res.wasThrown).to.be.undefined()
  102. expect(res.result.value).to.equal(6)
  103. w.webContents.debugger.detach()
  104. done()
  105. }
  106. const params = {'expression': '4+2'}
  107. w.webContents.debugger.sendCommand('Runtime.evaluate', params, callback)
  108. })
  109. it('returns response when devtools is opened', done => {
  110. w.webContents.loadURL('about:blank')
  111. try {
  112. w.webContents.debugger.attach()
  113. } catch (err) {
  114. return done(`unexpected error : ${err}`)
  115. }
  116. const callback = (err, res) => {
  117. expect(err.message).to.be.undefined()
  118. expect(res.wasThrown).to.be.undefined()
  119. expect(res.result.value).to.equal(6)
  120. w.webContents.debugger.detach()
  121. done()
  122. }
  123. w.webContents.openDevTools()
  124. w.webContents.once('devtools-opened', () => {
  125. const params = {'expression': '4+2'}
  126. w.webContents.debugger.sendCommand('Runtime.evaluate', params, callback)
  127. })
  128. })
  129. it('fires message event', done => {
  130. const url = process.platform !== 'win32'
  131. ? `file://${path.join(fixtures, 'pages', 'a.html')}`
  132. : `file:///${path.join(fixtures, 'pages', 'a.html').replace(/\\/g, '/')}`
  133. w.webContents.loadURL(url)
  134. try {
  135. w.webContents.debugger.attach()
  136. } catch (err) {
  137. done(`unexpected error : ${err}`)
  138. }
  139. w.webContents.debugger.on('message', (e, method, params) => {
  140. if (method === 'Console.messageAdded') {
  141. expect(params.message.level).to.equal('log')
  142. expect(params.message.url).to.equal(url)
  143. expect(params.message.text).to.equal('a')
  144. w.webContents.debugger.detach()
  145. done()
  146. }
  147. })
  148. w.webContents.debugger.sendCommand('Console.enable')
  149. })
  150. it('returns error message when command fails', done => {
  151. w.webContents.loadURL('about:blank')
  152. try {
  153. w.webContents.debugger.attach()
  154. } catch (err) {
  155. done(`unexpected error : ${err}`)
  156. }
  157. w.webContents.debugger.sendCommand('Test', err => {
  158. expect(err.message).to.equal("'Test' wasn't found")
  159. w.webContents.debugger.detach()
  160. done()
  161. })
  162. })
  163. it('handles valid unicode characters in message', (done) => {
  164. try {
  165. w.webContents.debugger.attach()
  166. } catch (err) {
  167. done(`unexpected error : ${err}`)
  168. }
  169. w.webContents.debugger.on('message', (event, method, params) => {
  170. if (method === 'Network.loadingFinished') {
  171. w.webContents.debugger.sendCommand('Network.getResponseBody', {
  172. requestId: params.requestId
  173. }, (_, data) => {
  174. expect(data.body).to.equal('\u0024')
  175. done()
  176. })
  177. }
  178. })
  179. server = http.createServer((req, res) => {
  180. res.setHeader('Content-Type', 'text/plain; charset=utf-8')
  181. res.end('\u0024')
  182. })
  183. server.listen(0, '127.0.0.1', () => {
  184. w.webContents.debugger.sendCommand('Network.enable')
  185. w.loadURL(`http://127.0.0.1:${server.address().port}`)
  186. })
  187. })
  188. it('does not crash for invalid unicode characters in message', (done) => {
  189. try {
  190. w.webContents.debugger.attach()
  191. } catch (err) {
  192. done(`unexpected error : ${err}`)
  193. }
  194. w.webContents.debugger.on('message', (event, method, params) => {
  195. // loadingFinished indicates that page has been loaded and it did not
  196. // crash because of invalid UTF-8 data
  197. if (method === 'Network.loadingFinished') {
  198. done()
  199. }
  200. })
  201. server = http.createServer((req, res) => {
  202. res.setHeader('Content-Type', 'text/plain; charset=utf-8')
  203. res.end('\uFFFF')
  204. })
  205. server.listen(0, '127.0.0.1', () => {
  206. w.webContents.debugger.sendCommand('Network.enable')
  207. w.loadURL(`http://127.0.0.1:${server.address().port}`)
  208. })
  209. })
  210. })
  211. })