Browse Source

Add csp tests

simov 7 years ago
parent
commit
07dc6529da
4 changed files with 183 additions and 6 deletions
  1. 161 0
      test/advanced-csp.js
  2. 10 0
      test/advanced-defaults.js
  3. 1 1
      test/advanced-origins.js
  4. 11 5
      test/index.js

+ 161 - 0
test/advanced-csp.js

@@ -0,0 +1,161 @@
+
+var t = require('assert')
+
+
+module.exports = ({browser, extensions, popup, advanced, content}) => {
+
+  before(async () => {
+    // add origin
+    await advanced.bringToFront()
+    await advanced.select('.m-select', 'http')
+    await advanced.type('[type=text]', 'localhost:3000')
+    await advanced.click('button')
+    await advanced.waitFor(() => document.querySelectorAll('.m-list li').length === 2)
+
+    // disable csp
+    if (await advanced.evaluate(() => state.csp)) {
+      await advanced.click('.m-switch:nth-of-type(2)')
+    }
+
+    // enable path matching
+    await advanced.evaluate(() => {
+      document.querySelector('.m-list li:nth-of-type(2) input')
+        .value = 'csp'
+      document.querySelector('.m-list li:nth-of-type(2) input')
+        .dispatchEvent(new Event('keyup'))
+    })
+    // there is debounce timeout of 750ms in the options UI
+    await advanced.waitFor(800)
+  })
+
+  describe('preserve state', () => {
+    it('options page', async () => {
+      await advanced.bringToFront()
+
+      // enable csp
+      if (!await advanced.evaluate(() => state.csp)) {
+        await advanced.click('.m-switch:nth-of-type(2)')
+      }
+      await advanced.reload()
+      await advanced.waitFor('#options')
+      await advanced.waitFor(100)
+
+      t.strictEqual(
+        await advanced.evaluate(() =>
+          document.querySelector('.m-switch:nth-of-type(2)')
+            .classList.contains('is-checked')
+        ),
+        true,
+        'csp checkbox should be enabled'
+      )
+
+      // disable csp
+      if (await advanced.evaluate(() => state.csp)) {
+        await advanced.click('.m-switch:nth-of-type(2)')
+      }
+      await advanced.reload()
+      await advanced.waitFor('#options')
+      await advanced.waitFor(100)
+
+      t.strictEqual(
+        await advanced.evaluate(() =>
+          document.querySelector('.m-switch:nth-of-type(2)')
+            .classList.contains('is-checked')
+        ),
+        false,
+        'csp checkbox should be disabled'
+      )
+    })
+  })
+
+  describe('enable csp', () => {
+    it('webRequest.onHeadersReceived event is enabled', async () => {
+      await advanced.bringToFront()
+      // enable csp
+      if (!await advanced.evaluate(() => state.csp)) {
+        await advanced.click('.m-switch:nth-of-type(2)')
+      }
+
+      // go to page serving content with strict csp
+      await content.goto('http://localhost:3000/csp')
+      await content.bringToFront()
+      await content.waitFor('#_html')
+
+      t.strictEqual(
+        await content.evaluate(() =>
+          window.localStorage.toString()
+        ),
+        '[object Storage]',
+        'localStorage should be accessible'
+      )
+    })
+  })
+
+  describe('disable csp', () => {
+    it('webRequest.onHeadersReceived event is disabled', async () => {
+      await advanced.bringToFront()
+      // disable csp
+      if (await advanced.evaluate(() => state.csp)) {
+        await advanced.click('.m-switch:nth-of-type(2)')
+      }
+
+      // go to page serving content with strict csp
+      await content.goto('http://localhost:3000/csp')
+      await content.bringToFront()
+      await content.waitFor('#_html')
+
+      t.strictEqual(
+        await content.evaluate(() => {
+          try {
+            window.localStorage
+          }
+          catch (err) {
+            return err.message.split(':')[1].trim()
+          }
+        }),
+        `The document is sandboxed and lacks the 'allow-same-origin' flag.`,
+        'localStorage should not be accessible'
+      )
+    })
+  })
+
+  describe('enable csp + suspend the event page', () => {
+    it('the tab is reloaded on event page wakeup', async () => {
+      await advanced.bringToFront()
+      // enable csp
+      if (!await advanced.evaluate(() => state.csp)) {
+        await advanced.click('.m-switch:nth-of-type(2)')
+      }
+
+      await extensions.bringToFront()
+      // enable developer mode
+      await extensions.click('#dev-toggle label')
+      // disable the extension
+      await extensions.click('.enable-checkbox label')
+      // enable the extension
+      await extensions.click('.enable-checkbox label')
+      // check
+      t.equal(
+        await extensions.evaluate(() =>
+          document.querySelector('.active-views a').innerText
+        ),
+        'background page (Inactive)',
+        'background page should be disabled'
+      )
+
+      // go to page serving content with strict csp
+      await content.goto('http://localhost:3000/csp')
+      await content.bringToFront()
+      await content.waitFor('#_html')
+
+      t.strictEqual(
+        await content.evaluate(() =>
+          window.localStorage.toString()
+        ),
+        '[object Storage]',
+        'localStorage should be accessible'
+      )
+    })
+  })
+
+}

+ 10 - 0
test/advanced-defaults.js

@@ -28,6 +28,16 @@ module.exports = ({advanced}) => {
     )
   })
 
+  it('csp option', async () => {
+    t.strictEqual(
+      await advanced.evaluate(() =>
+        state.csp
+      ),
+      false,
+      'state.csp should be false'
+    )
+  })
+
   it('allowed origins', async () => {
     t.deepStrictEqual(
       await advanced.evaluate(() =>

+ 1 - 1
test/advanced-origins.js

@@ -2,7 +2,7 @@
 var t = require('assert')
 
 
-module.exports = ({browser, content, advanced}) => {
+module.exports = ({browser, advanced, content}) => {
 
   before(async () => {
     // add origin

+ 11 - 5
test/index.js

@@ -17,6 +17,7 @@ var tests = [
   'advanced-defaults',
   'advanced-origins',
   'popup-options',
+  'advanced-csp', // should be last - destroys popup and advanced
 ]
 
 
@@ -26,10 +27,10 @@ describe('markdown-viewer', () => {
   it('test suite', async () => {
     browser = await puppeteer.launch(options)
 
-    var page = await browser.newPage()
-    await page.goto('chrome://extensions')
-    await page.waitForSelector('.extension-id')
-    var id = await page.evaluate(() =>
+    var extensions = await browser.newPage()
+    await extensions.goto('chrome://extensions')
+    await extensions.waitForSelector('.extension-id')
+    var id = await extensions.evaluate(() =>
       document.querySelector('.extension-id').innerText.trim()
     )
 
@@ -79,13 +80,18 @@ describe('markdown-viewer', () => {
             Array(500).fill('lorem ipsum').join(' '),
           ].join('\n\n'))
         }
+        else if (/csp/.test(req.url)) {
+          res.setHeader('Content-Security-Policy',
+            `default-src 'none'; style-src 'unsafe-inline'; sandbox`)
+          res.end('# h1')
+        }
       })
       server.listen(3000, resolve)
     })
 
     tests.forEach((file) => {
       describe(file, () => {
-        require(`./${file}.js`)({puppeteer, browser, popup, advanced, content})
+        require(`./${file}.js`)({puppeteer, browser, extensions, popup, advanced, content})
       })
     })