[gold] Simplify some tests.

Specifically:
 - Don't call window.customElements.whenDefined('my-component-sk').then(...), as custom elements are already defined before our tests run.
 - Don't use container elements; add the component under test directly as a child of document.body.

This CL makes our testing more uniform and will facilitate the extraction of common patterns from our tests into shared functions.

Bug: skia:9525
Change-Id: I7e1ccb1f15c1d772ab22dc10a7edaa06a4ae1dbc
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/265216
Commit-Queue: Leandro Lovisolo <lovisolo@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
diff --git a/golden/modules/changelist-controls-sk/changelist-controls-sk_test.js b/golden/modules/changelist-controls-sk/changelist-controls-sk_test.js
index 38078ff..892ba33 100644
--- a/golden/modules/changelist-controls-sk/changelist-controls-sk_test.js
+++ b/golden/modules/changelist-controls-sk/changelist-controls-sk_test.js
@@ -4,136 +4,111 @@
 import { twoPatchSets } from './test_data'
 
 describe('changelist-controls-sk', () => {
-
-  // A reusable HTML element in which we create our element under test.
-  let container;
-
-  // calls the test callback with an element under test 'ele'.
-  // We can't put the describes inside the whenDefined callback because
-  // that doesn't work on Firefox (and possibly other places).
-  function createElement(test) {
-    return window.customElements.whenDefined('changelist-controls-sk').then(() => {
-      container.innerHTML = `<changelist-controls-sk></changelist-controls-sk>`;
-      expect(container.firstElementChild).to.not.be.null;
-      test(container.firstElementChild);
-    });
-  }
+  let changelistControlsSk;
 
   beforeEach(() => {
-    container = document.createElement('div');
-    document.body.appendChild(container);
+    changelistControlsSk = document.createElement('changelist-controls-sk');
+    document.body.appendChild(changelistControlsSk);
   });
 
   afterEach(() => {
-    document.body.removeChild(container);
+    if (changelistControlsSk) {
+      document.body.removeChild(changelistControlsSk);
+      changelistControlsSk = null;
+    }
   });
 
-  //===============TESTS START====================================
-
   describe('html layout', () => {
     it('is empty with no data', () => {
-      return createElement((ele) => {
-        expect(ele.children.length).to.equal(0);
-      });
+      expect(changelistControlsSk.children.length).to.equal(0);
     });
 
     it('shows the latest patchset by default', () => {
-      return createElement((ele) => {
-        expect(ele.ps_order).to.equal(0);
-        expect(ele.include_master).to.equal(false);
+      expect(changelistControlsSk.ps_order).to.equal(0);
+      expect(changelistControlsSk.include_master).to.equal(false);
 
-        ele.setSummary(twoPatchSets);
-        const psSelector = $$('.inputs select', ele);
-        expect(psSelector).to.not.be.null;
-        expect(psSelector.value).to.equal('PS 4');
+      changelistControlsSk.setSummary(twoPatchSets);
+      const psSelector = $$('.inputs select', changelistControlsSk);
+      expect(psSelector).to.not.be.null;
+      expect(psSelector.value).to.equal('PS 4');
 
-        const includeMasterRadios = $('.inputs radio-sk', ele);
-        expect(includeMasterRadios.length).to.equal(2);
-        expect(includeMasterRadios[0].hasAttribute('checked')).to.equal(true);
+      const includeMasterRadios = $('.inputs radio-sk', changelistControlsSk);
+      expect(includeMasterRadios.length).to.equal(2);
+      expect(includeMasterRadios[0].hasAttribute('checked')).to.equal(true);
 
-        expect(ele.ps_order).to.equal(4);
+      expect(changelistControlsSk.ps_order).to.equal(4);
 
-        const tryJobs = $('.tryjob-container .tryjob', ele);
-        expect(tryJobs).to.not.be.null;
-        expect(tryJobs.length).to.equal(4);
-        // spot check a tryjob
-        expect(tryJobs[0].textContent.trim()).to.equal('android-marshmallow-arm64-rel');
-      });
+      const tryJobs = $('.tryjob-container .tryjob', changelistControlsSk);
+      expect(tryJobs).to.not.be.null;
+      expect(tryJobs.length).to.equal(4);
+      // spot check a tryjob
+      expect(tryJobs[0].textContent.trim()).to.equal('android-marshmallow-arm64-rel');
     });
 
     it('shows other patchsets when ps_order is changed', () => {
-      return createElement((ele) => {
-        ele.setSummary(twoPatchSets);
-        ele.ps_order = 1;
-        const psSelector = $$('.inputs select', ele);
-        expect(psSelector).to.not.be.null;
-        expect(psSelector.value).to.equal('PS 1');
+      changelistControlsSk.setSummary(twoPatchSets);
+      changelistControlsSk.ps_order = 1;
+      const psSelector = $$('.inputs select', changelistControlsSk);
+      expect(psSelector).to.not.be.null;
+      expect(psSelector.value).to.equal('PS 1');
 
-        const tryJobs = $('.tryjob-container .tryjob', ele);
-        expect(tryJobs).to.not.be.null;
-        expect(tryJobs.length).to.equal(1);
-        // spot check a tryjob
-        expect(tryJobs[0].textContent.trim()).to.equal('android-nougat-arm64-rel');
-      });
+      const tryJobs = $('.tryjob-container .tryjob', changelistControlsSk);
+      expect(tryJobs).to.not.be.null;
+      expect(tryJobs.length).to.equal(1);
+      // spot check a tryjob
+      expect(tryJobs[0].textContent.trim()).to.equal('android-nougat-arm64-rel');
     });
 
     it('flips the radio buttons on include_master', () => {
-      return createElement((ele) => {
-        ele.setSummary(twoPatchSets);
-        const includeMasterRadios = $('.inputs radio-sk', ele);
-        expect(includeMasterRadios.length).to.equal(2);
-        expect(includeMasterRadios[0].hasAttribute('checked')).to.equal(true);
-        expect(includeMasterRadios[1].hasAttribute('checked')).to.equal(false);
+      changelistControlsSk.setSummary(twoPatchSets);
+      const includeMasterRadios = $('.inputs radio-sk', changelistControlsSk);
+      expect(includeMasterRadios.length).to.equal(2);
+      expect(includeMasterRadios[0].hasAttribute('checked')).to.equal(true);
+      expect(includeMasterRadios[1].hasAttribute('checked')).to.equal(false);
 
-        ele.include_master = true;
-        expect(includeMasterRadios[0].hasAttribute('checked')).to.equal(false);
-        expect(includeMasterRadios[1].hasAttribute('checked')).to.equal(true);
-      });
+      changelistControlsSk.include_master = true;
+      expect(includeMasterRadios[0].hasAttribute('checked')).to.equal(false);
+      expect(includeMasterRadios[1].hasAttribute('checked')).to.equal(true);
     });
   }); // end describe('html layout')
 
   describe('events', () => {
     it('generates a cl-control-change event on master toggle', (done) => {
-      createElement((ele) => {
-        ele.include_master = false;
-        ele.setSummary(twoPatchSets);
+      changelistControlsSk.include_master = false;
+      changelistControlsSk.setSummary(twoPatchSets);
 
-        ele.addEventListener('cl-control-change', (e) => {
-          expect(e.detail.include_master).to.equal(true);
-          expect(e.detail.ps_order).to.equal(4);
-          done();
-        });
-
-        const includeMasterRadios = $('.inputs radio-sk', ele);
-        expect(includeMasterRadios.length).to.equal(2);
-        includeMasterRadios[1].click();
-        expect(ele.include_master).to.equal(true);
-        expect(includeMasterRadios[0].hasAttribute('checked')).to.equal(false);
-        expect(includeMasterRadios[1].hasAttribute('checked')).to.equal(true);
+      changelistControlsSk.addEventListener('cl-control-change', (e) => {
+        expect(e.detail.include_master).to.equal(true);
+        expect(e.detail.ps_order).to.equal(4);
+        done();
       });
+
+      const includeMasterRadios = $('.inputs radio-sk', changelistControlsSk);
+      expect(includeMasterRadios.length).to.equal(2);
+      includeMasterRadios[1].click();
+      expect(changelistControlsSk.include_master).to.equal(true);
+      expect(includeMasterRadios[0].hasAttribute('checked')).to.equal(false);
+      expect(includeMasterRadios[1].hasAttribute('checked')).to.equal(true);
     });
 
     it('generates a cl-control-change event on patchset change', (done) => {
-      createElement((ele) => {
-        ele.ps_order = 0;
-        ele.setSummary(twoPatchSets);
+      changelistControlsSk.ps_order = 0;
+      changelistControlsSk.setSummary(twoPatchSets);
 
-        ele.addEventListener('cl-control-change', (e) => {
-          expect(e.detail.include_master).to.equal(false);
-          expect(e.detail.ps_order).to.equal(1);
-          done();
-        });
-
-        const psSelector = $$('.inputs select', ele);
-        expect(psSelector).to.not.be.null;
-        expect(psSelector.value).to.equal('PS 4');
-
-        psSelector.selectedIndex = 0;
-        // we have to manually send this because just changing selectedIdx isn't enough.
-        // https://stackoverflow.com/a/23612498
-        psSelector.dispatchEvent(new Event('input'));
+      changelistControlsSk.addEventListener('cl-control-change', (e) => {
+        expect(e.detail.include_master).to.equal(false);
+        expect(e.detail.ps_order).to.equal(1);
+        done();
       });
+
+      const psSelector = $$('.inputs select', changelistControlsSk);
+      expect(psSelector).to.not.be.null;
+      expect(psSelector.value).to.equal('PS 4');
+
+      psSelector.selectedIndex = 0;
+      // we have to manually send this because just changing selectedIdx isn't enough.
+      // https://stackoverflow.com/a/23612498
+      psSelector.dispatchEvent(new Event('input'));
     });
   }); // end describe('events')
-
 });
diff --git a/golden/modules/changelists-page-sk/changelists-page-sk_test.js b/golden/modules/changelists-page-sk/changelists-page-sk_test.js
index efa9455..8b5136d 100644
--- a/golden/modules/changelists-page-sk/changelists-page-sk_test.js
+++ b/golden/modules/changelists-page-sk/changelists-page-sk_test.js
@@ -11,130 +11,89 @@
 import { fetchMock }  from 'fetch-mock';
 
 describe('changelists-page-sk', () => {
-  // A reusable HTML element in which we create our element under test.
-  const container = document.createElement('div');
-  document.body.appendChild(container);
+  let changelistsPageSk;
 
-  beforeEach(function() {
+  const loadChangelistsPageSk = async () => {
+    const endTask = eventPromise('end-task');
+    changelistsPageSk = document.createElement('changelists-page-sk');
+    document.body.appendChild(changelistsPageSk);
+    await endTask;
+  };
+
+  beforeEach(async () => {
     // Clear out any query params we might have to not mess with our current state.
     setQueryString('');
-  });
 
-  beforeEach(function() {
     // These are the default offset/page_size params
     fetchMock.get('/json/changelists?offset=0&size=50&active=true', JSON.stringify(changelistSummaries_5));
-
-    fetchMock.catch(404);
   });
 
   afterEach(function() {
+    // Remove the stale instance under test.
+    if (changelistsPageSk) {
+      document.body.removeChild(changelistsPageSk);
+      changelistsPageSk = null;
+    }
+
     // Completely remove the mocking which allows each test
     // to be able to mess with the mocked routes w/o impacting other tests.
     fetchMock.reset();
   });
 
-  afterEach(function() {
-    container.innerHTML = '';
-  });
-
-  // calls the test callback with an element under test 'ele'.
-  // We can't put the describes inside the whenDefined callback because
-  // that doesn't work on Firefox (and possibly other places).
-  function createElement(test) {
-    return window.customElements.whenDefined('changelists-page-sk').then(() => {
-      container.innerHTML = `<changelists-page-sk></changelists-page-sk>`;
-      expect(container.firstElementChild).to.not.be.null;
-      test(container.firstElementChild);
-    });
-  }
-
-  function whenPageLoads(test) {
-    // The changelists-page-sk emits an 'end-task' event when each fetch finishes.
-    // For now, there is only one, but this logic may have to be tweaked if we
-    // do multiple.
-    let ran = false;
-    let ele = null;
-    const fn = (e) => {
-      e.stopPropagation(); // Prevent interference with eventPromise('end-task').
-      // reset for next time
-      container.removeEventListener('end-task', fn);
-      if (!ran) {
-        ran = true; // prevent multiple runs if the test makes the
-                    // app go busy (e.g. if it calls fetch).
-        test(ele);
-      }
-    };
-    // add the listener and then create the element to make sure we don't miss
-    // the busy-end event. The busy-end event should trigger when all fetches
-    // are done and the page is rendered.
-    container.addEventListener('end-task', fn);
-    createElement((e) => {
-      ele = e;
-    });
-  }
-
-  //===============TESTS START====================================
-
   describe('html layout', () => {
-    it('should make a table with 5 rows in the body', (done) => {
-      whenPageLoads((ele) => {
-        const tbl = $$('table', ele);
-        expect(tbl).to.not.be.null;
-        const rows = $('tbody tr', ele);
-        expect(rows.length).to.equal(5); // one row per item in changelistSummaries_5
-        done();
-      });
+    beforeEach(loadChangelistsPageSk);
+
+    it('should make a table with 5 rows in the body', () => {
+      const tbl = $$('table', changelistsPageSk);
+      expect(tbl).to.not.be.null;
+      const rows = $('tbody tr', changelistsPageSk);
+      expect(rows.length).to.equal(5); // one row per item in changelistSummaries_5
     });
 
-    it('has icons that indicate the status', (done) => {
-      whenPageLoads((ele) => {
-        const rows = $('tbody tr', ele);
-        // First row has an open CL.
-        let icon = $$('cached-icon-sk', rows[0]);
-        expect(icon).to.not.be.null;
-        // Fourth row has an abandoned CL.
-        icon = $$('block-icon-sk', rows[3]);
-        expect(icon).to.not.be.null;
-        // Fifth row has an closed CL.
-        icon = $$('done-icon-sk', rows[4]);
-        expect(icon).to.not.be.null;
-        done();
-      });
+    it('has icons that indicate the status', () => {
+      const rows = $('tbody tr', changelistsPageSk);
+      // First row has an open CL.
+      let icon = $$('cached-icon-sk', rows[0]);
+      expect(icon).to.not.be.null;
+      // Fourth row has an abandoned CL.
+      icon = $$('block-icon-sk', rows[3]);
+      expect(icon).to.not.be.null;
+      // Fifth row has an closed CL.
+      icon = $$('done-icon-sk', rows[4]);
+      expect(icon).to.not.be.null;
     });
   }); // end describe('html layout')
 
   describe('api calls', () => {
-    it('includes pagination params in request to changelists', (done) => {
-      whenPageLoads((ele) => {
-        fetchMock.resetHistory();
+    beforeEach(loadChangelistsPageSk);
 
-        fetchMock.get('/json/changelists?offset=100&size=10', JSON.stringify(empty));
-        // pretend these were loaded in via stateReflector
-        ele._offset = 100;
-        ele._page_size = 10;
-        ele._showAll = true;
+    it('includes pagination params in request to changelists', async () => {
+      fetchMock.resetHistory();
 
-        ele._fetch().then(done);
-      });
+      fetchMock.get('/json/changelists?offset=100&size=10', JSON.stringify(empty));
+      // pretend these were loaded in via stateReflector
+      changelistsPageSk._offset = 100;
+      changelistsPageSk._page_size = 10;
+      changelistsPageSk._showAll = true;
+
+      await changelistsPageSk._fetch();
     });
 
-    it('includes the active params unless show_all is set', (done) => {
-      whenPageLoads((ele) => {
-        fetchMock.resetHistory();
+    it('includes the active params unless show_all is set', async () => {
+      fetchMock.resetHistory();
 
-        fetchMock.get('/json/changelists?offset=100&size=10&active=true', JSON.stringify(empty));
-        // pretend these were loaded in via stateReflector
-        ele._offset = 100;
-        ele._page_size = 10;
-        ele._showAll = false;
+      fetchMock.get('/json/changelists?offset=100&size=10&active=true', JSON.stringify(empty));
+      // pretend these were loaded in via stateReflector
+      changelistsPageSk._offset = 100;
+      changelistsPageSk._page_size = 10;
+      changelistsPageSk._showAll = false;
 
-        ele._fetch().then(done);
-      });
+      changelistsPageSk._fetch();
     });
   }); // end describe('api calls')
 
   describe('navigation', () => {
-    it('responds to the browser back/forward buttons', (done) => {
+    it('responds to the browser back/forward buttons', async () => {
       // First page of results.
       fetchMock.get(
           '/json/changelists?offset=0&size=5&active=true',
@@ -157,69 +116,65 @@
       // required for the mock RPCs above to work.
       setQueryString('?page_size=5');
 
-      whenPageLoads(async (el) => {
-        expectQueryStringToEqual('?page_size=5');
-        expectFirstPage();
+      await loadChangelistsPageSk();  // Instantiate component.
+      expectQueryStringToEqual('?page_size=5');
+      expectFirstPage();
 
-        await goToNextPage(el);
-        expectQueryStringToEqual('?offset=5&page_size=5');
-        expectSecondPage();
+      await goToNextPage(changelistsPageSk);
+      expectQueryStringToEqual('?offset=5&page_size=5');
+      expectSecondPage();
 
-        await goToNextPage(el);
-        expectQueryStringToEqual('?offset=10&page_size=5');
-        expectThirdPage();
+      await goToNextPage(changelistsPageSk);
+      expectQueryStringToEqual('?offset=10&page_size=5');
+      expectThirdPage();
 
-        await goBack();
-        expectQueryStringToEqual('?offset=5&page_size=5');
-        expectSecondPage();
+      await goBack();
+      expectQueryStringToEqual('?offset=5&page_size=5');
+      expectSecondPage();
 
-        // State at component instantiation.
-        await goBack();
-        expectQueryStringToEqual('?page_size=5');
-        expectFirstPage();
+      // State at component instantiation.
+      await goBack();
+      expectQueryStringToEqual('?page_size=5');
+      expectFirstPage();
 
-        // State before the component was instantiated.
-        await goBack();
-        expectQueryStringToEqual('?hello=world');
+      // State before the component was instantiated.
+      await goBack();
+      expectQueryStringToEqual('?hello=world');
 
-        await goForward();
-        expectQueryStringToEqual('?page_size=5');
-        expectFirstPage();
+      await goForward();
+      expectQueryStringToEqual('?page_size=5');
+      expectFirstPage();
 
-        await goForward();
-        expectQueryStringToEqual('?offset=5&page_size=5');
-        expectSecondPage();
+      await goForward();
+      expectQueryStringToEqual('?offset=5&page_size=5');
+      expectSecondPage();
 
-        await goForward();
-        expectQueryStringToEqual('?offset=10&page_size=5');
-        expectThirdPage();
-
-        done();
-      });
+      await goForward();
+      expectQueryStringToEqual('?offset=10&page_size=5');
+      expectThirdPage();
     });
   }); // end describe('navigation')
 
   describe('dynamic content', () => {
-    it('responds to clicking the show all checkbox', (done) => {
-      whenPageLoads((ele) => {
-        fetchMock.get('/json/changelists?offset=0&size=50', JSON.stringify(empty));
-        // click on the input inside the checkbox, otherwise, we see double
-        // events, since checkbox-sk "re-throws" the click event.
-        const showAllBox = $$('.controls checkbox-sk input', ele);
-        expect(showAllBox).to.not.be.null;
-        expect(ele._showAll).to.equal(false);
-        expectQueryStringToEqual('');
-        showAllBox.click();
-        expect(ele._showAll).to.equal(true);
-        expectQueryStringToEqual('?page_size=50&show_all=true');
-        showAllBox.click();
-        expect(ele._showAll).to.equal(false);
-        expectQueryStringToEqual('?page_size=50');
-        showAllBox.click();
-        expect(ele._showAll).to.equal(true);
-        expectQueryStringToEqual('?page_size=50&show_all=true');
-        done();
-      });
+    beforeEach(loadChangelistsPageSk);
+
+    it('responds to clicking the show all checkbox', () => {
+      fetchMock.get('/json/changelists?offset=0&size=50', JSON.stringify(empty));
+      // click on the input inside the checkbox, otherwise, we see double
+      // events, since checkbox-sk "re-throws" the click event.
+      const showAllBox = $$('.controls checkbox-sk input', changelistsPageSk);
+      expect(showAllBox).to.not.be.null;
+      expect(changelistsPageSk._showAll).to.equal(false);
+      expectQueryStringToEqual('');
+      showAllBox.click();
+      expect(changelistsPageSk._showAll).to.equal(true);
+      expectQueryStringToEqual('?page_size=50&show_all=true');
+      showAllBox.click();
+      expect(changelistsPageSk._showAll).to.equal(false);
+      expectQueryStringToEqual('?page_size=50');
+      showAllBox.click();
+      expect(changelistsPageSk._showAll).to.equal(true);
+      expectQueryStringToEqual('?page_size=50&show_all=true');
     });
 
   }); // end describe('dynamic content')
@@ -229,9 +184,9 @@
         null, '', window.location.origin + window.location.pathname + q);
   }
 
-  function goToNextPage(el) {
+  function goToNextPage(changelistsPageSk) {
     const event = eventPromise('end-task');
-    $$('pagination-sk button.next', el).click();
+    $$('pagination-sk button.next', changelistsPageSk).click();
     return event;
   }
 
diff --git a/golden/modules/gold-scaffold-sk/gold-scaffold-sk_test.js b/golden/modules/gold-scaffold-sk/gold-scaffold-sk_test.js
index b8211a7..f46a046 100644
--- a/golden/modules/gold-scaffold-sk/gold-scaffold-sk_test.js
+++ b/golden/modules/gold-scaffold-sk/gold-scaffold-sk_test.js
@@ -1,103 +1,90 @@
 import './index.js'
 
 import { $, $$ } from 'common-sk/modules/dom'
+import { eventPromise } from '../test_util';
 
 describe('gold-scaffold-sk', () => {
+  let goldScaffoldSk;
 
-  // A reusable HTML element in which we create our element under test.
-  const container = document.createElement('div');
-  document.body.appendChild(container);
-
-  afterEach(function() {
-    container.innerHTML = '';
+  beforeEach(() => {
+    const content = document.createElement('div');
+    content.innerHTML = 'content';
+    goldScaffoldSk = document.createElement('gold-scaffold-sk');
+    goldScaffoldSk.setAttribute('testing_offline', '');
+    goldScaffoldSk.appendChild(content);
+    document.body.appendChild(goldScaffoldSk);
   });
 
-  // calls the test callback with an element under test 'ele'.
-  // We can't put the describes inside the whenDefined callback because
-  // that doesn't work on Firefox (and possibly other places).
-  function createElement(test) {
-    return window.customElements.whenDefined('gold-scaffold-sk').then(() => {
-      container.innerHTML = `
-          <gold-scaffold-sk testing_offline>
-            <div>content</div>
-          </gold-scaffold-sk>`;
-      expect(container.firstElementChild).to.not.be.null;
-      test(container.firstElementChild);
-    });
-  }
-
-  //===============TESTS START====================================
+  afterEach(() => {
+    // Remove the stale instance under test.
+    if (goldScaffoldSk) {
+      document.body.removeChild(goldScaffoldSk);
+      goldScaffoldSk = null;
+    }
+  });
 
   describe('html layout', () => {
     it('adds a login-sk element', () => {
-      return createElement((ele) => {
-        const log = $$('header login-sk', ele);
-        expect(log).to.not.be.null;
-      });
+      const log = $$('header login-sk', goldScaffoldSk);
+      expect(log).to.not.be.null;
     });
 
     it('adds a sidebar with links', () => {
-      return createElement((ele) => {
-        const nav = $$('aside nav', ele);
-        expect(nav).to.not.be.null;
-        const links = $('a', nav);
-        expect(links.length).not.to.equal(0);
-      });
+      const nav = $$('aside nav', goldScaffoldSk);
+      expect(nav).to.not.be.null;
+      const links = $('a', nav);
+      expect(links.length).not.to.equal(0);
     });
 
     it('puts the content under <main>', () => {
-      return createElement((ele) => {
-        const main = $$('main', ele);
-        expect(main).to.not.be.null;
-        const content = $$('div', main);
-        expect(content).to.not.be.null;
-        expect(content.textContent).to.equal('content');
-      });
+      const main = $$('main', goldScaffoldSk);
+      expect(main).to.not.be.null;
+      const content = $$('div', main);
+      expect(content).to.not.be.null;
+      expect(content.textContent).to.equal('content');
     });
   });// end describe('html layout')
 
   describe('spinner and busy property', () => {
     it('becomes busy while there are tasks to be done', () => {
-      return createElement((ele) => {
-        expect(ele.busy).to.equal(false);
-        ele.dispatchEvent(new CustomEvent('begin-task', {bubbles: true}));
-        ele.dispatchEvent(new CustomEvent('begin-task', {bubbles: true}));
-        expect(ele.busy).to.equal(true);
-        ele.dispatchEvent(new CustomEvent('end-task', {bubbles: true}));
-        expect(ele.busy).to.equal(true);
-        ele.dispatchEvent(new CustomEvent('end-task', {bubbles: true}));
-        expect(ele.busy).to.equal(false);
-      });
+      expect(goldScaffoldSk.busy).to.equal(false);
+      goldScaffoldSk.dispatchEvent(
+          new CustomEvent('begin-task', {bubbles: true}));
+      goldScaffoldSk.dispatchEvent(
+          new CustomEvent('begin-task', {bubbles: true}));
+      expect(goldScaffoldSk.busy).to.equal(true);
+      goldScaffoldSk.dispatchEvent(
+          new CustomEvent('end-task', {bubbles: true}));
+      expect(goldScaffoldSk.busy).to.equal(true);
+      goldScaffoldSk.dispatchEvent(
+          new CustomEvent('end-task', {bubbles: true}));
+      expect(goldScaffoldSk.busy).to.equal(false);
     });
 
     it('keeps spinner active while busy', () => {
-      return createElement((ele) => {
-        const spinner = $$('header spinner-sk', ele);
-        expect(spinner.active).to.equal(false);
-        ele.dispatchEvent(new CustomEvent('begin-task', {bubbles: true}));
-        ele.dispatchEvent(new CustomEvent('begin-task', {bubbles: true}));
-        expect(spinner.active).to.equal(true);
-        ele.dispatchEvent(new CustomEvent('end-task', {bubbles: true}));
-        expect(spinner.active).to.equal(true);
-        ele.dispatchEvent(new CustomEvent('end-task', {bubbles: true}));
-        expect(spinner.active).to.equal(false);
-      });
+      const spinner = $$('header spinner-sk', goldScaffoldSk);
+      expect(spinner.active).to.equal(false);
+      goldScaffoldSk.dispatchEvent(
+          new CustomEvent('begin-task', {bubbles: true}));
+      goldScaffoldSk.dispatchEvent(
+          new CustomEvent('begin-task', {bubbles: true}));
+      expect(spinner.active).to.equal(true);
+      goldScaffoldSk.dispatchEvent(
+          new CustomEvent('end-task', {bubbles: true}));
+      expect(spinner.active).to.equal(true);
+      goldScaffoldSk.dispatchEvent(
+          new CustomEvent('end-task', {bubbles: true}));
+      expect(spinner.active).to.equal(false);
     });
 
-    it('emits a busy-end task when tasks finished', function(done) {
-      createElement((ele) => {
-        ele.addEventListener('busy-end', (e) => {
-          e.stopPropagation();
-          expect(ele.busy).to.equal(false);
-          done();
-        });
-        ele.dispatchEvent(new CustomEvent('begin-task', {bubbles: true}));
-
-        setTimeout(()=>{
-          ele.dispatchEvent(new CustomEvent('end-task', {bubbles: true}));
-        }, 10);
-      });
+    it('emits a busy-end task when tasks finished', async () => {
+      const busyEnd = eventPromise('busy-end');
+      goldScaffoldSk.dispatchEvent(
+          new CustomEvent('begin-task', {bubbles: true}));
+      await new Promise((resolve) => setTimeout(resolve, 10));
+      goldScaffoldSk.dispatchEvent(
+          new CustomEvent('end-task', {bubbles: true}));
+      await busyEnd;
     });
   }); // end describe('spinner and busy property')
-
-});
\ No newline at end of file
+});
diff --git a/golden/modules/pagination-sk/pagination-sk_test.js b/golden/modules/pagination-sk/pagination-sk_test.js
index 452b6bb..22822bc 100644
--- a/golden/modules/pagination-sk/pagination-sk_test.js
+++ b/golden/modules/pagination-sk/pagination-sk_test.js
@@ -3,103 +3,89 @@
 import { $, $$ } from 'common-sk/modules/dom'
 
 describe('pagination-sk', () => {
+  let paginationSk;
 
-  // A reusable HTML element in which we create our element under test.
-  const container = document.createElement('div');
-  document.body.appendChild(container);
-
-  afterEach(function() {
-    container.innerHTML = '';
+  beforeEach(() => {
+    paginationSk = document.createElement('pagination-sk');
+    paginationSk.setAttribute('offset', '0');
+    paginationSk.setAttribute('total', '127');
+    paginationSk.setAttribute('page_size', '20');
+    document.body.appendChild(paginationSk);
   });
 
-  // calls the test callback with an element under test 'ele'.
-  // We can't put the describes inside the whenDefined callback because
-  // that doesn't work on Firefox (and possibly other places).
-  function createElement(test) {
-    return window.customElements.whenDefined('pagination-sk').then(() => {
-      container.innerHTML = `
-        <pagination-sk offset=0 total=127 page_size=20></pagination-sk>`;
-      expect(container.firstElementChild).to.not.be.null;
-      test(container.firstElementChild);
-    });
-  }
-
-  //===============TESTS START====================================
+  afterEach(() => {
+    // Remove the stale instance under test.
+    if (paginationSk) {
+      document.body.removeChild(paginationSk);
+      paginationSk = null;
+    }
+  });
 
   describe('html layout', () => {
     it('has three buttons', () => {
-      return createElement((ele) => {
-        const btns = $('button', ele);
-        expect(btns.length).to.equal(3);
-        // backward
-        expect(btns[0].hasAttribute('disabled')).to.be.true;
-        // forward
-        expect(btns[1].hasAttribute('disabled')).to.be.false;
-        // forward+5
-        expect(btns[2].hasAttribute('disabled')).to.be.false;
+      const btns = $('button', paginationSk);
+      expect(btns.length).to.equal(3);
+      // backward
+      expect(btns[0].hasAttribute('disabled')).to.be.true;
+      // forward
+      expect(btns[1].hasAttribute('disabled')).to.be.false;
+      // forward+5
+      expect(btns[2].hasAttribute('disabled')).to.be.false;
 
-        ele.offset = 20;
-        ele._render();
-        expect(btns[0].hasAttribute('disabled')).to.be.false;
-        expect(btns[1].hasAttribute('disabled')).to.be.false;
-        expect(btns[2].hasAttribute('disabled')).to.be.false;
+      paginationSk.offset = 20;
+      paginationSk._render();
+      expect(btns[0].hasAttribute('disabled')).to.be.false;
+      expect(btns[1].hasAttribute('disabled')).to.be.false;
+      expect(btns[2].hasAttribute('disabled')).to.be.false;
 
-        ele.offset = 40;
-        ele._render();
-        expect(btns[0].hasAttribute('disabled')).to.be.false;
-        expect(btns[1].hasAttribute('disabled')).to.be.false;
-        expect(btns[2].hasAttribute('disabled')).to.be.true;
+      paginationSk.offset = 40;
+      paginationSk._render();
+      expect(btns[0].hasAttribute('disabled')).to.be.false;
+      expect(btns[1].hasAttribute('disabled')).to.be.false;
+      expect(btns[2].hasAttribute('disabled')).to.be.true;
 
-        ele.offset = 120;
-        ele._render();
-        expect(btns[0].hasAttribute('disabled')).to.be.false;
-        expect(btns[1].hasAttribute('disabled')).to.be.true;
-        expect(btns[2].hasAttribute('disabled')).to.be.true;
-      });
+      paginationSk.offset = 120;
+      paginationSk._render();
+      expect(btns[0].hasAttribute('disabled')).to.be.false;
+      expect(btns[1].hasAttribute('disabled')).to.be.true;
+      expect(btns[2].hasAttribute('disabled')).to.be.true;
     });
 
     it('displays the page count', () => {
-      return createElement((ele) => {
-        const cnt = $$('.counter', ele);
-        expect(cnt).to.not.be.null;
-        expect(cnt.textContent).to.have.string('page 1');
-      });
+      const cnt = $$('.counter', paginationSk);
+      expect(cnt).to.not.be.null;
+      expect(cnt.textContent).to.have.string('page 1');
     });
 
     it('has several properties', () => {
-      return createElement((ele) => {
-        expect(ele.total).to.equal(127);
-        expect(ele.offset).to.equal(0);
-        expect(ele.page_size).to.equal(20);
-      });
+      expect(paginationSk.total).to.equal(127);
+      expect(paginationSk.offset).to.equal(0);
+      expect(paginationSk.page_size).to.equal(20);
     });
   });// end describe('html layout')
 
   describe('paging behavior', () => {
     it('creates page events', (done) => {
-      createElement((ele) => {
-        ele.offset = 20;
-        ele._render();
-        const btns = $('button', ele);
-        expect(btns.length).to.equal(3);
-        const bck =  btns[0];
-        const fwd =  btns[1];
-        const pls5 = btns[2];
+      paginationSk.offset = 20;
+      paginationSk._render();
+      const btns = $('button', paginationSk);
+      expect(btns.length).to.equal(3);
+      const bck =  btns[0];
+      const fwd =  btns[1];
+      const pls5 = btns[2];
 
-        let d = 0;
-        const deltas = [1 ,-1, 5];
-        ele.addEventListener('page-changed', (e) => {
-          expect(e.detail.delta).to.equal(deltas[d]);
-          d++;
-          if (d === 3) {
-            done();
-          }
-        });
-        fwd.click();
-        bck.click();
-        pls5.click();
+      let d = 0;
+      const deltas = [1 ,-1, 5];
+      paginationSk.addEventListener('page-changed', (e) => {
+        expect(e.detail.delta).to.equal(deltas[d]);
+        d++;
+        if (d === 3) {
+          done();
+        }
       });
+      fwd.click();
+      bck.click();
+      pls5.click();
     });
   }); // end describe('paging behavior')
-
-});
\ No newline at end of file
+});