Skip to content

Instantly share code, notes, and snippets.

@twolfson
Last active March 14, 2016 05:41
Show Gist options
  • Save twolfson/f7d257966d7cdafdf30c to your computer and use it in GitHub Desktop.
Save twolfson/f7d257966d7cdafdf30c to your computer and use it in GitHub Desktop.
Strategy for add `window.postMessage` support to Karma

We are adding window.postMessage support to Karma in karma-runner/karma#1984 and there are a lot of ways for this to go wrong/get frustrated.

This document will outline the steps to prevent us from getting too frustrated.

Setting up the basics

  • Get local Karma + PhantomJS test suite running
    • We want something headless to run so it can be hands free and distraction free
  • Make sure we know how to log to Karma in case things get super fucky
    • In parent context, use console.log or karma.log('log', ['message'])
    • In child context, use console.log or parentWindow.karma.log('log', ['message'])
      • We tried to use parentWindow.console.log but it wasn't working for some reason. I'm guessing we got the unpatched binding =/
  • Add Browserify build for context.html (or whatever the iframe window is called)
  • Move PhantomJS to use window.open (not sure about this step being here)

Need to prove/solve

  • Verify we can get a postMessage from parent to child in PhantomJS
  • Verify we can get a postMessage from child to parent in PhantomJS
  • Verify we can get a postMessage from parent to child in Electron
  • Verify we can get a postMessage from child to parent in Electron
  • Define a non-postMessage yet postMessage like bridge for PhantomJS to use (see issue for code snippet)
  • Transfer context reloading from parent Karma to child Karma
    • Likely done via a postMessage from parent to child telling it to reload itself
    • This means no more about:blank or similar context-required situations
    • Drunk thoughts on this...
      • If window.opener.eval is prevalent (pretty sure not), then we can use it everywhere
      • Otherwise, must use postMessage
        • We should define a blank.html which sends a postMessage when it's loaded
      • Or maybe find out that we don't even need about:blank...
      • Like what about a new &timestamp={{timestamp}} parameter
    • There are a few things we need to handle
      • reloadingContext is a flag which tells us to fire a Karma error or not whenever the browser navigates
        • Make sure there is a test to error warn users on undesired navigation
      • config.clearContext is a flag to tell us to clear the context after the test runs
        • I think it's mostly for debugging
        • Ported but untested x_x
        • Make sure there's tests for this...
      • navigateContextTo used for reloading our context window
        • Good except it uses opener('about:blank') + location = url for non-iframe
        • We can't use setters due to Electron so opener(url) with patched clearContext should be good
      • clearContext used to reset context window to empty state
        • Currently, this calls navigateContextTo
        • We should update it to use close() for non-iframes and navigateContextTo for iframes
        • Realized we should move all logic into navigateContextTo, no need for duplication
  • Guarantee we properly handle hasError
    • Should be straightforward; set it whenever karma.error is called
  • What the fuck is this.store used for...
    • Posted to Gitter about this
    • Worst case scenario: We move it to cookies since those are also a "shared storage"

Easy polish

  • Add stringify to context.html build
  • Define callParentKarmaMethod with no postMessage fallback yet
  • Define an _log in parent Karma to call so we can call log locally then send to callParentKarmaMethod
  • Transfer onbeforeunload and similar proxies (including console)

Final polish

  • Add karma-electron to test suite to verify window.postMessage works when we can't talk directly across contexts
@twolfson
Copy link
Author

This went a little different in the end:

  • Transition low level methods first (e.g. info, log, error, start, complete)
  • Update failing tests
  • Transition high level bindings (e.g. onerror, onbeforeunload)
  • Update failing tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment