Convert tests to karma

This change was done with Find-Replace. Additional manual
fixes exist in some tests (adding cleanups, replace some helper methods,
etc...).

This change contains only _test.js files and doesn't change any
production file.

Change-Id: I77973f7accbbd2b639beef71bcebf93e255cf8a1
diff --git a/polygerrit-ui/app/behaviors/base-url-behavior/base-url-behavior_test.js b/polygerrit-ui/app/behaviors/base-url-behavior/base-url-behavior_test.js
index 44173323..3b8a9cb 100644
--- a/polygerrit-ui/app/behaviors/base-url-behavior/base-url-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/base-url-behavior/base-url-behavior_test.js
@@ -19,7 +19,7 @@
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {BaseUrlBehavior} from './base-url-behavior.js';
 
-const basicFixture = fixtureFromElement('test-element');
+const basicFixture = fixtureFromElement('base-url-behavior-test-element');
 
 suite('base-url-behavior tests', () => {
   let element;
@@ -30,7 +30,7 @@
     window.CANONICAL_PATH = '/r';
     // Define a Polymer element that uses this behavior.
     Polymer({
-      is: 'test-element',
+      is: 'base-url-behavior-test-element',
       behaviors: [
         BaseUrlBehavior,
       ],
diff --git a/polygerrit-ui/app/behaviors/docs-url-behavior/docs-url-behavior_test.js b/polygerrit-ui/app/behaviors/docs-url-behavior/docs-url-behavior_test.js
index 0efd80f..93beb52 100644
--- a/polygerrit-ui/app/behaviors/docs-url-behavior/docs-url-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/docs-url-behavior/docs-url-behavior_test.js
@@ -1,36 +1,26 @@
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<!-- Polymer included for the html import polyfill. -->
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<title>docs-url-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <docs-url-behavior-element></docs-url-behavior-element>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {DocsUrlBehavior} from './docs-url-behavior.js';
+
+const basicFixture = fixtureFromElement('docs-url-behavior-element');
+
 suite('docs-url-behavior tests', () => {
   let element;
 
@@ -43,7 +33,7 @@
   });
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element._clearDocsBaseUrlCache();
   });
 
@@ -96,4 +86,4 @@
         });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior_test.js b/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior_test.js
index 1e842c1..c110b34 100644
--- a/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/dom-util-behavior/dom-util-behavior_test.js
@@ -1,46 +1,36 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>dom-util-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<test-fixture id="nested-structure">
-  <template>
-    <test-element></test-element>
-    <div>
-      <div class="a">
-        <div class="b">
-          <div class="c"></div>
-        </div>
-      </div>
-    </div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {DomUtilBehavior} from './dom-util-behavior.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const nestedStructureFixture = fixtureFromTemplate(html`
+  <dom-util-behavior-test-element></dom-util-behavior-test-element>
+  <div>
+    <div class="a">
+      <div class="b">
+        <div class="c"></div>
+      </div>
+    </div>
+  </div>
+`);
+
 suite('dom-util-behavior tests', () => {
   let element;
   let divs;
@@ -48,13 +38,13 @@
   suiteSetup(() => {
     // Define a Polymer element that uses this behavior.
     Polymer({
-      is: 'test-element',
+      is: 'dom-util-behavior-test-element',
       behaviors: [DomUtilBehavior],
     });
   });
 
   setup(() => {
-    const testDom = fixture('nested-structure');
+    const testDom = nestedStructureFixture.instantiate();
     element = testDom[0];
     divs = testDom[1];
   });
@@ -69,4 +59,4 @@
         divs.querySelector('.b')));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior_test.js b/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior_test.js
index c5f3f94..b29505f 100644
--- a/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/gr-access-behavior/gr-access-behavior_test.js
@@ -1,52 +1,39 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>keyboard-shortcut-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<test-fixture id="basic">
-  <template>
-    <test-element></test-element>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {AccessBehavior} from './gr-access-behavior.js';
+
+const basicFixture = fixtureFromElement('gr-access-behavior-test-element');
+
 suite('gr-access-behavior tests', () => {
   let element;
 
   suiteSetup(() => {
     // Define a Polymer element that uses this behavior.
     Polymer({
-      is: 'test-element',
+      is: 'gr-access-behavior-test-element',
       behaviors: [AccessBehavior],
     });
   });
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('toSortedArray', () => {
@@ -69,4 +56,4 @@
     assert.deepEqual(element.toSortedArray(rules), expectedResult);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior_test.js b/polygerrit-ui/app/behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior_test.js
index 3f58499..491444a 100644
--- a/polygerrit-ui/app/behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/gr-admin-nav-behavior/gr-admin-nav-behavior_test.js
@@ -1,39 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>keyboard-shortcut-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<test-fixture id="basic">
-  <template>
-    <test-element></test-element>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {AdminNavBehavior} from './gr-admin-nav-behavior.js';
+
+const basicFixture = fixtureFromElement('gr-admin-nav-behavior-test-element');
+
 suite('gr-admin-nav-behavior tests', () => {
   let element;
   let sandbox;
@@ -43,7 +30,7 @@
   suiteSetup(() => {
     // Define a Polymer element that uses this behavior.
     Polymer({
-      is: 'test-element',
+      is: 'gr-admin-nav-behavior-test-element',
       behaviors: [
         AdminNavBehavior,
       ],
@@ -51,7 +38,7 @@
   });
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     capabilityStub = sinon.stub();
     menuLinkStub = sinon.stub().returns([]);
@@ -366,4 +353,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.js b/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.js
index 3c5aedd..dfca358 100644
--- a/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/gr-change-table-behavior/gr-change-table-behavior_test.js
@@ -1,47 +1,35 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>keyboard-shortcut-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<test-fixture id="basic">
-  <template>
-    <test-element></test-element>
-  </template>
-</test-fixture>
-
-<test-fixture id="within-overlay">
-  <template>
-    <gr-overlay>
-      <test-element></test-element>
-    </gr-overlay>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {ChangeTableBehavior} from './gr-change-table-behavior.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromElement(
+    'gr-change-table-behavior-test-element');
+
+const withinOverlayFixture = fixtureFromTemplate(html`
+  <gr-overlay>
+    <gr-change-table-behavior-test-element>
+    </gr-change-table-behavior-test-element>
+  </gr-overlay>
+`);
+
 suite('gr-change-table-behavior tests', () => {
   let element;
   // eslint-disable-next-line no-unused-vars
@@ -50,14 +38,14 @@
   suiteSetup(() => {
     // Define a Polymer element that uses this behavior.
     Polymer({
-      is: 'test-element',
+      is: 'gr-change-table-behavior-test-element',
       behaviors: [ChangeTableBehavior],
     });
   });
 
   setup(() => {
-    element = fixture('basic');
-    overlay = fixture('within-overlay');
+    element = basicFixture.instantiate();
+    overlay = withinOverlayFixture.instantiate();
   });
 
   test('getComplementColumns', () => {
@@ -127,4 +115,4 @@
         columns.slice(0).concat(['Repo']));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/gr-display-name-behavior/gr-display-name-behavior_test.js b/polygerrit-ui/app/behaviors/gr-display-name-behavior/gr-display-name-behavior_test.js
index fa72c40..82108429 100644
--- a/polygerrit-ui/app/behaviors/gr-display-name-behavior/gr-display-name-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/gr-display-name-behavior/gr-display-name-behavior_test.js
@@ -1,39 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-display-name-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<test-fixture id="basic">
-  <template>
-    <test-element-anon></test-element-anon>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {DisplayNameBehavior} from './gr-display-name-behavior.js';
+
+const basicFixture = fixtureFromElement('test-element-anon');
+
 suite('gr-display-name-behavior tests', () => {
   let element;
   // eslint-disable-next-line no-unused-vars
@@ -54,7 +41,7 @@
   });
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('getUserName name only', () => {
@@ -97,4 +84,4 @@
         'Some user name (group)');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/gr-list-view-behavior/gr-list-view-behavior_test.js b/polygerrit-ui/app/behaviors/gr-list-view-behavior/gr-list-view-behavior_test.js
index 80013bf..bb54672 100644
--- a/polygerrit-ui/app/behaviors/gr-list-view-behavior/gr-list-view-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/gr-list-view-behavior/gr-list-view-behavior_test.js
@@ -1,39 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>keyboard-shortcut-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<test-fixture id="basic">
-  <template>
-    <test-element></test-element>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {ListViewBehavior} from './gr-list-view-behavior.js';
+
+const basicFixture = fixtureFromElement(
+    'gr-list-view-behavior-test-element');
+
 suite('gr-list-view-behavior tests', () => {
   let element;
   // eslint-disable-next-line no-unused-vars
@@ -42,13 +30,13 @@
   suiteSetup(() => {
     // Define a Polymer element that uses this behavior.
     Polymer({
-      is: 'test-element',
+      is: 'gr-list-view-behavior-test-element',
       behaviors: [ListViewBehavior],
     });
   });
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('computeLoadingClass', () => {
@@ -90,4 +78,4 @@
     assert.equal(element.getOffsetValue(params), 1);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.js b/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.js
index f03e3ac..b14c0bd 100644
--- a/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/gr-patch-set-behavior/gr-patch-set-behavior_test.js
@@ -1,28 +1,21 @@
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<!-- Polymer included for the html import polyfill. -->
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<title>gr-patch-set-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {PatchSetBehavior} from './gr-patch-set-behavior.js';
 suite('gr-patch-set-behavior tests', () => {
   test('getRevisionByPatchNum', () => {
@@ -321,4 +314,4 @@
     assert.equal(PatchSetBehavior.getParentIndex(-4), 4);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.js b/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.js
index cf5105e..94e82e2 100644
--- a/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/gr-path-list-behavior/gr-path-list-behavior_test.js
@@ -1,28 +1,21 @@
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<!-- Polymer included for the html import polyfill. -->
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<title>gr-path-list-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {PathListBehavior} from './gr-path-list-behavior.js';
 import {SpecialFilePath} from '../../constants/constants.js';
 
@@ -113,4 +106,4 @@
     assert.equal(shortenedPath, expectedPath);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior_test.js b/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior_test.js
index 79c515e..50a3316 100644
--- a/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/gr-tooltip-behavior/gr-tooltip-behavior_test.js
@@ -1,38 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<title>tooltip-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <tooltip-behavior-element></tooltip-behavior-element>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {TooltipBehavior} from './gr-tooltip-behavior.js';
+
+const basicFixture = fixtureFromElement('tooltip-behavior-element');
+
 suite('gr-tooltip-behavior tests', () => {
   let element;
   let sandbox;
@@ -58,7 +46,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -151,4 +139,4 @@
     assert.isTrue(removeListenerStub.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior_test.js b/polygerrit-ui/app/behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior_test.js
index d0a2cde..f62f50b 100644
--- a/polygerrit-ui/app/behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/gr-url-encoding-behavior/gr-url-encoding-behavior_test.js
@@ -1,38 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<title>gr-url-encoding-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <test-element></test-element>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {URLEncodingBehavior} from './gr-url-encoding-behavior.js';
+
+const basicFixture =
+    fixtureFromElement('gr-url-encoding-behavior-test-element');
+
 suite('gr-url-encoding-behavior tests', () => {
   let element;
   let sandbox;
@@ -40,14 +29,14 @@
   suiteSetup(() => {
     // Define a Polymer element that uses this behavior.
     Polymer({
-      is: 'test-element',
+      is: 'gr-url-encoding-behavior-test-element',
       behaviors: [URLEncodingBehavior],
     });
   });
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -89,4 +78,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.js b/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.js
index fcb7b4f..c3bcccc 100644
--- a/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior_test.js
@@ -1,47 +1,35 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>keyboard-shortcut-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<test-fixture id="basic">
-  <template>
-    <test-element></test-element>
-  </template>
-</test-fixture>
-
-<test-fixture id="within-overlay">
-  <template>
-    <gr-overlay>
-      <test-element></test-element>
-    </gr-overlay>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {KeyboardShortcutBehavior, KeyboardShortcutBinder} from './keyboard-shortcut-behavior.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture =
+    fixtureFromElement('keyboard-shortcut-behavior-test-element');
+
+const withinOverlayFixture = fixtureFromTemplate(html`
+<gr-overlay>
+  <keyboard-shortcut-behavior-test-element>      
+  </keyboard-shortcut-behavior-test-element>
+</gr-overlay>
+`);
+
 suite('keyboard-shortcut-behavior tests', () => {
   const kb = KeyboardShortcutBinder;
 
@@ -52,7 +40,7 @@
   suiteSetup(() => {
     // Define a Polymer element that uses this behavior.
     Polymer({
-      is: 'test-element',
+      is: 'keyboard-shortcut-behavior-test-element',
       behaviors: [KeyboardShortcutBehavior],
       keyBindings: {
         k: '_handleKey',
@@ -63,8 +51,8 @@
   });
 
   setup(() => {
-    element = fixture('basic');
-    overlay = fixture('within-overlay');
+    element = basicFixture.instantiate();
+    overlay = withinOverlayFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -326,7 +314,8 @@
 
   test('blocks kb shortcuts for anything in a gr-overlay', done => {
     const divEl = document.createElement('div');
-    const element = overlay.querySelector('test-element');
+    const element =
+        overlay.querySelector('keyboard-shortcut-behavior-test-element');
     element.appendChild(divEl);
     element._handleKey = e => {
       assert.isTrue(element.shouldSuppressKeyboardShortcut(e));
@@ -337,7 +326,8 @@
 
   test('blocks enter shortcut on an anchor', done => {
     const anchorEl = document.createElement('a');
-    const element = overlay.querySelector('test-element');
+    const element =
+        overlay.querySelector('keyboard-shortcut-behavior-test-element');
     element.appendChild(anchorEl);
     element._handleKey = e => {
       assert.isTrue(element.shouldSuppressKeyboardShortcut(e));
@@ -439,4 +429,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.js b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.js
index 980bc8f..8f63a25 100644
--- a/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/rest-client-behavior/rest-client-behavior_test.js
@@ -1,63 +1,46 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>keyboard-shortcut-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script type="module">
-import '../../test/common-test-setup.js';
-/** @type {string} */
-window.CANONICAL_PATH = '/r';
-</script>
-
-<test-fixture id="basic">
-  <template>
-    <test-element></test-element>
-  </template>
-</test-fixture>
-
-<test-fixture id="within-overlay">
-  <template>
-    <gr-overlay>
-      <test-element></test-element>
-    </gr-overlay>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {BaseUrlBehavior} from '../base-url-behavior/base-url-behavior.js';
 import {RESTClientBehavior} from './rest-client-behavior.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromElement('rest-client-behavior-test-element');
+
+const withinOverlayFixture = fixtureFromTemplate(html`
+<gr-overlay>
+  <rest-client-behavior-test-element></rest-client-behavior-test-element>
+</gr-overlay>
+`);
+
 suite('rest-client-behavior tests', () => {
   let element;
   // eslint-disable-next-line no-unused-vars
   let overlay;
+  let originalCanonicalPath;
 
   suiteSetup(() => {
+    originalCanonicalPath = window.CANONICAL_PATH;
+    window.CANONICAL_PATH = '/r';
     // Define a Polymer element that uses this behavior.
     Polymer({
-      is: 'test-element',
+      is: 'rest-client-behavior-test-element',
       behaviors: [
         BaseUrlBehavior,
         RESTClientBehavior,
@@ -65,9 +48,13 @@
     });
   });
 
+  suiteTeardown(() => {
+    window.CANONICAL_PATH = originalCanonicalPath;
+  });
+
   setup(() => {
-    element = fixture('basic');
-    overlay = fixture('within-overlay');
+    element = basicFixture.instantiate();
+    overlay = withinOverlayFixture.instantiate();
   });
 
   test('changeBaseURL', () => {
@@ -234,4 +221,4 @@
     assert.equal(statusString, 'Merge Conflict, WIP, Private');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior_test.js b/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior_test.js
index 6fe4460..ae37134 100644
--- a/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior_test.js
+++ b/polygerrit-ui/app/behaviors/safe-types-behavior/safe-types-behavior_test.js
@@ -1,38 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<title>safe-types-behavior</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <safe-types-element></safe-types-element>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
 import {SafeTypes} from './safe-types-behavior.js';
+
+const basicFixture = fixtureFromElement('safe-types-element');
+
 suite('gr-tooltip-behavior tests', () => {
   let element;
   let sandbox;
@@ -46,7 +34,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -119,4 +107,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.js b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.js
index c8c7f0c..973f3df 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.js
@@ -1,41 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-admin-group-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-admin-group-list></gr-admin-group-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-admin-group-list.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
+
+const basicFixture = fixtureFromElement('gr-admin-group-list');
+
 let counter = 0;
 const groupGenerator = () => {
   return {
@@ -60,7 +45,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -216,4 +201,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.js b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.js
index ec72bfd..6d47c5e 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.js
@@ -1,50 +1,35 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-admin-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-admin-view></gr-admin-view>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-admin-view.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
 
+const basicFixture = fixtureFromElement('gr-admin-view');
+
 suite('gr-admin-view tests', () => {
   let element;
   let sandbox;
 
   setup(done => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     stub('gr-rest-api-interface', {
       getProjectConfig() {
         return Promise.resolve({});
@@ -681,4 +666,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.js b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.js
index 003edfb..e00c23d 100644
--- a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-confirm-delete-item-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-confirm-delete-item-dialog></gr-confirm-delete-item-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-confirm-delete-item-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-confirm-delete-item-dialog');
+
 suite('gr-confirm-delete-item-dialog tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -87,4 +73,4 @@
     assert.notEqual(element._computeItemName('tags'), 'Branch');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.js b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.js
index eaee4a4..b87783e 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-create-change-dialog/gr-create-change-dialog_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-create-change-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-create-change-dialog></gr-create-change-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-create-change-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-create-change-dialog');
+
 suite('gr-create-change-dialog tests', () => {
   let element;
   let sandbox;
@@ -56,7 +42,7 @@
         }
       },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.repoName = 'test-repo';
     element._repoConfig = {
       private_by_default: {
@@ -164,4 +150,4 @@
     assert.equal(element._computePrivateSectionClass(false), '');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.js b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.js
index 164db53..cf17f24 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-create-group-dialog/gr-create-group-dialog_test.js
@@ -1,42 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-create-group-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-create-group-dialog></gr-create-group-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-create-group-dialog.js';
 import page from 'page/page.mjs';
 
+const basicFixture = fixtureFromElement('gr-create-group-dialog');
+
 suite('gr-create-group-dialog tests', () => {
   let element;
   let sandbox;
@@ -47,7 +31,7 @@
     stub('gr-rest-api-interface', {
       getLoggedIn() { return Promise.resolve(true); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -97,4 +81,4 @@
         });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog_test.js b/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog_test.js
index 2778d40..93d60ae 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-create-pointer-dialog/gr-create-pointer-dialog_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-create-pointer-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-create-pointer-dialog></gr-create-pointer-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-create-pointer-dialog.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-create-pointer-dialog');
+
 suite('gr-create-pointer-dialog tests', () => {
   let element;
   let sandbox;
@@ -48,7 +34,7 @@
     stub('gr-rest-api-interface', {
       getLoggedIn() { return Promise.resolve(true); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -132,4 +118,4 @@
     assert.equal(element._computeHideItemClass('tags'), '');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.js b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.js
index dfab4ac..b57bf25 100644
--- a/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-create-repo-dialog/gr-create-repo-dialog_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-create-repo-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-create-repo-dialog></gr-create-repo-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-create-repo-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-create-repo-dialog');
+
 suite('gr-create-repo-dialog tests', () => {
   let element;
   let sandbox;
@@ -43,7 +29,7 @@
     stub('gr-rest-api-interface', {
       getLoggedIn() { return Promise.resolve(true); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -102,4 +88,4 @@
     assert.deepEqual(element._repoConfig.owners, ['test-5']);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log_test.js b/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log_test.js
index 4590220..fdf073e 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-group-audit-log/gr-group-audit-log_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-group-audit-log</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-group-audit-log></gr-group-audit-log>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-group-audit-log.js';
+
+const basicFixture = fixtureFromElement('gr-group-audit-log');
+
 suite('gr-group-audit-log tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -113,4 +99,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.js b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.js
index 3a5bfd8..90228cc 100644
--- a/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-group-members/gr-group-members_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-group-members</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-group-members></gr-group-members>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-group-members.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-group-members');
+
 suite('gr-group-members tests', () => {
   let element;
   let sandbox;
@@ -150,7 +136,7 @@
         return Promise.resolve();
       },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox.stub(element, 'getBaseUrl').returns('https://test/site');
     element.groupId = 1;
     groupStub = sandbox.stub(
@@ -371,4 +357,4 @@
     element._loadGroupDetails();
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.js b/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.js
index 5621fff..0cb5dfe 100644
--- a/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-group/gr-group_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-group</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-group></gr-group>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-group.js';
+
+const basicFixture = fixtureFromElement('gr-group');
+
 suite('gr-group tests', () => {
   let element;
   let sandbox;
@@ -54,7 +40,7 @@
     stub('gr-rest-api-interface', {
       getLoggedIn() { return Promise.resolve(true); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     groupStub = sandbox.stub(
         element.$.restAPI,
         'getGroupConfig',
@@ -286,4 +272,4 @@
     assert.equal('user/group', element.$.uuid.text);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.js b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.js
index 1ce492e..1d9dacc 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.js
@@ -1,47 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-permission</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-permission></gr-permission>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-permission.js';
+
+const basicFixture = fixtureFromElement('gr-permission');
+
 suite('gr-permission tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox.stub(element.$.restAPI, 'getSuggestedGroups').returns(
         Promise.resolve({
           'Administrators': {
@@ -431,4 +416,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor_test.js b/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor_test.js
index 5eff42d..5791260 100644
--- a/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-plugin-config-array-editor/gr-plugin-config-array-editor_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-plugin-config-array-editor</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-plugin-config-array-editor></gr-plugin-config-array-editor>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-plugin-config-array-editor.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-plugin-config-array-editor');
+
 suite('gr-plugin-config-array-editor tests', () => {
   let element;
   let sandbox;
@@ -44,7 +30,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.pluginOption = {
       _key: 'test-key',
       info: {
@@ -141,4 +127,4 @@
     assert.equal(detail.notifyPath, 'test-key.values');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list_test.js b/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list_test.js
index e2c88a2..c1b32da 100644
--- a/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-plugin-list/gr-plugin-list_test.js
@@ -1,41 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-plugin-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-plugin-list></gr-plugin-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-plugin-list.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-plugin-list');
+
 let counter;
 const pluginGenerator = () => {
   const plugin = {
@@ -58,7 +43,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     counter = 0;
   });
 
@@ -181,4 +166,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.js b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.js
index 7d66cb0..6919940 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.js
@@ -1,43 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-repo-access</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-repo-access></gr-repo-access>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-repo-access.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-repo-access');
+
 suite('gr-repo-access tests', () => {
   let element;
   let sandbox;
@@ -116,7 +100,7 @@
   };
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     stub('gr-rest-api-interface', {
       getAccount() { return Promise.resolve(null); },
     });
@@ -1251,4 +1235,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.js b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.js
index a52ab92..b3fd560 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.js
@@ -1,42 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-repo-commands</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-repo-commands></gr-repo-commands>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-repo-commands.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-repo-commands');
+
 suite('gr-repo-commands tests', () => {
   let element;
   let sandbox;
@@ -44,7 +28,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     repoStub = sandbox.stub(
         element.$.restAPI,
         'getProjectConfig',
@@ -150,4 +134,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards_test.js b/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards_test.js
index dc12eff..0e058be 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-dashboards/gr-repo-dashboards_test.js
@@ -1,48 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-repo-dashboards</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-repo-dashboards></gr-repo-dashboards>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-repo-dashboards.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-repo-dashboards');
+
 suite('gr-repo-dashboards tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -158,4 +143,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.js b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.js
index 9d7bba4..fd3c4ae 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.js
@@ -1,42 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-repo-detail-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-repo-detail-list></gr-repo-detail-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-repo-detail-list.js';
 import page from 'page/page.mjs';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-repo-detail-list');
+
 let counter;
 const branchGenerator = () => {
   return {
@@ -78,7 +63,7 @@
 
     setup(() => {
       sandbox = sinon.sandbox.create();
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.detailType = 'branches';
       counter = 0;
       sandbox.stub(page, 'show');
@@ -354,7 +339,7 @@
 
     setup(() => {
       sandbox = sinon.sandbox.create();
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.detailType = 'tags';
       counter = 0;
       sandbox.stub(page, 'show');
@@ -573,4 +558,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.js b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.js
index 96cb9ff..e35f8e4 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.js
@@ -1,42 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-repo-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-repo-list></gr-repo-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-repo-list.js';
 import page from 'page/page.mjs';
 
+const basicFixture = fixtureFromElement('gr-repo-list');
+
 let counter;
 const repoGenerator = () => {
   return {
@@ -60,7 +44,7 @@
   setup(() => {
     sandbox = sinon.sandbox.create();
     sandbox.stub(page, 'show');
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     counter = 0;
   });
 
@@ -206,4 +190,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.js b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.js
index a2370d9..eea88de 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-repo-plugin-config</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-repo-plugin-config></gr-repo-plugin-config>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-repo-plugin-config.js';
+
+const basicFixture = fixtureFromElement('gr-repo-plugin-config');
+
 suite('gr-repo-plugin-config tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => sandbox.restore());
@@ -178,4 +164,4 @@
     assert.equal(detail.notifyPath, 'plugin.value');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.js b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.js
index 58b488a..345a034 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo_test.js
@@ -1,41 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-repo</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-repo></gr-repo>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-repo.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {PolymerElement} from '@polymer/polymer/polymer-element.js';
+
+const basicFixture = fixtureFromElement('gr-repo');
+
 suite('gr-repo tests', () => {
   let element;
   let sandbox;
@@ -120,7 +106,7 @@
         return Promise.resolve({download: {}});
       },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     repoStub = sandbox.stub(
         element.$.restAPI,
         'getProjectConfig',
@@ -397,4 +383,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.js b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.js
index f096eed..40cee04 100644
--- a/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.js
+++ b/polygerrit-ui/app/elements/admin/gr-rule-editor/gr-rule-editor_test.js
@@ -1,48 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-rule-editor</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-rule-editor></gr-rule-editor>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-rule-editor.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-rule-editor');
+
 suite('gr-rule-editor tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -623,4 +608,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.js b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.js
index e426d84..5084a3a 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.js
@@ -1,41 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-change-list-item</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-change-list-item></gr-change-list-item>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-change-list-item.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-change-list-item');
+
 suite('gr-change-list-item tests', () => {
   let element;
   let sandbox;
@@ -46,7 +31,7 @@
       getConfig() { return Promise.resolve({}); },
       getLoggedIn() { return Promise.resolve(false); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
@@ -309,4 +294,4 @@
         '…/test/repo');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.js b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.js
index 58ec4e1..89815f3 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-view/gr-change-list-view_test.js
@@ -1,43 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-change-list-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-change-list-view></gr-change-list-view>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-change-list-view.js';
 import page from 'page/page.mjs';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-change-list-view');
+
 const CHANGE_ID = 'IcA3dAB3edAB9f60B8dcdA6ef71A75980e4B7127';
 const COMMIT_HASH = '12345678';
 
@@ -54,7 +38,7 @@
       getAccountDetails() { return Promise.resolve({}); },
       getAccountStatus() { return Promise.resolve({}); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -266,4 +250,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.js b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.js
index 16abb10..5cf5d3b 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.js
@@ -1,76 +1,59 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-change-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script src="/node_modules/page/page.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-change-list></gr-change-list>
-  </template>
-</test-fixture>
-
-<test-fixture id="grouped">
-  <template>
-    <gr-change-list></gr-change-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-change-list.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {afterNextRender} from '@polymer/polymer/lib/utils/render-status.js';
-import {KeyboardShortcutBinder} from '../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
+import {TestKeyboardShortcutBinder} from '../../../test/test-utils.js';
+
+const basicFixture = fixtureFromElement('gr-change-list');
 
 suite('gr-change-list basic tests', () => {
-  // Define keybindings before attaching other fixtures.
-  const kb = KeyboardShortcutBinder;
-  kb.bindShortcut(kb.Shortcut.CURSOR_NEXT_CHANGE, 'j');
-  kb.bindShortcut(kb.Shortcut.CURSOR_PREV_CHANGE, 'k');
-  kb.bindShortcut(kb.Shortcut.OPEN_CHANGE, 'o');
-  kb.bindShortcut(kb.Shortcut.REFRESH_CHANGE_LIST, 'shift+r');
-  kb.bindShortcut(kb.Shortcut.TOGGLE_CHANGE_REVIEWED, 'r');
-  kb.bindShortcut(kb.Shortcut.TOGGLE_CHANGE_STAR, 's');
-  kb.bindShortcut(kb.Shortcut.NEXT_PAGE, 'n');
-  kb.bindShortcut(kb.Shortcut.NEXT_PAGE, 'p');
-
   let element;
   let sandbox;
 
+  suiteSetup(() => {
+    const kb = TestKeyboardShortcutBinder.push();
+    kb.bindShortcut(kb.Shortcut.CURSOR_NEXT_CHANGE, 'j');
+    kb.bindShortcut(kb.Shortcut.CURSOR_PREV_CHANGE, 'k');
+    kb.bindShortcut(kb.Shortcut.OPEN_CHANGE, 'o');
+    kb.bindShortcut(kb.Shortcut.REFRESH_CHANGE_LIST, 'shift+r');
+    kb.bindShortcut(kb.Shortcut.TOGGLE_CHANGE_REVIEWED, 'r');
+    kb.bindShortcut(kb.Shortcut.TOGGLE_CHANGE_STAR, 's');
+    kb.bindShortcut(kb.Shortcut.NEXT_PAGE, 'n');
+    kb.bindShortcut(kb.Shortcut.NEXT_PAGE, 'p');
+  });
+
+  suiteTeardown(() => {
+    TestKeyboardShortcutBinder.pop();
+  });
+
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
 
   suite('test show change number not logged in', () => {
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.account = null;
       element.preferences = null;
       element._config = {};
@@ -83,7 +66,7 @@
 
   suite('test show change number preference enabled', () => {
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.preferences = {
         legacycid_in_change_table: true,
         time_format: 'HHMM_12',
@@ -101,7 +84,7 @@
 
   suite('test show change number preference disabled', () => {
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       // legacycid_in_change_table is not set when false.
       element.preferences = {
         time_format: 'HHMM_12',
@@ -340,7 +323,7 @@
     let element;
 
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.sections = [
         {results: [{}]},
       ];
@@ -371,7 +354,7 @@
     let element;
 
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.sections = [
         {results: [{}]},
       ];
@@ -409,7 +392,7 @@
     let element;
 
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.sections = [
         {results: [{}]},
       ];
@@ -453,7 +436,7 @@
     /* This would only exist if somebody manually updated the config
     file. */
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.account = {_account_id: 1001};
       element.preferences = {
         legacycid_in_change_table: true,
@@ -478,7 +461,7 @@
 
     setup(() => {
       sandbox = sinon.sandbox.create();
-      element = fixture('basic');
+      element = basicFixture.instantiate();
     });
 
     teardown(() => { sandbox.restore(); });
@@ -531,7 +514,7 @@
 
     setup(() => {
       sandbox = sinon.sandbox.create();
-      element = fixture('basic');
+      element = basicFixture.instantiate();
     });
 
     teardown(() => { sandbox.restore(); });
@@ -659,4 +642,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.js b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.js
index 9b8ed29..9dd0a35 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.js
+++ b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.js
@@ -1,44 +1,30 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-create-change-help</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-create-change-help></gr-create-change-help>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-create-change-help.js';
+
+const basicFixture = fixtureFromElement('gr-create-change-help');
+
 suite('gr-create-change-help tests', () => {
   let element;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('Create change tap', done => {
@@ -47,4 +33,4 @@
         .querySelector('gr-button'));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog_test.js b/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog_test.js
index e6cd587..9dbcd29 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog_test.js
+++ b/polygerrit-ui/app/elements/change-list/gr-create-commands-dialog/gr-create-commands-dialog_test.js
@@ -1,44 +1,30 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-create-commands-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-create-commands-dialog></gr-create-commands-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-create-commands-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-create-commands-dialog');
+
 suite('gr-create-commands-dialog tests', () => {
   let element;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('_computePushCommand', () => {
@@ -51,4 +37,4 @@
         'git push origin HEAD:refs/for/stable-2.15');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.js b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.js
index 2fcf233..bf24c1b 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.js
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.js
@@ -1,42 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-dashboard-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-dashboard-view></gr-dashboard-view>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-dashboard-view.js';
 import {isHidden} from '../../../test/test-utils.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-dashboard-view');
+
 suite('gr-dashboard-view tests', () => {
   let element;
   let sandbox;
@@ -49,7 +34,7 @@
       getAccountDetails() { return Promise.resolve({}); },
       getAccountStatus() { return Promise.resolve(false); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     getChangesStub = sandbox.stub(element.$.restAPI, 'getChanges',
         (_, qs) => Promise.resolve(qs.map(() => [])));
@@ -378,4 +363,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header_test.js b/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header_test.js
index 78c1f09..b93bbb2 100644
--- a/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header_test.js
+++ b/polygerrit-ui/app/elements/change-list/gr-repo-header/gr-repo-header_test.js
@@ -1,48 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-repo-header</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-repo-header></gr-repo-header>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-repo-header.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-repo-header');
+
 suite('gr-repo-header tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
@@ -56,4 +41,4 @@
     assert.equal(element._repoUrl, 'http://test.com/test');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.js b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.js
index 44eb96c..76272c8 100644
--- a/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.js
+++ b/polygerrit-ui/app/elements/change-list/gr-user-header/gr-user-header_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-user-header</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-user-header></gr-user-header>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-user-header.js';
+
+const basicFixture = fixtureFromElement('gr-user-header');
+
 suite('gr-user-header tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
@@ -78,4 +64,4 @@
     assert.notInclude(element._computeDashboardLinkClass(true, true), 'hide');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.js b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.js
index 5efeebd..daa31392 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.js
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.js
@@ -1,42 +1,28 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-change-actions</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-change-actions></gr-change-actions>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-change-actions.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
+
+const basicFixture = fixtureFromElement('gr-change-actions');
+
 const CHERRY_PICK_TYPES = {
   SINGLE_CHANGE: 1,
   TOPIC: 2,
@@ -103,7 +89,7 @@
       sandbox.stub(pluginLoader, 'awaitPluginsLoaded')
           .returns(Promise.resolve());
 
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.change = {};
       element.changeNum = '42';
       element.latestPatchNum = '2';
@@ -2019,7 +2005,7 @@
       sandbox.stub(pluginLoader, 'awaitPluginsLoaded')
           .returns(Promise.resolve());
 
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       // getChangeRevisionActions is not called without
       // set the following properies
       element.change = {};
@@ -2064,4 +2050,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.js
index c3f6113..23c4d8a 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata-it_test.js
@@ -129,6 +129,11 @@
       });
     });
 
+    teardown(() => {
+      document.body.querySelectorAll('custom-style')
+          .forEach(style => style.remove());
+    });
+
     for (const sectionSelector of sectionSelectors) {
       test('section.strategy may have display: none', () => {
         assert.equal(getStyle(sectionSelector, 'display'), 'none');
@@ -149,6 +154,11 @@
       element = createElement();
     });
 
+    teardown(() => {
+      document.body.querySelectorAll('custom-style')
+          .forEach(style => style.remove());
+    });
+
     test('labels changed callback', done => {
       let callCount = 0;
       const labelChangeSpy = sandbox.spy(arg => {
@@ -177,4 +187,4 @@
       plugin.changeMetadata().onLabelsChanged(labelChangeSpy);
     });
   });
-});
\ No newline at end of file
+});
diff --git a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.js b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.js
index 276e821..d8a90fc 100644
--- a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.js
+++ b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.js
@@ -1,45 +1,31 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-change-requirements</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-change-requirements></gr-change-requirements>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-change-requirements.js';
 import {isHidden} from '../../../test/test-utils.js';
+
+const basicFixture = fixtureFromElement('gr-change-requirements');
+
 suite('gr-change-metadata tests', () => {
   let element;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('requirements computed fields', () => {
@@ -233,4 +219,4 @@
     assert.strictEqual(requirement.querySelector('.approved'), null);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
index 2f607a6..3790e7f 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.js
@@ -21,7 +21,6 @@
 import {PrimaryTab, SecondaryTab, ChangeStatus} from '../../../constants/constants.js';
 
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
-import {KeyboardShortcutBinder} from '../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js';
 import {GrEditConstants} from '../../edit/gr-edit-constants.js';
 import {_testOnly_resetEndpoints} from '../../shared/gr-js-api-interface/gr-plugin-endpoints.js';
 import {getComputedStyleValue} from '../../../utils/dom-util.js';
@@ -30,27 +29,35 @@
 import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
 
 import 'lodash/lodash.js';
+import {TestKeyboardShortcutBinder} from '../../../test/test-utils.js';
 
 const pluginApi = _testOnly_initGerritPluginApi();
 const fixture = fixtureFromElement('gr-change-view');
 
 suite('gr-change-view tests', () => {
-  const kb = KeyboardShortcutBinder;
-  kb.bindShortcut(kb.Shortcut.SEND_REPLY, 'ctrl+enter');
-  kb.bindShortcut(kb.Shortcut.REFRESH_CHANGE, 'shift+r');
-  kb.bindShortcut(kb.Shortcut.OPEN_REPLY_DIALOG, 'a');
-  kb.bindShortcut(kb.Shortcut.OPEN_DOWNLOAD_DIALOG, 'd');
-  kb.bindShortcut(kb.Shortcut.TOGGLE_DIFF_MODE, 'm');
-  kb.bindShortcut(kb.Shortcut.TOGGLE_CHANGE_STAR, 's');
-  kb.bindShortcut(kb.Shortcut.UP_TO_DASHBOARD, 'u');
-  kb.bindShortcut(kb.Shortcut.EXPAND_ALL_MESSAGES, 'x');
-  kb.bindShortcut(kb.Shortcut.COLLAPSE_ALL_MESSAGES, 'z');
-  kb.bindShortcut(kb.Shortcut.OPEN_DIFF_PREFS, ',');
-  kb.bindShortcut(kb.Shortcut.EDIT_TOPIC, 't');
-
   let element;
   let sandbox;
   let navigateToChangeStub;
+
+  suiteSetup(() => {
+    const kb = TestKeyboardShortcutBinder.push();
+    kb.bindShortcut(kb.Shortcut.SEND_REPLY, 'ctrl+enter');
+    kb.bindShortcut(kb.Shortcut.REFRESH_CHANGE, 'shift+r');
+    kb.bindShortcut(kb.Shortcut.OPEN_REPLY_DIALOG, 'a');
+    kb.bindShortcut(kb.Shortcut.OPEN_DOWNLOAD_DIALOG, 'd');
+    kb.bindShortcut(kb.Shortcut.TOGGLE_DIFF_MODE, 'm');
+    kb.bindShortcut(kb.Shortcut.TOGGLE_CHANGE_STAR, 's');
+    kb.bindShortcut(kb.Shortcut.UP_TO_DASHBOARD, 'u');
+    kb.bindShortcut(kb.Shortcut.EXPAND_ALL_MESSAGES, 'x');
+    kb.bindShortcut(kb.Shortcut.COLLAPSE_ALL_MESSAGES, 'z');
+    kb.bindShortcut(kb.Shortcut.OPEN_DIFF_PREFS, ',');
+    kb.bindShortcut(kb.Shortcut.EDIT_TOPIC, 't');
+  });
+
+  suiteTeardown(() => {
+    TestKeyboardShortcutBinder.pop();
+  });
+
   const TEST_SCROLL_TOP_PX = 100;
 
   const ROBOT_COMMENTS_LIMIT = 10;
diff --git a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.js b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.js
index 075b883..1de2964 100644
--- a/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.js
+++ b/polygerrit-ui/app/elements/change/gr-comment-list/gr-comment-list_test.js
@@ -1,48 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-comment-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-comment-list></gr-comment-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-comment-list.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-comment-list');
+
 suite('gr-comment-list tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     sandbox.stub(GerritNav, 'mapCommentlinks', x => x);
   });
@@ -129,4 +114,4 @@
         [123, 'proj', 'foo.cc', 4, -12, 456, true]);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.js b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.js
index d9664ec..8af988e 100644
--- a/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.js
+++ b/polygerrit-ui/app/elements/change/gr-commit-info/gr-commit-info_test.js
@@ -1,49 +1,34 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-commit-info</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-commit-info></gr-commit-info>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../../core/gr-router/gr-router.js';
 import './gr-commit-info.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-commit-info');
+
 suite('gr-commit-info tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -136,4 +121,4 @@
         element.serverConfig));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.js b/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.js
index c1e1165..34b59e1 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-confirm-abandon-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-confirm-abandon-dialog></gr-confirm-abandon-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-confirm-abandon-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-confirm-abandon-dialog');
+
 suite('gr-confirm-abandon-dialog tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -79,4 +65,4 @@
     assert.isTrue(element._handleCancelTap.calledOnce);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.js b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.js
index e0016f0..a8528c5 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.js
@@ -1,46 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-confirm-cherrypick-conflict-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-confirm-cherrypick-conflict-dialog></gr-confirm-cherrypick-conflict-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-confirm-cherrypick-conflict-dialog.js';
+
+const basicFixture =
+    fixtureFromElement('gr-confirm-cherrypick-conflict-dialog');
+
 suite('gr-confirm-cherrypick-conflict-dialog tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
@@ -75,4 +62,4 @@
     assert.isTrue(element._handleCancelTap.calledOnce);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.js b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.js
index 000718b..1f4e214 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-dialog/gr-confirm-cherrypick-dialog_test.js
@@ -1,40 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-confirm-cherrypick-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-confirm-cherrypick-dialog></gr-confirm-cherrypick-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-confirm-cherrypick-dialog.js';
 
+const basicFixture = fixtureFromElement('gr-confirm-cherrypick-dialog');
+
 const CHERRY_PICK_TYPES = {
   SINGLE_CHANGE: 1,
   TOPIC: 2,
@@ -60,7 +45,7 @@
         }
       },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.project = 'test-project';
   });
 
@@ -182,4 +167,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.js b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.js
index a8392aa..0241112 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-move-dialog/gr-confirm-move-dialog_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-confirm-move-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-confirm-move-dialog></gr-confirm-move-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-confirm-move-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-confirm-move-dialog');
+
 suite('gr-confirm-move-dialog tests', () => {
   let element;
 
@@ -53,7 +39,7 @@
         }
       },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.project = 'test-project';
   });
 
@@ -80,4 +66,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.js b/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.js
index 080a7e0..d50e889 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-rebase-dialog/gr-confirm-rebase-dialog_test.js
@@ -1,45 +1,31 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-confirm-rebase-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-confirm-rebase-dialog></gr-confirm-rebase-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-confirm-rebase-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-confirm-rebase-dialog');
+
 suite('gr-confirm-rebase-dialog tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -201,4 +187,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.js b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.js
index 3a341c5..5d1a4eb 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-dialog/gr-confirm-revert-dialog_test.js
@@ -1,45 +1,31 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-confirm-revert-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-confirm-revert-dialog></gr-confirm-revert-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-confirm-revert-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-confirm-revert-dialog');
+
 suite('gr-confirm-revert-dialog tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox =sinon.sandbox.create();
   });
 
@@ -98,4 +84,4 @@
     assert.equal(element._message, expected);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog_test.js b/polygerrit-ui/app/elements/change/gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog_test.js
index a11d996..2b5a064 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-revert-submission-dialog/gr-confirm-revert-submission-dialog_test.js
@@ -1,46 +1,31 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-confirm-revert-submission-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-confirm-revert-submission-dialog>
-    </gr-confirm-revert-submission-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-confirm-revert-submission-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-confirm-revert-submission-dialog');
+
 suite('gr-confirm-revert-submission-dialog tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -96,4 +81,4 @@
     assert.equal(element.message, expected);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.js b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.js
index 30699d5..ff5478f 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.js
@@ -1,47 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-confirm-submit-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script src="/node_modules/page/page.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-confirm-submit-dialog></gr-confirm-submit-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-confirm-submit-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-confirm-submit-dialog');
+
 suite('gr-file-list-header tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -97,4 +82,4 @@
     assert.equal(element._computeHasChangeEdit(change2), false);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.js b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.js
index 46c57fe..5b7cbd5 100644
--- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.js
@@ -1,46 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-download-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-download-dialog></gr-download-dialog>
-  </template>
-</test-fixture>
-
-<test-fixture id="loggedIn">
-  <template>
-    <gr-download-dialog logged-in></gr-download-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-download-dialog.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-download-dialog');
+
 function getChangeObject() {
   return {
     current_revision: '34685798fe548b6d17d1e8e5edc43a26d055cc72',
@@ -126,7 +106,7 @@
   setup(() => {
     sandbox = sinon.sandbox.create();
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.patchNum = '1';
     element.config = {
       schemes: {
@@ -219,4 +199,4 @@
     assert.isFalse(element._computeHidePatchFile(change2, patchNum));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.js b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.js
index 2a5a302..30a012e 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.js
@@ -1,50 +1,28 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-file-list-header</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script src="/node_modules/page/page.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-file-list-header></gr-file-list-header>
-  </template>
-</test-fixture>
-
-<test-fixture id="blank">
-  <template>
-    <div></div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-file-list-header.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {GrFileListConstants} from '../gr-file-list-constants.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-file-list-header');
+
 suite('gr-file-list-header tests', () => {
   let element;
   let sandbox;
@@ -56,7 +34,7 @@
       getAccount() { return Promise.resolve(null); },
       _fetchSharedCacheURL() { return Promise.resolve({}); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(done => {
@@ -329,4 +307,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.js b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.js
index ad0d1cf..3a6cce8 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.js
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.js
@@ -1,83 +1,79 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../../../test/common-test-setup-karma.js';
+import '../../diff/gr-comment-api/gr-comment-api.js';
+import {getMockDiffResponse} from '../../../test/mocks/diff-response.js';
+import './gr-file-list.js';
+import {createCommentApiMockWithTemplateElement} from '../../../test/mocks/comment-api.js';
+import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+import {GrFileListConstants} from '../gr-file-list-constants.js';
+import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
+import {runA11yAudit} from '../../../test/a11y-test-utils.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+import {TestKeyboardShortcutBinder} from '../../../test/test-utils.js';
 
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-file-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script src="/components/web-component-tester/data/a11ySuite.js"></script>
-<script src="/node_modules/page/page.js"></script>
-
-<dom-module id="comment-api-mock">
-  <template>
+const commentApiMock = createCommentApiMockWithTemplateElement(
+    'gr-file-list-comment-api-mock', html`
     <gr-file-list id="fileList"
         change-comments="[[_changeComments]]"
         on-reload-drafts="_reloadDraftsWithCallback"></gr-file-list>
     <gr-comment-api id="commentAPI"></gr-comment-api>
-  </template>
-  </dom-module>
+`);
 
-<test-fixture id="basic">
-  <template>
-    <comment-api-mock></comment-api-mock>
-  </template>
-</test-fixture>
+const basicFixture = fixtureFromElement(commentApiMock.is);
 
-<script type="module">
-import '../../../test/common-test-setup.js';
-import '../../diff/gr-comment-api/gr-comment-api.js';
-import {getMockDiffResponse} from '../../../test/mocks/diff-response.js';
-import './gr-file-list.js';
-import '../../../test/mocks/comment-api.js';
-import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
-import {KeyboardShortcutBinder} from '../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js';
-import {GrFileListConstants} from '../gr-file-list-constants.js';
-import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
+suite('gr-diff a11y test', () => {
+  test('audit', async () => {
+    await runA11yAudit(basicFixture);
+  });
+});
 
 suite('gr-file-list tests', () => {
-  const kb = KeyboardShortcutBinder;
-  kb.bindShortcut(kb.Shortcut.LEFT_PANE, 'shift+left');
-  kb.bindShortcut(kb.Shortcut.RIGHT_PANE, 'shift+right');
-  kb.bindShortcut(kb.Shortcut.TOGGLE_INLINE_DIFF, 'i:keyup');
-  kb.bindShortcut(kb.Shortcut.TOGGLE_ALL_INLINE_DIFFS, 'shift+i:keyup');
-  kb.bindShortcut(kb.Shortcut.CURSOR_NEXT_FILE, 'j', 'down');
-  kb.bindShortcut(kb.Shortcut.CURSOR_PREV_FILE, 'k', 'up');
-  kb.bindShortcut(kb.Shortcut.NEXT_LINE, 'j', 'down');
-  kb.bindShortcut(kb.Shortcut.PREV_LINE, 'k', 'up');
-  kb.bindShortcut(kb.Shortcut.NEW_COMMENT, 'c');
-  kb.bindShortcut(kb.Shortcut.OPEN_LAST_FILE, '[');
-  kb.bindShortcut(kb.Shortcut.OPEN_FIRST_FILE, ']');
-  kb.bindShortcut(kb.Shortcut.OPEN_FILE, 'o');
-  kb.bindShortcut(kb.Shortcut.NEXT_CHUNK, 'n');
-  kb.bindShortcut(kb.Shortcut.PREV_CHUNK, 'p');
-  kb.bindShortcut(kb.Shortcut.TOGGLE_FILE_REVIEWED, 'r');
-  kb.bindShortcut(kb.Shortcut.TOGGLE_LEFT_PANE, 'shift+a');
-
   let element;
   let commentApiWrapper;
   let sandbox;
   let saveStub;
   let loadCommentSpy;
 
+  suiteSetup(() => {
+    const kb = TestKeyboardShortcutBinder.push();
+    kb.bindShortcut(kb.Shortcut.LEFT_PANE, 'shift+left');
+    kb.bindShortcut(kb.Shortcut.RIGHT_PANE, 'shift+right');
+    kb.bindShortcut(kb.Shortcut.TOGGLE_INLINE_DIFF, 'i:keyup');
+    kb.bindShortcut(kb.Shortcut.TOGGLE_ALL_INLINE_DIFFS, 'shift+i:keyup');
+    kb.bindShortcut(kb.Shortcut.CURSOR_NEXT_FILE, 'j', 'down');
+    kb.bindShortcut(kb.Shortcut.CURSOR_PREV_FILE, 'k', 'up');
+    kb.bindShortcut(kb.Shortcut.NEXT_LINE, 'j', 'down');
+    kb.bindShortcut(kb.Shortcut.PREV_LINE, 'k', 'up');
+    kb.bindShortcut(kb.Shortcut.NEW_COMMENT, 'c');
+    kb.bindShortcut(kb.Shortcut.OPEN_LAST_FILE, '[');
+    kb.bindShortcut(kb.Shortcut.OPEN_FIRST_FILE, ']');
+    kb.bindShortcut(kb.Shortcut.OPEN_FILE, 'o');
+    kb.bindShortcut(kb.Shortcut.NEXT_CHUNK, 'n');
+    kb.bindShortcut(kb.Shortcut.PREV_CHUNK, 'p');
+    kb.bindShortcut(kb.Shortcut.TOGGLE_FILE_REVIEWED, 'r');
+    kb.bindShortcut(kb.Shortcut.TOGGLE_LEFT_PANE, 'shift+a');
+  });
+
+  suiteTeardown(() => {
+    TestKeyboardShortcutBinder.pop();
+  });
+
   suite('basic tests', () => {
     setup(done => {
       sandbox = sinon.sandbox.create();
@@ -100,7 +96,7 @@
 
       // Element must be wrapped in an element with direct access to the
       // comment API.
-      commentApiWrapper = fixture('basic');
+      commentApiWrapper = basicFixture.instantiate();
       element = commentApiWrapper.$.fileList;
       loadCommentSpy = sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll');
 
@@ -129,9 +125,9 @@
 
     test('correct number of files are shown', () => {
       element.fileListIncrement = 300;
-      element._filesByPath = _.range(500)
-          .reduce((_filesByPath, i) => {
-            _filesByPath['/file' + i] = {lines_inserted: 9};
+      element._filesByPath = Array(500).fill(0)
+          .reduce((_filesByPath, _, idx) => {
+            _filesByPath['/file' + idx] = {lines_inserted: 9};
             return _filesByPath;
           }, {});
 
@@ -157,9 +153,9 @@
 
     test('rendering each row calls the _reportRenderedRow method', () => {
       const renderedStub = sandbox.stub(element, '_reportRenderedRow');
-      element._filesByPath = _.range(10)
-          .reduce((_filesByPath, i) => {
-            _filesByPath['/file' + i] = {lines_inserted: 9};
+      element._filesByPath = Array(10).fill(0)
+          .reduce((_filesByPath, _, idx) => {
+            _filesByPath['/file' + idx] = {lines_inserted: 9};
             return _filesByPath;
           }, {});
       flushAsynchronousOperations();
@@ -1580,7 +1576,7 @@
 
       // Element must be wrapped in an element with direct access to the
       // comment API.
-      commentApiWrapper = fixture('basic');
+      commentApiWrapper = basicFixture.instantiate();
       element = commentApiWrapper.$.fileList;
       loadCommentSpy = sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll');
       element.diffPrefs = {};
@@ -1947,6 +1943,5 @@
       assert.equal(commentStubCount, commentStub.callCount);
     });
   });
-  a11ySuite('basic');
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.js b/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.js
index 5d5b1fc..efef229 100644
--- a/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-included-in-dialog/gr-included-in-dialog_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-included-in-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-included-in-dialog></gr-included-in-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-included-in-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-included-in-dialog');
+
 suite('gr-included-in-dialog', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
@@ -97,4 +83,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.js b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.js
index ca4fac3..eb09658 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.js
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.js
@@ -1,47 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-label-score-row</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-label-score-row></gr-label-score-row>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-label-score-row.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-label-score-row');
+
 suite('gr-label-row-score tests', () => {
   let element;
   let sandbox;
 
   setup(done => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.labels = {
       'Code-Review': {
         values: {
@@ -387,4 +373,4 @@
     assert.isNull(element.selectedValue);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.js b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.js
index 7ee86d6..4a182c1 100644
--- a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.js
+++ b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-label-scores</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-label-scores></gr-label-scores>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-label-scores.js';
+
+const basicFixture = fixtureFromElement('gr-label-scores');
+
 suite('gr-label-scores tests', () => {
   let element;
   let sandbox;
@@ -43,7 +29,7 @@
     stub('gr-rest-api-interface', {
       getLoggedIn() { return Promise.resolve(false); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.change = {
       _number: '123',
       labels: {
@@ -193,4 +179,4 @@
     ]);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.js b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.js
index 332ca52..d425398 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.js
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-message</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-message></gr-message>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-message.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-message');
+
 suite('gr-message tests', () => {
   let element;
 
@@ -47,7 +33,7 @@
         getIsAdmin() { return Promise.resolve(true); },
         deleteChangeCommitMessage() { return Promise.resolve({}); },
       });
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       flush(done);
     });
 
@@ -369,7 +355,7 @@
         getIsAdmin() { return Promise.resolve(false); },
         deleteChangeCommitMessage() { return Promise.resolve({}); },
       });
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       flush(done);
     });
 
@@ -399,7 +385,7 @@
 
   suite('patchset comment summary', () => {
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.message = {id: '6a07f64a82f96e7337ca5f7f84cfc73abf8ac2a3'};
     });
 
@@ -467,7 +453,7 @@
         getIsAdmin() { return Promise.resolve(false); },
         deleteChangeCommitMessage() { return Promise.resolve({}); },
       });
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       flush(done);
     });
 
@@ -521,4 +507,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list-experimental_test.js b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list-experimental_test.js
index c520b05..b9897dd 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list-experimental_test.js
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list-experimental_test.js
@@ -1,55 +1,42 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2020 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-messages-list-experimental</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<dom-module id="comment-api-mock">
-  <template>
-    <gr-messages-list-experimental
-        id="messagesList"
-        change-comments="[[_changeComments]]"></gr-messages-list-experimental>
-    <gr-comment-api id="commentAPI"></gr-comment-api>
-  </template>
-  </dom-module>
-
-<test-fixture id="basic">
-  <template>
-    <comment-api-mock>
-      <gr-messages-list-experimental></gr-messages-list-experimental>
-    </comment-api-mock>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../../diff/gr-comment-api/gr-comment-api.js';
 import './gr-messages-list-experimental.js';
-import '../../../test/mocks/comment-api.js';
+import {createCommentApiMockWithTemplateElement} from '../../../test/mocks/comment-api.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {TEST_ONLY} from './gr-messages-list-experimental.js';
 import {MessageTag} from '../../../constants/constants.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+createCommentApiMockWithTemplateElement(
+    'gr-messages-list-experimental-comment-mock-api', html`
+     <gr-messages-list-experimental
+         id="messagesList"
+         change-comments="[[_changeComments]]"></gr-messages-list-experimental>
+     <gr-comment-api id="commentAPI"></gr-comment-api>
+`);
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-messages-list-experimental-comment-mock-api>
+  <gr-messages-list-experimental></gr-messages-list-experimental>
+</gr-messages-list-experimental-comment-mock-api>
+`);
 
 const randomMessage = function(opt_params) {
   const params = opt_params || {};
@@ -68,6 +55,11 @@
   };
 };
 
+function generateRandomMessages(count) {
+  return new Array(count).fill()
+      .map(() => randomMessage());
+}
+
 suite('gr-messages-list-experimental tests', () => {
   let element;
   let messages;
@@ -149,10 +141,10 @@
         getDiffDrafts() { return Promise.resolve({}); },
       });
       sandbox = sinon.sandbox.create();
-      messages = _.times(3, randomMessage);
+      messages = generateRandomMessages(3);
       // Element must be wrapped in an element with direct access to the
       // comment API.
-      commentApiWrapper = fixture('basic');
+      commentApiWrapper = basicFixture.instantiate();
       element = commentApiWrapper.$.messagesList;
       element.messages = messages;
 
@@ -243,7 +235,7 @@
     test('scroll to message offscreen', () => {
       const scrollToStub = sandbox.stub(window, 'scrollTo');
       const highlightStub = sandbox.stub(element, '_highlightEl');
-      element.messages = _.times(25, randomMessage);
+      element.messages = generateRandomMessages(25);
       flushAsynchronousOperations();
       assert.isFalse(scrollToStub.called);
       assert.isFalse(highlightStub.called);
@@ -471,7 +463,7 @@
 
       // Element must be wrapped in an element with direct access to the
       // comment API.
-      commentApiWrapper = fixture('basic');
+      commentApiWrapper = basicFixture.instantiate();
       element = commentApiWrapper.$.messagesList;
       sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll');
       element.messages = messages;
@@ -558,4 +550,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.js b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.js
index 4a0f3f1..e3649fa 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.js
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.js
@@ -1,53 +1,42 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+import {createCommentApiMockWithTemplateElement} from '../../../test/mocks/comment-api';
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-messages-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<dom-module id="comment-api-mock">
-  <template>
-    <gr-messages-list
-        id="messagesList"
-        change-comments="[[_changeComments]]"></gr-messages-list>
-    <gr-comment-api id="commentAPI"></gr-comment-api>
-  </template>
-  </dom-module>
-
-<test-fixture id="basic">
-  <template>
-    <comment-api-mock>
-      <gr-messages-list></gr-messages-list>
-    </comment-api-mock>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../../diff/gr-comment-api/gr-comment-api.js';
 import './gr-messages-list.js';
 import '../../../test/mocks/comment-api.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+createCommentApiMockWithTemplateElement(
+    'gr-messages-list-comment-mock-api', html`
+     <gr-messages-list
+         id="messagesList"
+         change-comments="[[_changeComments]]"></gr-messages-list>
+     <gr-comment-api id="commentAPI"></gr-comment-api>
+`);
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-messages-list-comment-mock-api>
+  <gr-messages-list></gr-messages-list>
+</gr-messages-list-comment-mock-api>
+`);
+
 const randomMessage = function(opt_params) {
   const params = opt_params || {};
   const author1 = {
@@ -69,6 +58,32 @@
       randomMessage(opt_params));
 };
 
+function generateRandomMessages(count) {
+  return new Array(count).fill()
+      .map(() => randomMessage());
+}
+
+function generateRandomAutomatedMessages(count) {
+  return new Array(count).fill()
+      .map(() => randomAutomated());
+}
+
+// Returns a shuffled copy of array
+export function shuffle(arr) {
+  const result = [];
+  for (const item of arr) {
+    // Random number in the interval [0..array.length]
+    const j = Math.floor(Math.random() * (arr.length + 1));
+    if (j < result.length) {
+      result.push(result[j]);
+      result[j] = item;
+    } else {
+      result.push(item);
+    }
+  }
+  return result;
+}
+
 suite('gr-messages-list tests', () => {
   let element;
   let messages;
@@ -141,10 +156,10 @@
         getDiffDrafts() { return Promise.resolve({}); },
       });
       sandbox = sinon.sandbox.create();
-      messages = _.times(3, randomMessage);
+      messages = generateRandomMessages(3);
       // Element must be wrapped in an element with direct access to the
       // comment API.
-      commentApiWrapper = fixture('basic');
+      commentApiWrapper = basicFixture.instantiate();
       element = commentApiWrapper.$.messagesList;
       element.messages = messages;
 
@@ -159,7 +174,7 @@
 
     test('show some old messages', () => {
       assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden'));
-      element.messages = _.times(26, randomMessage);
+      element.messages = generateRandomMessages(26);
       flushAsynchronousOperations();
 
       assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden'));
@@ -181,7 +196,7 @@
 
     test('show all old messages', () => {
       assert.isTrue(element.$.messageControlsContainer.hasAttribute('hidden'));
-      element.messages = _.times(26, randomMessage);
+      element.messages = generateRandomMessages(26);
       flushAsynchronousOperations();
 
       assert.isFalse(element.$.messageControlsContainer.hasAttribute('hidden'));
@@ -196,8 +211,8 @@
     });
 
     test('message count respects automated', () => {
-      element.messages = _.times(10, randomAutomated)
-          .concat(_.times(11, randomMessage));
+      element.messages = generateRandomAutomatedMessages(10)
+          .concat(generateRandomMessages(11));
       flushAsynchronousOperations();
 
       assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(),
@@ -210,8 +225,8 @@
     });
 
     test('message count still respects non-automated on toggle', () => {
-      element.messages = _.times(10, randomMessage)
-          .concat(_.times(11, randomAutomated));
+      element.messages = generateRandomMessages(10)
+          .concat(generateRandomAutomatedMessages(11));
       flushAsynchronousOperations();
 
       assert.equal(element.$.oldMessagesBtn.innerText.toUpperCase(),
@@ -226,8 +241,8 @@
     });
 
     test('show all messages respects expand', () => {
-      element.messages = _.times(10, randomAutomated)
-          .concat(_.times(11, randomMessage));
+      element.messages = generateRandomAutomatedMessages(10)
+          .concat(generateRandomMessages(11));
       flushAsynchronousOperations();
 
       MockInteractions.tap(element.shadowRoot
@@ -251,8 +266,8 @@
     });
 
     test('show all messages respects collapse', () => {
-      element.messages = _.times(10, randomAutomated)
-          .concat(_.times(11, randomMessage));
+      element.messages = generateRandomAutomatedMessages(10)
+          .concat(generateRandomMessages(11));
       flushAsynchronousOperations();
 
       MockInteractions.tap(element.shadowRoot
@@ -353,7 +368,7 @@
     test('scroll to message offscreen', () => {
       const scrollToStub = sandbox.stub(window, 'scrollTo');
       const highlightStub = sandbox.stub(element, '_highlightEl');
-      element.messages = _.times(25, randomMessage);
+      element.messages = generateRandomMessages(25);
       flushAsynchronousOperations();
       assert.isFalse(scrollToStub.called);
       assert.isFalse(highlightStub.called);
@@ -468,12 +483,12 @@
       });
 
       sandbox = sinon.sandbox.create();
-      messages = _.times(2, randomAutomated);
+      messages = generateRandomAutomatedMessages(2);
       messages.push(randomMessageReviewer);
 
       // Element must be wrapped in an element with direct access to the
       // comment API.
-      commentApiWrapper = fixture('basic');
+      commentApiWrapper = basicFixture.instantiate();
       element = commentApiWrapper.$.messagesList;
       sandbox.spy(commentApiWrapper.$.commentAPI, 'loadAll');
       element.messages = messages;
@@ -529,27 +544,28 @@
       assert.equal(element._getDelta([], messages, false), 1);
       assert.equal(element._getDelta([], messages, true), 1);
 
-      messages = _.times(7, randomMessage);
+      messages = generateRandomMessages(7);
       assert.equal(element._getDelta([], messages, false), 5);
       assert.equal(element._getDelta([], messages, true), 5);
 
-      messages = _.times(4, randomMessage)
-          .concat(_.times(2, randomAutomated))
-          .concat(_.times(3, randomMessage));
+      messages = generateRandomMessages(4)
+          .concat(generateRandomAutomatedMessages(2))
+          .concat(generateRandomMessages(3));
 
-      const dummyArr = _.times(2, randomMessage);
+      const dummyArr = generateRandomMessages(2);
       assert.equal(element._getDelta(dummyArr, messages, false), 5);
       assert.equal(element._getDelta(dummyArr, messages, true), 7);
     });
 
     test('_getHumanMessages', () => {
       assert.equal(
-          element._getHumanMessages(_.times(5, randomAutomated)).length, 0);
+          element._getHumanMessages(
+              generateRandomAutomatedMessages(5)).length, 0);
       assert.equal(
-          element._getHumanMessages(_.times(5, randomMessage)).length, 5);
+          element._getHumanMessages(generateRandomMessages(5)).length, 5);
 
-      let messages = _.shuffle(_.times(5, randomMessage)
-          .concat(_.times(5, randomAutomated)));
+      let messages = shuffle(generateRandomMessages(5)
+          .concat(generateRandomAutomatedMessages(5)));
       messages = element._getHumanMessages(messages);
       assert.equal(messages.length, 5);
       assert.isFalse(element._hasAutomatedMessages(messages));
@@ -615,4 +631,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.js b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.js
index e639217..9f652d1 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.js
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.js
@@ -1,38 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-related-changes-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-related-changes-list></gr-related-changes-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-related-changes-list.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
@@ -40,12 +23,14 @@
 
 const pluginApi = _testOnly_initGerritPluginApi();
 
+const basicFixture = fixtureFromElement('gr-related-changes-list');
+
 suite('gr-related-changes-list tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -288,7 +273,7 @@
     let element;
 
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
 
       sandbox.stub(element, '_getRelatedChanges')
           .returns(Promise.resolve({changes: []}));
@@ -317,7 +302,7 @@
     let conflictsStub;
 
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
 
       sandbox.stub(element, '_getRelatedChanges')
           .returns(Promise.resolve({changes: []}));
@@ -559,7 +544,8 @@
           .querySelector('.note'));
       assert.strictEqual(
           element.shadowRoot
-              .querySelector('.note').innerText, '(+ 1 non-visible change)');
+              .querySelector('.note').innerText.trim(),
+          '(+ 1 non-visible change)');
     });
 
     test('visible and non-visible submitted together changes', () => {
@@ -570,7 +556,8 @@
           .querySelector('.note'));
       assert.strictEqual(
           element.shadowRoot
-              .querySelector('.note').innerText, '(+ 2 non-visible changes)');
+              .querySelector('.note').innerText.trim(),
+          '(+ 2 non-visible changes)');
     });
   });
 
@@ -596,4 +583,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js
index 8f3e3f7..7262fc3 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.js
@@ -1,44 +1,29 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-reply-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-reply-dialog></gr-reply-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
+import '../../../test/common-test-setup-karma.js';
 import {IronOverlayManager} from '@polymer/iron-overlay-behavior/iron-overlay-manager.js';
-import '../../../test/common-test-setup.js';
 import './gr-reply-dialog.js';
 import {mockPromise} from '../../../test/test-utils.js';
 import {SpecialFilePath} from '../../../constants/constants.js';
 import {appContext} from '../../../services/app-context.js';
 
+const basicFixture = fixtureFromElement('gr-reply-dialog');
+
 function cloneableResponse(status, text) {
   return {
     ok: false,
@@ -87,7 +72,7 @@
 
     sandbox.stub(appContext.flagsService, 'isEnabled').returns(true);
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.change = {
       _number: changeNum,
       owner: {
@@ -1406,4 +1391,4 @@
     assert.equal(element.$.pluginMessage.textContent, 'foo');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.js b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.js
index 6949afc..f9b32cd 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.js
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-reviewer-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-reviewer-list></gr-reviewer-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-reviewer-list.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-reviewer-list');
+
 suite('gr-reviewer-list tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.serverConfig = {};
     sandbox = sinon.sandbox.create();
     stub('gr-rest-api-interface', {
@@ -320,4 +306,4 @@
         element._computeVoteableText({_account_id: 1}, change), '');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.js b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.js
index 3b29ea7..67af168 100644
--- a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.js
+++ b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.js
@@ -1,43 +1,28 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-thread-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-thread-list></gr-thread-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-thread-list.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {NO_THREADS_MSG} from '../../../constants/messages.js';
 import {SpecialFilePath} from '../../../constants/constants.js';
 
+const basicFixture = fixtureFromElement('gr-thread-list');
+
 suite('gr-thread-list tests', () => {
   let element;
   let sandbox;
@@ -51,7 +36,7 @@
 
   setup(done => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.threads = [
       {
         comments: [
@@ -648,4 +633,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog_test.js b/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog_test.js
index 164c483..d1af425 100644
--- a/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog_test.js
+++ b/polygerrit-ui/app/elements/change/gr-upload-help-dialog/gr-upload-help-dialog_test.js
@@ -1,44 +1,30 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-upload-help-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-upload-help-dialog></gr-upload-help-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-upload-help-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-upload-help-dialog');
+
 suite('gr-upload-help-dialog tests', () => {
   let element;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('constructs push command from branch', () => {
@@ -121,4 +107,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.js b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.js
index a366d09..a8f206c 100644
--- a/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.js
+++ b/polygerrit-ui/app/elements/core/gr-account-dropdown/gr-account-dropdown_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-account-dropdown</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-account-dropdown></gr-account-dropdown>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-account-dropdown.js';
+
+const basicFixture = fixtureFromElement('gr-account-dropdown');
+
 suite('gr-account-dropdown tests', () => {
   let element;
 
@@ -41,7 +27,7 @@
     stub('gr-rest-api-interface', {
       getConfig() { return Promise.resolve({}); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('account information', () => {
@@ -121,4 +107,4 @@
         '${}, TEST, , bar');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog_test.js b/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog_test.js
index bd4991f..ea8f7c5 100644
--- a/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog_test.js
+++ b/polygerrit-ui/app/elements/core/gr-error-dialog/gr-error-dialog_test.js
@@ -1,44 +1,30 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-error-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-error-dialog></gr-error-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-error-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-error-dialog');
+
 suite('gr-error-dialog tests', () => {
   let element;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('dismiss tap fires event', done => {
@@ -46,4 +32,4 @@
     MockInteractions.tap(element.$.dialog.$.confirm);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.js b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.js
index b52bb7d..934e822 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.js
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.js
@@ -1,42 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-error-manager</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-error-manager></gr-error-manager>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-error-manager.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
 
+const basicFixture = fixtureFromElement('gr-error-manager');
+
 _testOnly_initGerritPluginApi();
 
 suite('gr-error-manager tests', () => {
@@ -52,11 +37,20 @@
   });
 
   suite('when authed', () => {
+    let toastSpy;
+
     setup(() => {
       sandbox.stub(window, 'fetch')
           .returns(Promise.resolve({ok: true, status: 204}));
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element._authService.clearCache();
+      toastSpy = sandbox.spy(element, '_createToastAlert');
+    });
+
+    teardown(() => {
+      toastSpy.getCalls().forEach(call => {
+        call.returnValue.remove();
+      });
     });
 
     test('does not show auth error on 403 by default', done => {
@@ -237,7 +231,6 @@
       element.$.restAPI.getLoggedIn();
       const refreshStub = sandbox.stub(element.$.restAPI, 'getAccount',
           () => Promise.resolve({}));
-      const toastSpy = sandbox.spy(element, '_createToastAlert');
       const windowOpen = sandbox.stub(window, 'open');
       const responseText = Promise.resolve('Authentication required\n');
       // fake failed auth
@@ -309,7 +302,6 @@
     test('auth toast should dismiss existing toast', done => {
       // starts with authed state
       element.$.restAPI.getLoggedIn();
-      const toastSpy = sandbox.spy(element, '_createToastAlert');
       const responseText = Promise.resolve('Authentication required\n');
 
       // fake an alert
@@ -351,7 +343,6 @@
     test('regular toast should dismiss regular toast', () => {
       // starts with authed state
       element.$.restAPI.getLoggedIn();
-      const toastSpy = sandbox.spy(element, '_createToastAlert');
 
       // fake an alert
       element.dispatchEvent(
@@ -378,7 +369,6 @@
     test('regular toast should not dismiss auth toast', done => {
       // starts with authed state
       element.$.restAPI.getLoggedIn();
-      const toastSpy = sandbox.spy(element, '_createToastAlert');
       const responseText = Promise.resolve('Authentication required\n');
 
       // fake auth
@@ -535,11 +525,19 @@
   });
 
   suite('when not authed', () => {
+    let toastSpy;
     setup(() => {
       stub('gr-rest-api-interface', {
         getLoggedIn() { return Promise.resolve(false); },
       });
-      element = fixture('basic');
+      element = basicFixture.instantiate();
+      toastSpy = sandbox.spy(element, '_createToastAlert');
+    });
+
+    teardown(() => {
+      toastSpy.getCalls().forEach(call => {
+        call.returnValue.remove();
+      });
     });
 
     test('refresh loop continues on credential fail', done => {
@@ -562,4 +560,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.js b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.js
index 8ae0f69..0c25e6e 100644
--- a/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.js
+++ b/polygerrit-ui/app/elements/core/gr-key-binding-display/gr-key-binding-display_test.js
@@ -1,43 +1,30 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-key-binding-display</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-key-binding-display></gr-key-binding-display>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-key-binding-display.js';
+
+const basicFixture = fixtureFromElement('gr-key-binding-display');
+
 suite('gr-key-binding-display tests', () => {
   let element;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   suite('_computeKey', () => {
@@ -64,4 +51,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog_test.js b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog_test.js
index 1b5cd0f..2e6f5d3 100644
--- a/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog_test.js
+++ b/polygerrit-ui/app/elements/core/gr-keyboard-shortcuts-dialog/gr-keyboard-shortcuts-dialog_test.js
@@ -1,45 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-key-binding-display</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-keyboard-shortcuts-dialog></gr-keyboard-shortcuts-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-keyboard-shortcuts-dialog.js';
 import {KeyboardShortcutBinder} from '../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js';
+
+const basicFixture = fixtureFromElement('gr-keyboard-shortcuts-dialog');
+
 suite('gr-keyboard-shortcuts-dialog tests', () => {
   const kb = KeyboardShortcutBinder;
   let element;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   function update(directory) {
@@ -177,5 +164,4 @@
     });
   });
 });
-</script>
 
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.js b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.js
index 336d873..bbff1d8 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.js
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-main-header</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-main-header></gr-main-header>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-main-header.js';
+
+const basicFixture = fixtureFromElement('gr-main-header');
+
 suite('gr-main-header tests', () => {
   let element;
   let sandbox;
@@ -47,7 +33,7 @@
     stub('gr-main-header', {
       _loadAccount() {},
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -407,4 +393,4 @@
     assert.equal(element._registerText, 'Sign up');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation_test.js b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation_test.js
index 8fc4c75..93a1e9e 100644
--- a/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation_test.js
+++ b/polygerrit-ui/app/elements/core/gr-navigation/gr-navigation_test.js
@@ -1,31 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-navigation</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import {GerritNav} from './gr-navigation.js';
 
 suite('gr-navigation tests', () => {
@@ -85,4 +75,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js
index b5bfd4e..6f3692c 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router_test.js
@@ -1,49 +1,34 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-router</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-router></gr-router>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-router.js';
 import page from 'page/page.mjs';
 import {GerritNav} from '../gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-router');
+
 suite('gr-router tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
@@ -1649,4 +1634,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.js b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.js
index 9e5fdfe..61ecc3c 100644
--- a/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.js
+++ b/polygerrit-ui/app/elements/core/gr-search-bar/gr-search-bar_test.js
@@ -1,52 +1,43 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-search-bar</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script src="/node_modules/page/page.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-search-bar></gr-search-bar>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-search-bar.js';
 import '../../../scripts/util.js';
-import {KeyboardShortcutBinder} from '../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js';
-suite('gr-search-bar tests', () => {
-  const kb = KeyboardShortcutBinder;
-  kb.bindShortcut(kb.Shortcut.SEARCH, '/');
+import {TestKeyboardShortcutBinder} from '../../../test/test-utils.js';
 
+const basicFixture = fixtureFromElement('gr-search-bar');
+
+suite('gr-search-bar tests', () => {
   let element;
   let sandbox;
 
+  suiteSetup(() => {
+    const kb = TestKeyboardShortcutBinder.push();
+    kb.bindShortcut(kb.Shortcut.SEARCH, '/');
+  });
+
+  suiteTeardown(() => {
+    TestKeyboardShortcutBinder.pop();
+  });
+
   setup(done => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     flush(done);
   });
 
@@ -213,7 +204,7 @@
           },
         });
 
-        element = fixture('basic');
+        element = basicFixture.instantiate();
         flush(done);
       });
 
@@ -230,4 +221,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.js b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.js
index 87dfaf4..74063f0 100644
--- a/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.js
+++ b/polygerrit-ui/app/elements/core/gr-smart-search/gr-smart-search_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-smart-search</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-smart-search></gr-smart-search>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-smart-search.js';
+
+const basicFixture = fixtureFromElement('gr-smart-search');
+
 suite('gr-smart-search tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -153,4 +139,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/custom-dark-theme_test.js b/polygerrit-ui/app/elements/custom-dark-theme_test.js
index cc955ce..bb91214 100644
--- a/polygerrit-ui/app/elements/custom-dark-theme_test.js
+++ b/polygerrit-ui/app/elements/custom-dark-theme_test.js
@@ -39,6 +39,11 @@
     sandbox.restore();
     window.localStorage.removeItem('dark-theme');
     removeTheme();
+    // The app sends requests to server. This can lead to
+    // unexpected gr-alert elements in document.body
+    document.body.querySelectorAll('gr-alert').forEach(grAlert => {
+      grAlert.remove();
+    });
   });
 
   test('should tried to load dark theme', () => {
@@ -57,4 +62,4 @@
             .toLowerCase(),
         '#3b3d3f');
   });
-});
\ No newline at end of file
+});
diff --git a/polygerrit-ui/app/elements/custom-light-theme_test.js b/polygerrit-ui/app/elements/custom-light-theme_test.js
index a866bb3..3ba602b 100644
--- a/polygerrit-ui/app/elements/custom-light-theme_test.js
+++ b/polygerrit-ui/app/elements/custom-light-theme_test.js
@@ -43,6 +43,11 @@
   });
   teardown(() => {
     sandbox.restore();
+    // The app sends requests to server. This can lead to
+    // unexpected gr-alert elements in document.body
+    document.body.querySelectorAll('gr-alert').forEach(grAlert => {
+      grAlert.remove();
+    });
   });
 
   test('should not load dark theme', () => {
@@ -60,4 +65,4 @@
             .toLowerCase(),
         'transparent');
   });
-});
\ No newline at end of file
+});
diff --git a/polygerrit-ui/app/elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog_test.js b/polygerrit-ui/app/elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog_test.js
index 65958c8..c9f1660 100644
--- a/polygerrit-ui/app/elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-apply-fix-dialog/gr-apply-fix-dialog_test.js
@@ -1,38 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the 'License');
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an 'AS IS' BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<meta name='viewport' content='width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes'>
-<title>gr-apply-fix-dialog</title>
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id='basic'>
-  <template>
-    <gr-apply-fix-dialog></gr-apply-fix-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-apply-fix-dialog.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-apply-fix-dialog');
+
 suite('gr-apply-fix-dialog tests', () => {
   let element;
   let sandbox;
@@ -48,7 +36,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.changeNum = '1';
     element._patchNum = 2;
     element.change = {
@@ -313,4 +301,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api_test.js b/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api_test.js
index 172a342..dc599c7 100644
--- a/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-comment-api/gr-comment-api_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-comment-api</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-comment-api></gr-comment-api>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-comment-api.js';
+
+const basicFixture = fixtureFromElement('gr-comment-api');
+
 suite('gr-comment-api tests', () => {
   const PARENT = 'PARENT';
 
@@ -42,7 +28,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
@@ -760,4 +746,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer_test.js b/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer_test.js
index b80c56f3..e886e61 100644
--- a/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-coverage-layer/gr-coverage-layer_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-coverage-layer</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-coverage-layer></gr-coverage-layer>
-  </template>
-</test-fixture>
-
-<script type="module">
+import '../../../test/common-test-setup-karma.js';
 import '../gr-diff/gr-diff-line.js';
-import '../../../test/common-test-setup.js';
 import './gr-coverage-layer.js';
+
+const basicFixture = fixtureFromElement('gr-coverage-layer');
+
 suite('gr-coverage-layer', () => {
   let element;
 
@@ -74,7 +60,7 @@
       },
     ];
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.coverageRanges = initialCoverageRanges;
     element.side = 'right';
   });
@@ -135,4 +121,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element_test.js b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element_test.js
index 057401b..c988f3a 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-element_test.js
@@ -1,54 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-diff-builder</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template is="dom-template">
-    <gr-diff-builder>
-      <table id="diffTable"></table>
-    </gr-diff-builder>
-  </template>
-</test-fixture>
-
-<test-fixture id="div-with-text">
-  <template>
-    <div>Lorem ipsum dolor sit amet, suspendisse inceptos vehicula</div>
-  </template>
-</test-fixture>
-
-<test-fixture id="mock-diff">
-  <template>
-    <gr-diff-builder view-mode="SIDE_BY_SIDE">
-      <table id="diffTable"></table>
-    </gr-diff-builder>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../gr-diff/gr-diff-group.js';
 import './gr-diff-builder.js';
 import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
@@ -59,6 +26,23 @@
 import {GrDiffLine} from '../gr-diff/gr-diff-line.js';
 import {GrDiffGroup} from '../gr-diff/gr-diff-group.js';
 import {GrDiffBuilder} from './gr-diff-builder.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+    <gr-diff-builder>
+      <table id="diffTable"></table>
+    </gr-diff-builder>
+`);
+
+const divWithTextFixture = fixtureFromTemplate(html`
+<div>Lorem ipsum dolor sit amet, suspendisse inceptos vehicula</div>
+`);
+
+const mockDiffFixture = fixtureFromTemplate(html`
+<gr-diff-builder view-mode="SIDE_BY_SIDE">
+      <table id="diffTable"></table>
+    </gr-diff-builder>
+`);
 
 const DiffViewMode = {
   SIDE_BY_SIDE: 'SIDE_BY_SIDE',
@@ -74,7 +58,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     stub('gr-rest-api-interface', {
       getLoggedIn() { return Promise.resolve(false); },
       getProjectConfig() { return Promise.resolve({}); },
@@ -379,7 +363,7 @@
     }
 
     setup(() => {
-      el = fixture('div-with-text');
+      el = divWithTextFixture.instantiate();
       str = el.textContent;
       annotateElementSpy = sandbox.spy(GrAnnotation, 'annotateElement');
       layer = document.createElement('gr-diff-builder')
@@ -537,7 +521,7 @@
     const lineNumberEl = document.createElement('td');
 
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element._showTabs = true;
       layer = element._createTabIndicatorLayer();
     });
@@ -649,7 +633,7 @@
     let withLayerCount;
     setup(() => {
       const layers = [];
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.layers = layers;
       element._showTrailingWhitespace = true;
       element._setupAnnotationLayers();
@@ -664,7 +648,7 @@
     suite('with layers', () => {
       const layers = [{}, {}];
       setup(() => {
-        element = fixture('basic');
+        element = basicFixture.instantiate();
         element.layers = layers;
         element._showTrailingWhitespace = true;
         element._setupAnnotationLayers();
@@ -685,7 +669,7 @@
     const lineNumberEl = document.createElement('td');
 
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element._showTrailingWhitespace = true;
       layer = element._createTrailingWhitespaceLayer();
     });
@@ -782,7 +766,7 @@
     let content;
 
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.viewMode = 'SIDE_BY_SIDE';
       processStub = sandbox.stub(element.$.processor, 'process')
           .returns(Promise.resolve());
@@ -856,7 +840,7 @@
           ],
         },
       ];
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       outputEl = element.queryEffectiveChildren('#diffTable');
       keyLocations = {left: {}, right: {}};
       sandbox.stub(element, '_getDiffBuilder', () => {
@@ -923,7 +907,7 @@
     let keyLocations;
 
     setup(done => {
-      element = fixture('mock-diff');
+      element = mockDiffFixture.instantiate();
       diff = getMockDiffResponse();
       element.diff = diff;
 
@@ -1252,4 +1236,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified_test.js b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified_test.js
index 2d26667..7346bf7 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-builder/gr-diff-builder-unified_test.js
@@ -1,32 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>GrDiffBuilderUnified</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../gr-diff/gr-diff-group.js';
 import './gr-diff-builder.js';
 import './gr-diff-builder-unified.js';
@@ -202,4 +191,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.js b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.js
index 440b233..9301d64 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.js
@@ -1,51 +1,36 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-diff-cursor</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-diff></gr-diff>
-    <gr-diff-cursor></gr-diff-cursor>
-    <gr-rest-api-interface></gr-rest-api-interface>
-  </template>
-</test-fixture>
-
-<test-fixture id="empty">
-  <template>
-    <div></div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../gr-diff/gr-diff.js';
 import './gr-diff-cursor.js';
 import '../../shared/gr-rest-api-interface/gr-rest-api-interface.js';
 import {getMockDiffResponse} from '../../../test/mocks/diff-response.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+  <gr-diff></gr-diff>
+  <gr-diff-cursor></gr-diff-cursor>
+  <gr-rest-api-interface></gr-rest-api-interface>
+`);
+
+const emptyFixture = fixtureFromElement('div');
+
 suite('gr-diff-cursor tests', () => {
   let sandbox;
   let cursorElement;
@@ -54,7 +39,7 @@
   setup(done => {
     sandbox = sinon.sandbox.create();
 
-    const fixtureElems = fixture('basic');
+    const fixtureElems = basicFixture.instantiate();
     diffElement = fixtureElems[0];
     cursorElement = fixtureElems[1];
     const restAPI = fixtureElems[2];
@@ -428,7 +413,7 @@
 
     setup(() => {
       sandbox = sinon.sandbox.create();
-      someEmptyDiv = fixture('empty');
+      someEmptyDiv = emptyFixture.instantiate();
     });
 
     teardown(() => sandbox.restore());
@@ -442,4 +427,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.js b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.js
index 2bda950..3c107dd 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-annotation_test.js
@@ -1,40 +1,29 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+const basicFixture = fixtureFromTemplate(html`
+<div>Lorem ipsum dolor sit amet, suspendisse inceptos vehicula</div>
+`);
 
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-annotation</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <div>Lorem ipsum dolor sit amet, suspendisse inceptos vehicula</div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import {GrAnnotation} from './gr-annotation.js';
 import {sanitizeDOMValue, setSanitizeDOMValue} from '@polymer/polymer/lib/utils/settings.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
 suite('annotation', () => {
   let str;
   let parent;
@@ -43,7 +32,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    parent = fixture('basic');
+    parent = basicFixture.instantiate();
     textNode = parent.childNodes[0];
     str = textNode.textContent;
   });
@@ -295,4 +284,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.js b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.js
index ec7e6d2..1695988 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.js
@@ -1,37 +1,34 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../../../test/common-test-setup-karma.js';
+import './gr-diff-highlight.js';
+import {GrRangeNormalizer} from './gr-range-normalizer.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-diff-highlight</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <style>
+// Splitting long lines in html into shorter rows breaks tests:
+// zero-length text nodes and new lines are not expected in some places
+/* eslint-disable max-len */
+const basicFixture = fixtureFromTemplate(html`
+<style>
       .tab-indicator:before {
         color: #C62828;
         /* >> character */
-        content: '\00BB';
+        content: '\\00BB';
       }
     </style>
     <gr-diff-highlight>
@@ -50,10 +47,10 @@
           <tr class="diff-row side-by-side" left-type="remove" right-type="add">
             <td class="left lineNum" data-value="2"></td>
             <!-- Next tag is formatted to eliminate zero-length text nodes. -->
-            <td class="content remove"><div class="contentText">na💢ti <hl class="foo">te, inquit</hl>, sumus <hl class="bar">aliquando</hl> otiosum, <hl>certe</hl> a <hl><span class="tab-indicator" style="tab-size:8;">	</span></hl>udiam, <hl>quid</hl> sit, <span class="tab-indicator" style="tab-size:8;">	</span>quod <hl>Epicurum</hl></div></td>
+            <td class="content remove"><div class="contentText">na💢ti <hl class="foo">te, inquit</hl>, sumus <hl class="bar">aliquando</hl> otiosum, <hl>certe</hl> a <hl><span class="tab-indicator" style="tab-size:8;">\\u0009</span></hl>udiam, <hl>quid</hl> sit, <span class="tab-indicator" style="tab-size:8;">\\u0009</span>quod <hl>Epicurum</hl></div></td>
             <td class="right lineNum" data-value="2"></td>
             <!-- Next tag is formatted to eliminate zero-length text nodes. -->
-            <td class="content add"><div class="contentText">nacti , <hl>,</hl> sumus <hl><span class="tab-indicator" style="tab-size:8;">	</span></hl> otiosum,  <span class="tab-indicator" style="tab-size:8;">	</span> audiam,  sit, quod</div></td>
+            <td class="content add"><div class="contentText">nacti , <hl>,</hl> sumus <hl><span class="tab-indicator" style="tab-size:8;">\\u0009</span></hl> otiosum,  <span class="tab-indicator" style="tab-size:8;">\\u0009</span> audiam,  sit, quod</div></td>
           </tr>
         </tbody>
 
@@ -70,19 +67,19 @@
           <tr class="diff-row side-by-side" left-type="remove" right-type="add">
             <td class="left lineNum" data-value="140"></td>
             <!-- Next tag is formatted to eliminate zero-length text nodes. -->
-            <td class="content remove"><div class="contentText">na💢ti <hl class="foo">te, inquit</hl>, sumus <hl class="bar">aliquando</hl> otiosum, <hl>certe</hl> a <hl><span class="tab-indicator" style="tab-size:8;">	</span></hl>udiam, <hl>quid</hl> sit, <span class="tab-indicator" style="tab-size:8;">	</span>quod <hl>Epicurum</hl></div><div class="comment-thread">
+            <td class="content remove"><div class="contentText">na💢ti <hl class="foo">te, inquit</hl>, sumus <hl class="bar">aliquando</hl> otiosum, <hl>certe</hl> a <hl><span class="tab-indicator" style="tab-size:8;">\\u0009</span></hl>udiam, <hl>quid</hl> sit, <span class="tab-indicator" style="tab-size:8;">\\u0009</span>quod <hl>Epicurum</hl></div><div class="comment-thread">
                 [Yet another random diff thread content here]
             </div></td>
             <td class="right lineNum" data-value="120"></td>
             <!-- Next tag is formatted to eliminate zero-length text nodes. -->
-            <td class="content add"><div class="contentText">nacti , <hl>,</hl> sumus <hl><span class="tab-indicator" style="tab-size:8;">	</span></hl> otiosum,  <span class="tab-indicator" style="tab-size:8;">	</span> audiam,  sit, quod</div></td>
+            <td class="content add"><div class="contentText">nacti , <hl>,</hl> sumus <hl><span class="tab-indicator" style="tab-size:8;">\\u0009</span></hl> otiosum,  <span class="tab-indicator" style="tab-size:8;">\\u0009</span> audiam,  sit, quod</div></td>
           </tr>
         </tbody>
 
         <tbody class="section both">
           <tr class="diff-row side-by-side" left-type="both" right-type="both">
             <td class="left lineNum" data-value="141"></td>
-            <td class="content both"><div class="contentText">nam et<hl><span class="tab-indicator" style="tab-size:8;">	</span></hl>complectitur<span class="tab-indicator" style="tab-size:8;">	</span>verbis, quod vult, et dicit plane, quod intellegam;</div></td>
+            <td class="content both"><div class="contentText">nam et<hl><span class="tab-indicator" style="tab-size:8;">\\u0009</span></hl>complectitur<span class="tab-indicator" style="tab-size:8;">\\u0009</span>verbis, quod vult, et dicit plane, quod intellegam;</div></td>
             <td class="right lineNum" data-value="130"></td>
             <td class="content both"><div class="contentText">nam et complectitur verbis, quod vult, et dicit plane, quod intellegam;</div></td>
           </tr>
@@ -123,29 +120,14 @@
             <td class="left lineNum" data-value="165"></td>
             <td class="content both"><div class="contentText"></div></td>
             <td class="right lineNum" data-value="147"></td>
-            <td class="content both"><div class="contentText">in physicis, <hl><span class="tab-indicator" style="tab-size:8;">	</span></hl> quibus maxime gloriatur, primum totus est alienus. Democritea dicit</div></td>
+            <td class="content both"><div class="contentText">in physicis, <hl><span class="tab-indicator" style="tab-size:8;">\\u0009</span></hl> quibus maxime gloriatur, primum totus est alienus. Democritea dicit</div></td>
           </tr>
         </tbody>
 
       </table>
     </gr-diff-highlight>
-  </template>
-</test-fixture>
-
-<test-fixture id="highlighted">
-  <template>
-    <div>
-      <hl class="rangeHighlight">foo</hl>
-      bar
-      <hl class="rangeHighlight">baz</hl>
-    </div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
-import './gr-diff-highlight.js';
-import {GrRangeNormalizer} from './gr-range-normalizer.js';
+`);
+/* eslint-enable max-len */
 
 suite('gr-diff-highlight', () => {
   let element;
@@ -153,7 +135,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic')[1];
+    element = basicFixture.instantiate()[1];
   });
 
   teardown(() => {
@@ -627,4 +609,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.js b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.js
index 342c7ec..a0e2bbc 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.js
@@ -1,44 +1,29 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-diff</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-diff-host></gr-diff-host>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-diff-host.js';
 import {GrDiffBuilderImage} from '../gr-diff-builder/gr-diff-builder-image.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {DiffSide} from '../gr-diff/gr-diff-utils.js';
 
+const basicFixture = fixtureFromElement('gr-diff-host');
+
 suite('gr-diff-host tests', () => {
   let element;
   let sandbox;
@@ -50,7 +35,7 @@
     stub('gr-rest-api-interface', {
       async getLoggedIn() { return getLoggedIn; },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox.stub(element.reporting, 'time');
     sandbox.stub(element.reporting, 'timeEnd');
   });
@@ -65,7 +50,7 @@
       stub('gr-js-api-interface', {
         getDiffLayers() { return pluginLayers; },
       });
-      element = fixture('basic');
+      element = basicFixture.instantiate();
     });
     test('plugin layers requested', () => {
       element.patchRange = {};
@@ -407,7 +392,7 @@
   suite('not logged in', () => {
     setup(() => {
       getLoggedIn = false;
-      element = fixture('basic');
+      element = basicFixture.instantiate();
     });
 
     test('reload() loads files weblinks', () => {
@@ -866,7 +851,7 @@
 
   suite('blame', () => {
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
     });
 
     test('clearBlame', () => {
@@ -1036,7 +1021,7 @@
     let reportStub;
 
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.path = 'file.txt';
       element.patchRange = {basePatchNum: 1};
       reportStub = sandbox.stub(element.reporting, 'reportInteraction');
@@ -1571,7 +1556,7 @@
           });
         },
       });
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       const prefs = {
         line_length: 10,
         show_tabs: true,
@@ -1701,4 +1686,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.js b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.js
index 309f4ac..e5ecde0 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.js
@@ -1,47 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-diff-mode-selector</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script src="/node_modules/page/page.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-diff-mode-selector></gr-diff-mode-selector>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-diff-mode-selector.js';
+
+const basicFixture = fixtureFromElement('gr-diff-mode-selector');
+
 suite('gr-diff-mode-selector tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -81,4 +66,4 @@
     assert.isTrue(saveStub.calledOnce);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.js b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.js
index aafd374..ea7f049 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-processor/gr-diff-processor_test.js
@@ -1,42 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-diff-processor test</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-diff-processor></gr-diff-processor>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-diff-processor.js';
 import {GrDiffLine} from '../gr-diff/gr-diff-line.js';
 import {GrDiffGroup} from '../gr-diff/gr-diff-group.js';
 
+const basicFixture = fixtureFromElement('gr-diff-processor');
+
 suite('gr-diff-processor tests', () => {
   const WHOLE_FILE = -1;
   const loremIpsum =
@@ -59,7 +44,7 @@
 
   suite('not logged in', () => {
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
 
       element.context = 4;
     });
@@ -609,8 +594,8 @@
     test('scrolling pauses rendering', () => {
       const contentRow = {
         ab: [
-          '<!DOCTYPE html>',
-          '<meta charset="utf-8">',
+          '',
+          '',
         ],
       };
       const content = _.times(200, _.constant(contentRow));
@@ -629,8 +614,8 @@
     test('image diffs', () => {
       const contentRow = {
         ab: [
-          '<!DOCTYPE html>',
-          '<meta charset="utf-8">',
+          '',
+          '',
         ],
       };
       const content = _.times(200, _.constant(contentRow));
@@ -926,10 +911,10 @@
   });
 
   test('detaching cancels', () => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox.stub(element, 'cancel');
     element.detached();
     assert(element.cancel.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.js b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.js
index 1221b58..938833f 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-selection/gr-diff-selection_test.js
@@ -1,33 +1,28 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import '../../../test/common-test-setup-karma.js';
+import './gr-diff-selection.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-diff-selection</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-diff-selection>
+// Splitting long lines in html into shorter rows breaks tests:
+// zero-length text nodes and new lines are not expected in some places
+/* eslint-disable max-len */
+const basicFixture = fixtureFromTemplate(html`
+<gr-diff-selection>
       <table id="diffTable" class="side-by-side">
         <tr class="diff-row">
           <td class="blame" data-line-number="1"></td>
@@ -100,12 +95,9 @@
         </tr>
       </table>
     </gr-diff-selection>
-  </template>
-</test-fixture>
+`);
+/* eslint-enable max-len */
 
-<script type="module">
-import '../../../test/common-test-setup.js';
-import './gr-diff-selection.js';
 suite('gr-diff-selection', () => {
   let element;
   let sandbox;
@@ -124,7 +116,7 @@
   };
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     sandbox.stub(element, '_getCopyEventTarget');
     element._cachedDiffBuilder = {
@@ -398,4 +390,4 @@
     assert.deepEqual(element._linesCache, {left: null, right: null});
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
index 8a64cdb..d619536 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
@@ -1,84 +1,70 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-diff-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script src="/node_modules/page/page.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-diff-view></gr-diff-view>
-  </template>
-</test-fixture>
-
-<test-fixture id="blank">
-  <template>
-    <div></div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-diff-view.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
-import {KeyboardShortcutBinder} from '../../../behaviors/keyboard-shortcut-behavior/keyboard-shortcut-behavior.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 import {ChangeStatus} from '../../../constants/constants.js';
+import {TestKeyboardShortcutBinder} from '../../../test/test-utils';
+
+const basicFixture = fixtureFromElement('gr-diff-view');
+
+const blankFixture = fixtureFromElement('div');
 
 suite('gr-diff-view tests', () => {
   suite('basic tests', () => {
-    const kb = KeyboardShortcutBinder;
-    kb.bindShortcut(kb.Shortcut.LEFT_PANE, 'shift+left');
-    kb.bindShortcut(kb.Shortcut.RIGHT_PANE, 'shift+right');
-    kb.bindShortcut(kb.Shortcut.NEXT_LINE, 'j', 'down');
-    kb.bindShortcut(kb.Shortcut.PREV_LINE, 'k', 'up');
-    kb.bindShortcut(kb.Shortcut.NEXT_FILE_WITH_COMMENTS, 'shift+j');
-    kb.bindShortcut(kb.Shortcut.PREV_FILE_WITH_COMMENTS, 'shift+k');
-    kb.bindShortcut(kb.Shortcut.NEW_COMMENT, 'c');
-    kb.bindShortcut(kb.Shortcut.SAVE_COMMENT, 'ctrl+s');
-    kb.bindShortcut(kb.Shortcut.NEXT_FILE, ']');
-    kb.bindShortcut(kb.Shortcut.PREV_FILE, '[');
-    kb.bindShortcut(kb.Shortcut.NEXT_CHUNK, 'n');
-    kb.bindShortcut(kb.Shortcut.NEXT_COMMENT_THREAD, 'shift+n');
-    kb.bindShortcut(kb.Shortcut.PREV_CHUNK, 'p');
-    kb.bindShortcut(kb.Shortcut.PREV_COMMENT_THREAD, 'shift+p');
-    kb.bindShortcut(kb.Shortcut.OPEN_REPLY_DIALOG, 'a');
-    kb.bindShortcut(kb.Shortcut.TOGGLE_LEFT_PANE, 'shift+a');
-    kb.bindShortcut(kb.Shortcut.UP_TO_CHANGE, 'u');
-    kb.bindShortcut(kb.Shortcut.OPEN_DIFF_PREFS, ',');
-    kb.bindShortcut(kb.Shortcut.TOGGLE_DIFF_MODE, 'm');
-    kb.bindShortcut(kb.Shortcut.TOGGLE_FILE_REVIEWED, 'r');
-    kb.bindShortcut(kb.Shortcut.EXPAND_ALL_DIFF_CONTEXT, 'shift+x');
-    kb.bindShortcut(kb.Shortcut.EXPAND_ALL_COMMENT_THREADS, 'e');
-    kb.bindShortcut(kb.Shortcut.TOGGLE_HIDE_ALL_COMMENT_THREADS, 'h');
-    kb.bindShortcut(kb.Shortcut.COLLAPSE_ALL_COMMENT_THREADS, 'shift+e');
-    kb.bindShortcut(kb.Shortcut.NEXT_UNREVIEWED_FILE, 'shift+m');
-    kb.bindShortcut(kb.Shortcut.TOGGLE_BLAME, 'b');
-
     let element;
     let sandbox;
 
+    suiteSetup(() => {
+      const kb = TestKeyboardShortcutBinder.push();
+      kb.bindShortcut(kb.Shortcut.LEFT_PANE, 'shift+left');
+      kb.bindShortcut(kb.Shortcut.RIGHT_PANE, 'shift+right');
+      kb.bindShortcut(kb.Shortcut.NEXT_LINE, 'j', 'down');
+      kb.bindShortcut(kb.Shortcut.PREV_LINE, 'k', 'up');
+      kb.bindShortcut(kb.Shortcut.NEXT_FILE_WITH_COMMENTS, 'shift+j');
+      kb.bindShortcut(kb.Shortcut.PREV_FILE_WITH_COMMENTS, 'shift+k');
+      kb.bindShortcut(kb.Shortcut.NEW_COMMENT, 'c');
+      kb.bindShortcut(kb.Shortcut.SAVE_COMMENT, 'ctrl+s');
+      kb.bindShortcut(kb.Shortcut.NEXT_FILE, ']');
+      kb.bindShortcut(kb.Shortcut.PREV_FILE, '[');
+      kb.bindShortcut(kb.Shortcut.NEXT_CHUNK, 'n');
+      kb.bindShortcut(kb.Shortcut.NEXT_COMMENT_THREAD, 'shift+n');
+      kb.bindShortcut(kb.Shortcut.PREV_CHUNK, 'p');
+      kb.bindShortcut(kb.Shortcut.PREV_COMMENT_THREAD, 'shift+p');
+      kb.bindShortcut(kb.Shortcut.OPEN_REPLY_DIALOG, 'a');
+      kb.bindShortcut(kb.Shortcut.TOGGLE_LEFT_PANE, 'shift+a');
+      kb.bindShortcut(kb.Shortcut.UP_TO_CHANGE, 'u');
+      kb.bindShortcut(kb.Shortcut.OPEN_DIFF_PREFS, ',');
+      kb.bindShortcut(kb.Shortcut.TOGGLE_DIFF_MODE, 'm');
+      kb.bindShortcut(kb.Shortcut.TOGGLE_FILE_REVIEWED, 'r');
+      kb.bindShortcut(kb.Shortcut.EXPAND_ALL_DIFF_CONTEXT, 'shift+x');
+      kb.bindShortcut(kb.Shortcut.EXPAND_ALL_COMMENT_THREADS, 'e');
+      kb.bindShortcut(kb.Shortcut.TOGGLE_HIDE_ALL_COMMENT_THREADS, 'h');
+      kb.bindShortcut(kb.Shortcut.COLLAPSE_ALL_COMMENT_THREADS, 'shift+e');
+      kb.bindShortcut(kb.Shortcut.NEXT_UNREVIEWED_FILE, 'shift+m');
+      kb.bindShortcut(kb.Shortcut.TOGGLE_BLAME, 'b');
+    });
+
+    suiteTeardown(() => {
+      TestKeyboardShortcutBinder.pop();
+    });
+
     const PARENT = 'PARENT';
 
     function getFilesFromFileList(fileList) {
@@ -127,7 +113,7 @@
           return Promise.resolve([]);
         },
       });
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       return element._loadComments();
     });
 
@@ -271,11 +257,14 @@
           false, 'SIDE_BY_SIDE', false));
 
       sandbox.stub(element, '_setReviewed');
+      sandbox.spy(element, '_handleToggleFileReviewed');
       element.$.reviewed.checked = false;
       MockInteractions.pressAndReleaseKeyOn(element, 82, 'shift', 'r');
       assert.isFalse(element._setReviewed.called);
+      assert.isTrue(element._handleToggleFileReviewed.calledOnce);
 
       MockInteractions.pressAndReleaseKeyOn(element, 82, null, 'r');
+      assert.isTrue(element._handleToggleFileReviewed.calledTwice);
       assert.isTrue(element._setReviewed.called);
       assert.equal(element._setReviewed.lastCall.args[0], true);
     });
@@ -954,7 +943,7 @@
 
       // Attach a new gr-diff-view so we can intercept the preferences fetch.
       const view = document.createElement('gr-diff-view');
-      fixture('blank').appendChild(view);
+      blankFixture.instantiate().appendChild(view);
       flushAsynchronousOperations();
 
       // At this point the diff mode doesn't yet have the user's preference.
@@ -1549,7 +1538,7 @@
         getDiffDrafts() { return Promise.resolve({}); },
         getReviewedFiles() { return Promise.resolve([]); },
       });
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       return element._loadComments();
     });
 
@@ -1584,4 +1573,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group_test.js b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group_test.js
index d50a7f4..d72f981 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff-group_test.js
@@ -1,30 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-diff-group</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import {GrDiffLine} from './gr-diff-line.js';
 import {GrDiffGroup} from './gr-diff-group.js';
 
@@ -206,4 +197,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.js b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.js
index 218ca7e..cc0f92b 100644
--- a/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-patch-range-select/gr-patch-range-select_test.js
@@ -1,53 +1,39 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-patch-range-select</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script src="/node_modules/page/page.js"></script>
-
-<dom-module id="comment-api-mock">
-  <template>
-    <gr-patch-range-select id="patchRange" auto
-        change-comments="[[_changeComments]]"></gr-patch-range-select>
-    <gr-comment-api id="commentAPI"></gr-comment-api>
-  </template>
-  </dom-module>
-
-<test-fixture id="basic">
-  <template>
-    <comment-api-mock></comment-api-mock>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../gr-comment-api/gr-comment-api.js';
 import '../../shared/revision-info/revision-info.js';
 import './gr-patch-range-select.js';
 import '../../../test/mocks/comment-api.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {RevisionInfo} from '../../shared/revision-info/revision-info.js';
+import {createCommentApiMockWithTemplateElement} from '../../../test/mocks/comment-api';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const commentApiMockElement = createCommentApiMockWithTemplateElement(
+    'gr-patch-range-select-comment-api-mock', html`
+    <gr-patch-range-select id="patchRange" auto
+        change-comments="[[_changeComments]]"></gr-patch-range-select>
+    <gr-comment-api id="commentAPI"></gr-comment-api>
+`);
+
+const basicFixture = fixtureFromElement(commentApiMockElement.is);
+
 suite('gr-patch-range-select tests', () => {
   let element;
   let sandbox;
@@ -72,7 +58,7 @@
 
     // Element must be wrapped in an element with direct access to the
     // comment API.
-    commentApiWrapper = fixture('basic');
+    commentApiWrapper = basicFixture.instantiate();
     element = commentApiWrapper.$.patchRange;
 
     // Stub methods on the changeComments object after changeComments has
@@ -426,4 +412,4 @@
         {basePatchNum: 1, patchNum: 'edit'});
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer_test.js b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer_test.js
index 37d1707..59cb817 100644
--- a/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-ranged-comment-layer/gr-ranged-comment-layer_test.js
@@ -1,43 +1,28 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-ranged-comment-layer</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-ranged-comment-layer></gr-ranged-comment-layer>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../gr-diff/gr-diff-line.js';
 import './gr-ranged-comment-layer.js';
 import {GrAnnotation} from '../gr-diff-highlight/gr-annotation.js';
 import {GrDiffLine} from '../gr-diff/gr-diff-line.js';
 
+const basicFixture = fixtureFromElement('gr-ranged-comment-layer');
+
 suite('gr-ranged-comment-layer', () => {
   let element;
   let sandbox;
@@ -83,7 +68,7 @@
     ];
 
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.commentRanges = initialCommentRanges;
   });
 
@@ -339,4 +324,4 @@
     assert.equal(range.end, line.text.length);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box_test.js b/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box_test.js
index ff6fba7..e2e901d 100644
--- a/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-selection-action-box/gr-selection-action-box_test.js
@@ -1,49 +1,38 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-selection-action-box</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <div>
-      <gr-selection-action-box></gr-selection-action-box>
-      <div class="target">some text</div>
-    </div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-selection-action-box.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+  <div>
+    <gr-selection-action-box></gr-selection-action-box>
+    <div class="target">some text</div>
+  </div>
+`);
+
 suite('gr-selection-action-box', () => {
   let container;
   let element;
   let sandbox;
 
   setup(() => {
-    container = fixture('basic');
+    container = basicFixture.instantiate();
     element = container.querySelector('gr-selection-action-box');
     sandbox = sinon.sandbox.create();
     sandbox.stub(element, 'dispatchEvent');
@@ -132,4 +121,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer_test.js b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer_test.js
index 638b188..f3d1a40 100644
--- a/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-syntax-layer/gr-syntax-layer_test.js
@@ -1,43 +1,28 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-syntax-layer</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-syntax-layer></gr-syntax-layer>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import {getMockDiffResponse} from '../../../test/mocks/diff-response.js';
 import './gr-syntax-layer.js';
 import {GrAnnotation} from '../gr-diff-highlight/gr-annotation.js';
 import {GrDiffLine} from '../gr-diff/gr-diff-line.js';
 
+const basicFixture = fixtureFromElement('gr-syntax-layer');
+
 suite('gr-syntax-layer tests', () => {
   let sandbox;
   let diff;
@@ -65,7 +50,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     diff = getMockDiffResponse();
     element.diff = diff;
   });
@@ -500,4 +485,4 @@
     assert.equal(element._workaround('go', line), expected);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.js b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.js
index d0581ef..c7d419a 100644
--- a/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.js
+++ b/polygerrit-ui/app/elements/documentation/gr-documentation-search/gr-documentation-search_test.js
@@ -1,42 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-documentation-search</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-documentation-search></gr-documentation-search>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-documentation-search.js';
 import page from 'page/page.mjs';
 
+const basicFixture = fixtureFromElement('gr-documentation-search');
+
 let counter;
 const documentationGenerator = () => {
   return {
@@ -54,7 +38,7 @@
   setup(() => {
     sandbox = sinon.sandbox.create();
     sandbox.stub(page, 'show');
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     counter = 0;
   });
 
@@ -121,4 +105,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.js b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.js
index 229c6c3..d40e83d 100644
--- a/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.js
+++ b/polygerrit-ui/app/elements/edit/gr-default-editor/gr-default-editor_test.js
@@ -1,43 +1,30 @@
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-default-editor</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-default-editor></gr-default-editor>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-default-editor.js';
+
+const basicFixture = fixtureFromElement('gr-default-editor');
+
 suite('gr-default-editor tests', () => {
   let element;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.fileContent = '';
   });
 
@@ -53,4 +40,4 @@
         {target: textarea, bubbles: true, composed: true}));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.js b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.js
index 1267525..f1ee264 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.js
+++ b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.js
@@ -1,42 +1,28 @@
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-edit-controls</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-edit-controls></gr-edit-controls>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-edit-controls.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {PolymerElement} from '@polymer/polymer/polymer-element.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-edit-controls');
+
 suite('gr-edit-controls tests', () => {
   let element;
   let sandbox;
@@ -46,7 +32,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.change = {_number: '42'};
     showDialogSpy = sandbox.spy(element, '_showDialog');
     closeDialogSpy = sandbox.spy(element, '_closeDialog');
@@ -430,4 +416,4 @@
     assert.notOk(spy.lastCall.returnValue);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.js b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.js
index e11a2bd..735a8f5 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.js
+++ b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.js
@@ -1,41 +1,27 @@
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-edit-file-controls</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-edit-file-controls></gr-edit-file-controls>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../gr-edit-constants.js';
 import './gr-edit-file-controls.js';
 import {GrEditConstants} from '../gr-edit-constants.js';
 
+const basicFixture = fixtureFromElement('gr-edit-file-controls');
+
 suite('gr-edit-file-controls tests', () => {
   let element;
   let sandbox;
@@ -43,7 +29,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     fileActionHandler = sandbox.stub();
     element.addEventListener('file-action-tap', fileActionHandler);
   });
@@ -106,4 +92,4 @@
     assert.equal(element._allFileActions.length, 4);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.js b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.js
index e385854..d9f9606 100644
--- a/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.js
+++ b/polygerrit-ui/app/elements/edit/gr-editor-view/gr-editor-view_test.js
@@ -1,40 +1,26 @@
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-editor-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-editor-view></gr-editor-view>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-editor-view.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-editor-view');
+
 suite('gr-editor-view tests', () => {
   let element;
   let sandbox;
@@ -54,7 +40,7 @@
       getEditPreferences() { return Promise.resolve({}); },
     });
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     savePathStub = sandbox.stub(element.$.restAPI, 'renameFileInChangeEdit');
     saveFileStub = sandbox.stub(element.$.restAPI, 'saveChangeEdit');
     changeDetailStub = sandbox.stub(element.$.restAPI, 'getDiffChangeDetail');
@@ -409,4 +395,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/gr-app_test.js b/polygerrit-ui/app/elements/gr-app_test.js
index 6322518..86c24f7 100644
--- a/polygerrit-ui/app/elements/gr-app_test.js
+++ b/polygerrit-ui/app/elements/gr-app_test.js
@@ -1,41 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-app</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-app id="app"></gr-app>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../test/common-test-setup.js';
+import '../test/common-test-setup-karma.js';
 import './gr-app.js';
 import {appContext} from '../services/app-context.js';
 import {GerritNav} from './core/gr-navigation/gr-navigation.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`<gr-app id="app"></gr-app>`);
 
 suite('gr-app tests', () => {
   let sandbox;
@@ -68,7 +54,7 @@
       probePath() { return Promise.resolve(42); },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     flush(done);
   });
 
@@ -103,4 +89,4 @@
     assert.ok(appElement()._lastSearchPage);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-admin-api/gr-admin-api_test.js b/polygerrit-ui/app/elements/plugins/gr-admin-api/gr-admin-api_test.js
index a865233..87ec2f5 100644
--- a/polygerrit-ui/app/elements/plugins/gr-admin-api/gr-admin-api_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-admin-api/gr-admin-api_test.js
@@ -1,31 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-admin-api</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
 import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
 import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
@@ -69,4 +59,4 @@
         {text: 'text', url: 'url', capability: 'capability'});
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper_test.js b/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper_test.js
index 50f9002..9881954 100644
--- a/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-attribute-helper/gr-attribute-helper_test.js
@@ -1,35 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-attribute-helper</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<dom-element id="some-element">
-  <script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
+import {GrAttributeHelper} from './gr-attribute-helper.js';
+
 Polymer({
-  is: 'some-element',
+  is: 'gr-attrubute-helper-some-element',
   properties: {
     fooBar: {
       type: Object,
@@ -37,18 +28,8 @@
     },
   },
 });
-</script>
 
-</dom-element>
-
-<test-fixture id="basic">
-  <template>
-    <some-element></some-element>
-  </template>
-</test-fixture>
-
-<script type="module">
-import {GrAttributeHelper} from './gr-attribute-helper.js';
+const basicFixture = fixtureFromElement('gr-attrubute-helper-some-element');
 
 suite('gr-attribute-helper tests', () => {
   let element;
@@ -57,7 +38,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     instance = new GrAttributeHelper(element);
   });
 
@@ -98,4 +79,4 @@
     assert.isFalse(stub.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks_test.js b/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks_test.js
index 17a22e9..e98ada3 100644
--- a/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-dom-hooks/gr-dom-hooks_test.js
@@ -1,37 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-dom-hooks</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <div></div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
 import {GrDomHook, GrDomHooksManager} from './gr-dom-hooks.js';
 import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
@@ -163,4 +147,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.js b/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.js
index a27c817..e268c5f 100644
--- a/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-event-helper/gr-event-helper_test.js
@@ -1,35 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-event-helper</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<dom-element id="some-element">
-  <script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
+import {addListener} from '@polymer/polymer/lib/utils/gestures.js';
+import {GrEventHelper} from './gr-event-helper.js';
 import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
+
 Polymer({
-  is: 'some-element',
+  is: 'gr-event-helper-some-element',
 
   properties: {
     fooBar: {
@@ -38,20 +30,8 @@
     },
   },
 });
-</script>
 
-</dom-element>
-
-<test-fixture id="basic">
-  <template>
-    <some-element></some-element>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
-import {addListener} from '@polymer/polymer/lib/utils/gestures.js';
-import {GrEventHelper} from './gr-event-helper.js';
+const basicFixture = fixtureFromElement('gr-event-helper-some-element');
 
 suite('gr-event-helper tests', () => {
   let element;
@@ -60,7 +40,7 @@
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     instance = new GrEventHelper(element);
   });
 
@@ -135,4 +115,4 @@
         }));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style_test.js b/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style_test.js
index 12444f5..790c088 100644
--- a/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-external-style/gr-external-style_test.js
@@ -18,10 +18,11 @@
 import '../../../test/common-test-setup-karma.js';
 import {resetPlugins} from '../../../test/test-utils.js';
 import './gr-external-style.js';
-import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
 import {pluginEndpoints} from '../../shared/gr-js-api-interface/gr-plugin-endpoints.js';
 import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
 const pluginApi = _testOnly_initGerritPluginApi();
 
 const basicFixture = fixtureFromTemplate(
@@ -75,6 +76,8 @@
   teardown(() => {
     sandbox.restore();
     resetPlugins();
+    document.body.querySelectorAll('custom-style')
+        .forEach(style => style.remove());
   });
 
   test('imports plugin-provided module', async () => {
@@ -113,4 +116,4 @@
     await new Promise(flush);
     assert.isTrue(element._applyStyle.calledWith('some-module'));
   });
-});
\ No newline at end of file
+});
diff --git a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.js b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.js
index 2c8a8c0..b77d33e 100644
--- a/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-plugin-host/gr-plugin-host_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-plugin-host</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-plugin-host></gr-plugin-host>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-plugin-host.js';
 import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
 
+const basicFixture = fixtureFromElement('gr-plugin-host');
+
 suite('gr-plugin-host tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     sandbox.stub(document.body, 'appendChild');
   });
@@ -91,4 +77,4 @@
     assert.isTrue(pluginLoader.loadPlugins.calledWith([], {}));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup_test.js b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup_test.js
index 2e65365..bbb08d1 100644
--- a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-plugin-popup_test.js
@@ -1,45 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-plugin-popup</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-plugin-popup></gr-plugin-popup>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-plugin-popup.js';
+
+const basicFixture = fixtureFromElement('gr-plugin-popup');
+
 suite('gr-plugin-popup tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     stub('gr-overlay', {
       open: sandbox.stub().returns(Promise.resolve()),
       close: sandbox.stub(),
@@ -66,4 +53,4 @@
     assert.isTrue(element.$.overlay.close.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface_test.js b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface_test.js
index 62ab0e7..42ebf98 100644
--- a/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-popup-interface/gr-popup-interface_test.js
@@ -1,53 +1,39 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-popup-interface</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="container">
-  <template>
-    <div></div>
-  </template>
-</test-fixture>
-
-<dom-module id="gr-user-test-popup">
-  <template>
-    <div id="barfoo">some test module</div>
-  </template>
-  <script type="module">
-import '../../../test/common-test-setup.js';
-import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
-import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
-Polymer({is: 'gr-user-test-popup'});
-</script>
-</dom-module>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {GrPopupInterface} from './gr-popup-interface.js';
 import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+import {PolymerElement} from '@polymer/polymer/polymer-element.js';
+
+class GrUserTestPopupElement extends PolymerElement {
+  static get is() { return 'gr-user-test-popup'; }
+
+  static get template() {
+    return html`<div id="barfoo">some test module</div>`;
+  }
+}
+
+customElements.define(GrUserTestPopupElement.is, GrUserTestPopupElement);
+
+const containerFixture = fixtureFromElement('div');
 
 const pluginApi = _testOnly_initGerritPluginApi();
 suite('gr-popup-interface tests', () => {
@@ -60,7 +46,7 @@
     sandbox = sinon.sandbox.create();
     pluginApi.install(p => { plugin = p; }, '0.1',
         'http://test.com/plugins/testplugin/static/test.js');
-    container = fixture('container');
+    container = containerFixture.instantiate();
     sandbox.stub(plugin, 'hook').returns({
       getLastAttached() {
         return Promise.resolve(container);
@@ -124,4 +110,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.js b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.js
index 1af91fd..4c8e1e5 100644
--- a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.js
@@ -1,41 +1,30 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-repo-api</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-endpoint-decorator name="repo-command">
-    </gr-endpoint-decorator>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../gr-endpoint-decorator/gr-endpoint-decorator.js';
 import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
 import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-endpoint-decorator name="repo-command">
+    </gr-endpoint-decorator>
+`);
 
 const pluginApi = _testOnly_initGerritPluginApi();
 
@@ -67,7 +56,7 @@
     repoApi
         .createCommand('foo', attachedStub)
         .onTap(tapStub);
-    const element = fixture('basic');
+    const element = basicFixture.instantiate();
     flush(() => {
       assert.isTrue(attachedStub.called);
       const pluginCommand = element.shadowRoot
@@ -84,4 +73,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.js b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.js
index 5057992..236d1f0 100644
--- a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.js
@@ -1,43 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Settings
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-settings-api</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-endpoint-decorator name="settings-menu-item">
-    </gr-endpoint-decorator>
-    <gr-endpoint-decorator name="settings-screen">
-    </gr-endpoint-decorator>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../gr-endpoint-decorator/gr-endpoint-decorator.js';
 import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
 import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-endpoint-decorator name="settings-menu-item">
+    </gr-endpoint-decorator>
+    <gr-endpoint-decorator name="settings-screen">
+    </gr-endpoint-decorator>
+`);
 
 const pluginApi = _testOnly_initGerritPluginApi();
 
@@ -69,7 +58,7 @@
         .token('bar')
         .module('some-settings-screen')
         .build();
-    const element = fixture('basic');
+    const element = basicFixture.instantiate();
     flush(() => {
       const [menuItemEl, itemEl] = element;
       const menuItem = menuItemEl.shadowRoot
@@ -86,4 +75,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-styles-api/gr-styles-api_test.js b/polygerrit-ui/app/elements/plugins/gr-styles-api/gr-styles-api_test.js
index d6bae9b..9671708 100644
--- a/polygerrit-ui/app/elements/plugins/gr-styles-api/gr-styles-api_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-styles-api/gr-styles-api_test.js
@@ -1,47 +1,37 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-admin-api</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<dom-module id="gr-style-test-element">
-  <template>
-    <div id="wrapper"></div>
-  </template>
-  <script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
-import {Polymer} from '@polymer/polymer/lib/legacy/polymer-fn.js';
-Polymer({is: 'gr-style-test-element'});
-</script>
-</dom-module>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
-import '../../shared/gr-js-api-interface/gr-js-api-interface.js';
+import {PolymerElement} from '@polymer/polymer/polymer-element.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
 import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+class GrStyleTestElement extends PolymerElement {
+  static get is() { return 'gr-style-test-element'; }
+
+  static get template() {
+    return html`<div id="wrapper"></div>`;
+  }
+}
+
+customElements.define(GrStyleTestElement.is, GrStyleTestElement);
 
 const pluginApi = _testOnly_initGerritPluginApi();
 
@@ -77,6 +67,7 @@
     let stylesApi;
     let displayInlineStyle;
     let displayNoneStyle;
+    let elementsToRemove;
 
     setup(() => {
       sandbox = sinon.sandbox.create();
@@ -87,12 +78,17 @@
       stylesApi = plugin.styles();
       displayInlineStyle = stylesApi.css('display: inline');
       displayNoneStyle = stylesApi.css('display: none');
+      elementsToRemove = [];
     });
 
     teardown(() => {
       displayInlineStyle = null;
       displayNoneStyle = null;
       stylesApi = null;
+      elementsToRemove.forEach(element => {
+        element.remove();
+      });
+      elementsToRemove = null;
       sandbox.restore();
     });
 
@@ -109,6 +105,11 @@
       dom(parentElement).appendChild(element2);
       dom(element2).appendChild(element3);
 
+      if (parentElement === document.body) {
+        elementsToRemove.push(element1);
+        elementsToRemove.push(element2);
+      }
+
       return [element1, element2, element3];
     }
 
@@ -121,6 +122,7 @@
     test('getClassName  - elements inside polymer element', () => {
       const polymerElement = document.createElement('gr-style-test-element');
       dom(document.body).appendChild(polymerElement);
+      elementsToRemove.push(polymerElement);
       const contentElements = createNestedElements(polymerElement.$.wrapper);
 
       testGetClassName(contentElements);
@@ -154,6 +156,7 @@
     test('apply - elements inside polymer element', () => {
       const polymerElement = document.createElement('gr-style-test-element');
       dom(document.body).appendChild(polymerElement);
+      elementsToRemove.push(polymerElement);
       const contentElements = createNestedElements(polymerElement.$.wrapper);
 
       testApply(contentElements);
@@ -185,4 +188,4 @@
     }
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.js b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.js
index 9e2e190..7b1e4ab 100644
--- a/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.js
+++ b/polygerrit-ui/app/elements/plugins/gr-theme-api/gr-theme-api_test.js
@@ -1,42 +1,31 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-theme-api</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="header-title">
-  <template>
-    <gr-endpoint-decorator name="header-title">
-      <span class="titleText"></span>
-    </gr-endpoint-decorator>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../gr-endpoint-decorator/gr-endpoint-decorator.js';
 import {pluginLoader} from '../../shared/gr-js-api-interface/gr-plugin-loader.js';
 import {_testOnly_initGerritPluginApi} from '../../shared/gr-js-api-interface/gr-gerrit.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const headerTitleFixture = fixtureFromTemplate(html`
+<gr-endpoint-decorator name="header-title">
+      <span class="titleText"></span>
+    </gr-endpoint-decorator>
+`);
 
 const pluginApi = _testOnly_initGerritPluginApi();
 
@@ -65,7 +54,7 @@
     let customHeader;
 
     setup(() => {
-      fixture('header-title');
+      headerTitleFixture.instantiate();
       stub('gr-custom-plugin-header', {
         /** @override */
         ready() { customHeader = this; },
@@ -84,4 +73,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.js b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.js
index 53641d9..45b75d4 100644
--- a/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-account-info/gr-account-info_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-account-info</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-account-info></gr-account-info>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-account-info.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-account-info');
+
 suite('gr-account-info tests', () => {
   let element;
   let account;
@@ -70,7 +56,7 @@
         return Promise.resolve({time_format: 'HHMM_12'});
       },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     // Allow the element to render.
     element.loadData().then(() => { flush(done); });
   });
@@ -339,4 +325,4 @@
     assert.equal(element._hideAvatarChangeUrl('https://example.com'), '');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list_test.js b/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list_test.js
index 3a2b86d..ed0bdb3 100644
--- a/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-agreements-list/gr-agreements-list_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-settings-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-agreements-list></gr-agreements-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-agreements-list.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-agreements-list');
+
 suite('gr-agreements-list tests', () => {
   let element;
   let agreements;
@@ -50,7 +36,7 @@
       getAccountAgreements() { return Promise.resolve(agreements); },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
 
     element.loadData().then(() => { flush(done); });
   });
@@ -67,4 +53,4 @@
     assert.equal(nameCells[0], 'Agreements 1');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.js b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.js
index 27532b4..e051ef7 100644
--- a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-settings-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-change-table-editor></gr-change-table-editor>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-change-table-editor.js';
+
+const basicFixture = fixtureFromElement('gr-change-table-editor');
+
 suite('gr-change-table-editor tests', () => {
   let element;
   let columns;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
 
     columns = [
@@ -168,4 +154,4 @@
     assert.notInclude(element.displayedColumns, 'Assignee');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view_test.js b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view_test.js
index bc3c10c..6f89c49 100644
--- a/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-cla-view/gr-cla-view_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-cla-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-cla-view></gr-cla-view>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-cla-view.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-cla-view');
+
 suite('gr-cla-view tests', () => {
   let element;
   const signedAgreements = [{
@@ -124,7 +110,7 @@
       getAccountGroups() { return Promise.resolve(groups); },
       getAccountAgreements() { return Promise.resolve(signedAgreements); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.loadData().then(() => { flush(done); });
   });
 
@@ -191,4 +177,4 @@
         'test_cla.html'), '/test_cla.html');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences_test.js b/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences_test.js
index 3cc7bfe..e9967b7 100644
--- a/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-edit-preferences/gr-edit-preferences_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-edit-preferences</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-edit-preferences></gr-edit-preferences>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-edit-preferences.js';
+
+const basicFixture = fixtureFromElement('gr-edit-preferences');
+
 suite('gr-edit-preferences tests', () => {
   let element;
   let sandbox;
@@ -76,7 +62,7 @@
       },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     return element.loadData();
   });
@@ -123,4 +109,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.js b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.js
index ad2553d..805b8c8 100644
--- a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-email-editor</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-email-editor></gr-email-editor>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-email-editor.js';
+
+const basicFixture = fixtureFromElement('gr-email-editor');
+
 suite('gr-email-editor tests', () => {
   let element;
 
@@ -48,7 +34,7 @@
       getAccountEmails() { return Promise.resolve(emails); },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
 
     element.loadData().then(flush(done));
   });
@@ -149,4 +135,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_test.js b/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_test.js
index 4a0af5b..7752ca7 100644
--- a/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-gpg-editor/gr-gpg-editor_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-gpg-editor</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-gpg-editor></gr-gpg-editor>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-gpg-editor.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-gpg-editor');
+
 suite('gr-gpg-editor tests', () => {
   let element;
   let keys;
@@ -69,7 +55,7 @@
       getAccountGPGKeys() { return Promise.resolve(keys); },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
 
     element.loadData().then(() => { flush(done); });
   });
@@ -192,4 +178,4 @@
     assert.deepEqual(addStub.lastCall.args[0], {add: [newKeyString]});
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list_test.js b/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list_test.js
index 2fdc7b3..dec2928 100644
--- a/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-group-list/gr-group-list_test.js
@@ -1,42 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-settings-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-group-list></gr-group-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-group-list.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-group-list');
+
 suite('gr-group-list tests', () => {
   let sandbox;
   let element;
@@ -67,7 +52,7 @@
       getAccountGroups() { return Promise.resolve(groups); },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
 
     element.loadData().then(() => { flush(done); });
   });
@@ -121,4 +106,4 @@
         '/admin/groups/user/test');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_test.js b/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_test.js
index 26fa84d..388ac96 100644
--- a/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-http-password/gr-http-password_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-settings-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-http-password></gr-http-password>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-http-password.js';
+
+const basicFixture = fixtureFromElement('gr-http-password');
+
 suite('gr-http-password tests', () => {
   let element;
   let account;
@@ -48,7 +34,7 @@
       getConfig() { return Promise.resolve(config); },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.loadData().then(() => { flush(done); });
   });
 
@@ -88,4 +74,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-identities/gr-identities_test.js b/polygerrit-ui/app/elements/settings/gr-identities/gr-identities_test.js
index 0965826..cd5e685 100644
--- a/polygerrit-ui/app/elements/settings/gr-identities/gr-identities_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-identities/gr-identities_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-identities</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-identities></gr-identities>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-identities.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-identities');
+
 suite('gr-identities tests', () => {
   let element;
   let sandbox;
@@ -61,7 +47,7 @@
       getExternalIds() { return Promise.resolve(ids); },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
 
     element.loadData().then(() => { flush(done); });
   });
@@ -187,4 +173,4 @@
     assert.isFalse(element._showLinkAnotherIdentity);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.js b/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.js
index 9c8db6d..19852d9 100644
--- a/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-settings-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-menu-editor></gr-menu-editor>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-menu-editor.js';
 import {flush as flush$0} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-menu-editor');
+
 suite('gr-menu-editor tests', () => {
   let element;
   let menu;
@@ -61,7 +47,7 @@
   }
 
   setup(done => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     menu = [
       {url: '/first/url', name: 'first name', target: '_blank'},
       {url: '/second/url', name: 'second name', target: '_blank'},
@@ -175,4 +161,4 @@
     assertMenuNamesEqual(element, ['new name']);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.js b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.js
index a3f8548..e6f06df 100644
--- a/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-registration-dialog/gr-registration-dialog_test.js
@@ -1,45 +1,24 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-registration-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-registration-dialog></gr-registration-dialog>
-  </template>
-</test-fixture>
-
-<test-fixture id="blank">
-  <template>
-    <div></div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import '../../../test/common-test-setup-karma.js';
 import './gr-registration-dialog.js';
+
+const basicFixture = fixtureFromElement('gr-registration-dialog');
+
 suite('gr-registration-dialog tests', () => {
   let element;
   let account;
@@ -82,7 +61,7 @@
       },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
 
     return element.loadData();
   });
@@ -183,4 +162,4 @@
         {auth: {editable_account_fields: []}}, 'abc'));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.js b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.js
index 09ad0e3..f328cda 100644
--- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.js
@@ -523,4 +523,4 @@
       resolveConfirm('bar');
     });
   });
-});
\ No newline at end of file
+});
diff --git a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_test.js b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_test.js
index 56625ae..445199b 100644
--- a/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-ssh-editor/gr-ssh-editor_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-ssh-editor</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-ssh-editor></gr-ssh-editor>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-ssh-editor.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-ssh-editor');
+
 suite('gr-ssh-editor tests', () => {
   let element;
   let keys;
@@ -60,7 +46,7 @@
       getAccountSSHKeys() { return Promise.resolve(keys); },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
 
     element.loadData().then(() => { flush(done); });
   });
@@ -178,4 +164,4 @@
     assert.equal(addStub.lastCall.args[0], newKeyString);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.js b/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.js
index 2a08e4f..d42f579 100644
--- a/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.js
+++ b/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-settings-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-watched-projects-editor></gr-watched-projects-editor>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-watched-projects-editor.js';
+
+const basicFixture = fixtureFromElement('gr-watched-projects-editor');
+
 suite('gr-watched-projects-editor tests', () => {
   let element;
 
@@ -75,7 +61,7 @@
       },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
 
     element.loadData().then(() => { flush(done); });
   });
@@ -212,4 +198,4 @@
     assert.equal(element._projectsToRemove[0].project, 'project b');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry_test.js b/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry_test.js
index 5899ad4..0ec3481 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-entry/gr-account-entry_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-account-entry</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-account-entry></gr-account-entry>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-account-entry.js';
+
+const basicFixture = fixtureFromElement('gr-account-entry');
+
 suite('gr-account-entry tests', () => {
   let sandbox;
   let element;
@@ -54,7 +40,7 @@
   };
 
   setup(done => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     return flush(done);
   });
@@ -106,4 +92,4 @@
     assert.isFalse(suggestSpy.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.js b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.js
index 4cc66c4..94274a7 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-account-label</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-account-label></gr-account-label>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-account-label.js';
+
+const basicFixture = fixtureFromElement('gr-account-label');
+
 suite('gr-account-label tests', () => {
   let element;
 
@@ -42,7 +28,7 @@
       getConfig() { return Promise.resolve({}); },
       getLoggedIn() { return Promise.resolve(false); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element._config = {
       user: {
         anonymous_coward_name: 'Anonymous Coward',
@@ -91,4 +77,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_test.js b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_test.js
index f3bff6e..e42907b 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-link/gr-account-link_test.js
@@ -1,41 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-account-link</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-account-link></gr-account-link>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-account-link.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 
+const basicFixture = fixtureFromElement('gr-account-link');
+
 suite('gr-account-link tests', () => {
   let element;
   let sandbox;
@@ -44,7 +29,7 @@
     stub('gr-rest-api-interface', {
       getConfig() { return Promise.resolve({}); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -78,4 +63,4 @@
     assert.isTrue(urlStub.lastCall.calledWithExactly('_account_id'));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-account-list/gr-account-list_test.js b/polygerrit-ui/app/elements/shared/gr-account-list/gr-account-list_test.js
index 41158a8..c7635cf 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-list/gr-account-list_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-account-list/gr-account-list_test.js
@@ -1,41 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-account-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-account-list></gr-account-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-account-list.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 
+const basicFixture = fixtureFromElement('gr-account-list');
+
 class MockSuggestionsProvider {
   getSuggestions(input) {
     return Promise.resolve([]);
@@ -80,7 +65,7 @@
     stub('gr-rest-api-interface', {
       getConfig() { return Promise.resolve({}); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.accounts = [existingAccount1, existingAccount2];
     suggestionsProvider = new MockSuggestionsProvider();
     element.suggestionsProvider = suggestionsProvider;
@@ -551,4 +536,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.js b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.js
index 557ec28..8105584 100644
--- a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.js
@@ -1,31 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-alert</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-alert.js';
 suite('gr-alert tests', () => {
   let element;
@@ -56,4 +46,4 @@
         .querySelector('.action'));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown_test.js b/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown_test.js
index d836155..54e2a5f 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete-dropdown/gr-autocomplete-dropdown_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-autocomplete-dropdown</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-autocomplete-dropdown></gr-autocomplete-dropdown>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-autocomplete-dropdown.js';
+
+const basicFixture = fixtureFromElement('gr-autocomplete-dropdown');
+
 suite('gr-autocomplete-dropdown', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.open();
     element.suggestions = [
       {dataValue: 'test value 1', name: 'test name 1', text: 1, label: 'hi'},
@@ -151,4 +137,4 @@
     assert.isTrue(resetStopsSpy.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.js b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.js
index dddc3d8..6a3fe36 100644
--- a/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-avatar/gr-avatar_test.js
@@ -1,48 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-avatar</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-avatar></gr-avatar>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-avatar.js';
 import {pluginLoader} from '../gr-js-api-interface/gr-plugin-loader.js';
 
+const basicFixture = fixtureFromElement('gr-avatar');
+
 suite('gr-avatar tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -103,51 +88,49 @@
     assert.equal(element._buildAvatarURL(undefined), '');
   });
 
-  test('dom for existing account', () => {
-    assert.isFalse(element.hasAttribute('hidden'));
+  suite('config set', () => {
+    setup(() => {
+      stub('gr-avatar', {
+        _getConfig: () => Promise.resolve({plugin: {has_avatars: true}}),
+      });
+      element = basicFixture.instantiate();
+    });
 
-    sandbox.stub(
-        element,
-        '_getConfig',
-        () => Promise.resolve({plugin: {has_avatars: true}}));
-
-    element.imageSize = 64;
-    element.account = {
-      _account_id: 123,
-    };
-
-    assert.strictEqual(element.style.backgroundImage, '');
-
-    // Emulate plugins loaded.
-    pluginLoader.loadPlugins([]);
-
-    Promise.all([
-      element.$.restAPI.getConfig(),
-      pluginLoader.awaitPluginsLoaded(),
-    ]).then(() => {
+    test('dom for existing account', () => {
       assert.isFalse(element.hasAttribute('hidden'));
 
-      assert.isTrue(
-          element.style.backgroundImage.includes('/accounts/123/avatar?s=64'));
+      element.imageSize = 64;
+      element.account = {
+        _account_id: 123,
+      };
+
+      assert.strictEqual(element.style.backgroundImage, '');
+
+      // Emulate plugins loaded.
+      pluginLoader.loadPlugins([]);
+
+      return Promise.all([
+        element.$.restAPI.getConfig(),
+        pluginLoader.awaitPluginsLoaded(),
+      ]).then(() => {
+        assert.isFalse(element.hasAttribute('hidden'));
+
+        assert.isTrue(
+            element.style.backgroundImage.includes(
+                '/accounts/123/avatar?s=64'));
+      });
     });
   });
 
   suite('plugin has avatars', () => {
     let element;
-    let sandbox;
 
     setup(() => {
-      sandbox = sinon.sandbox.create();
-
       stub('gr-avatar', {
         _getConfig: () => Promise.resolve({plugin: {has_avatars: true}}),
       });
 
-      element = fixture('basic');
-    });
-
-    teardown(() => {
-      sandbox.restore();
+      element = basicFixture.instantiate();
     });
 
     test('dom for non available account', () => {
@@ -169,20 +152,13 @@
 
   suite('config not set', () => {
     let element;
-    let sandbox;
 
     setup(() => {
-      sandbox = sinon.sandbox.create();
-
       stub('gr-avatar', {
         _getConfig: () => Promise.resolve({}),
       });
 
-      element = fixture('basic');
-    });
-
-    teardown(() => {
-      sandbox.restore();
+      element = basicFixture.instantiate();
     });
 
     test('avatar hidden when account set', () => {
@@ -206,4 +182,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.js b/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.js
index dfc3d75..3bad443 100644
--- a/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.js
@@ -1,55 +1,37 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-button</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-button></gr-button>
-  </template>
-</test-fixture>
-
-<test-fixture id="nested">
-  <template>
-    <div id="test">
-      <gr-button class="testBtn"></gr-button>
-    </div>
-  </template>
-</test-fixture>
-
-<test-fixture id="tabindex">
-  <template>
-    <gr-button tabindex="3"></gr-button>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-button.js';
 import {addListener} from '@polymer/polymer/lib/utils/gestures.js';
 import {appContext} from '../../../services/app-context.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromElement('gr-button');
+
+const nestedFixture = fixtureFromTemplate(html`
+<div id="test">
+  <gr-button class="testBtn"></gr-button>
+</div>
+`);
+
+const tabindexFixture = fixtureFromTemplate(html`
+  <gr-button tabindex="3"></gr-button>
+`);
 
 suite('gr-button tests', () => {
   let element;
@@ -66,7 +48,7 @@
   };
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -118,7 +100,7 @@
   });
 
   test('tabindex should be preserved', () => {
-    element = fixture('tabindex');
+    element = tabindexFixture.instantiate();
     element.disabled = false;
     assert.equal(element.getAttribute('tabindex'), '3');
     element.disabled = true;
@@ -204,19 +186,20 @@
       assert.isTrue(reportStub.calledOnce);
       assert.equal(reportStub.lastCall.args[0], 'button-click');
       assert.deepEqual(reportStub.lastCall.args[1], {
-        path: 'html>body>test-fixture#basic>gr-button',
+        path: `html>body>test-fixture#${basicFixture.fixtureId}>gr-button`,
       });
     });
 
     test('report event after click on nested', () => {
-      element = fixture('nested');
+      element = nestedFixture.instantiate();
       MockInteractions.click(element.querySelector('gr-button'));
       assert.isTrue(reportStub.calledOnce);
       assert.equal(reportStub.lastCall.args[0], 'button-click');
       assert.deepEqual(reportStub.lastCall.args[1], {
-        path: 'html>body>test-fixture#nested>div#test>gr-button.testBtn',
+        path: `html>body>test-fixture#${nestedFixture.fixtureId}` +
+            `>div#test>gr-button.testBtn`,
       });
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.js b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.js
index 1ea9071..d479ece 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.js
@@ -1,44 +1,30 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-change-star</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-change-star></gr-change-star>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-change-star.js';
+
+const basicFixture = fixtureFromElement('gr-change-star');
+
 suite('gr-change-star tests', () => {
   let element;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.change = {
       _number: 2,
       starred: true,
@@ -79,4 +65,4 @@
         .querySelector('button'));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.js b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.js
index 806203b..8112e21 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-change-status</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-change-status></gr-change-status>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-change-status.js';
+
+const basicFixture = fixtureFromElement('gr-change-status');
+
 const WIP_TOOLTIP = 'This change isn\'t ready to be reviewed or submitted. ' +
     'It will not appear on dashboards unless you are CC\'ed or assigned, ' +
     'and email notifications will be silenced until the review is started.';
@@ -50,7 +36,7 @@
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -134,4 +120,4 @@
     assert.isTrue(element.classList.contains('wip'));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.js b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.js
index e219b22..17c92fc 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.js
@@ -1,49 +1,30 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-comment-thread</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-comment-thread></gr-comment-thread>
-  </template>
-</test-fixture>
-
-<test-fixture id="withComment">
-  <template>
-    <gr-comment-thread></gr-comment-thread>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-comment-thread.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
 import {SpecialFilePath} from '../../../constants/constants.js';
 
+const basicFixture = fixtureFromElement('gr-comment-thread');
+
+const withCommentFixture = fixtureFromElement('gr-comment-thread');
+
 suite('gr-comment-thread tests', () => {
   suite('basic test', () => {
     let element;
@@ -55,7 +36,7 @@
         getLoggedIn() { return Promise.resolve(false); },
       });
       sandbox = sinon.sandbox.create();
-      element = fixture('basic');
+      element = basicFixture.instantiate();
     });
 
     teardown(() => {
@@ -277,7 +258,7 @@
       },
       deleteDiffDraft() { return Promise.resolve({ok: true}); },
     });
-    element = fixture('withComment');
+    element = withCommentFixture.instantiate();
     element.comments = [{
       author: {
         name: 'Mr. Peanutbutter',
@@ -858,7 +839,7 @@
       },
       deleteDiffDraft() { return Promise.resolve({ok: true}); },
     });
-    element = fixture('withComment');
+    element = withCommentFixture.instantiate();
     element.comments = [{
       author: {
         name: 'Mr. Peanutbutter',
@@ -903,4 +884,4 @@
     assert.ok(quoteBtn);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js
index 17c01e9..cfbe836 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.js
@@ -1,46 +1,30 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-comment</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script src="/node_modules/page/page.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-comment></gr-comment>
-  </template>
-</test-fixture>
-
-<test-fixture id="draft">
-  <template>
-    <gr-comment draft="true"></gr-comment>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-comment.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromElement('gr-comment');
+
+const draftFixture = fixtureFromTemplate(html`
+<gr-comment draft="true"></gr-comment>
+`);
+
 function isVisible(el) {
   assert.ok(el);
   return getComputedStyle(el).getPropertyValue('display') !== 'none';
@@ -50,11 +34,13 @@
   suite('basic tests', () => {
     let element;
     let sandbox;
+    let openOverlaySpy;
+
     setup(() => {
       stub('gr-rest-api-interface', {
         getAccount() { return Promise.resolve(null); },
       });
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.comment = {
         author: {
           name: 'Mr. Peanutbutter',
@@ -66,9 +52,13 @@
         updated: '2015-12-08 19:48:33.843000000',
       };
       sandbox = sinon.sandbox.create();
+      openOverlaySpy = sandbox.spy(element, '_openOverlay');
     });
 
     teardown(() => {
+      openOverlaySpy.getCalls().forEach(call => {
+        call.args[0].remove();
+      });
       sandbox.restore();
     });
 
@@ -397,7 +387,7 @@
       stub('gr-storage', {
         getDraftComment() { return null; },
       });
-      element = fixture('draft');
+      element = draftFixture.instantiate();
       element.changeNum = 42;
       element.patchNum = 1;
       element.editing = false;
@@ -1174,7 +1164,7 @@
         setRespectfulTipVisibility() { return respectfulSetStub(); },
       });
       respectfulGetStub.returns(null);
-      element = fixture('draft');
+      element = draftFixture.instantiate();
       // fake random
       element.getRandomNum = () => 0;
       element.comment = {__editing: true};
@@ -1197,7 +1187,7 @@
         setRespectfulTipVisibility(days) { return respectfulSetStub(days); },
       });
       respectfulGetStub.returns(null);
-      element = fixture('draft');
+      element = draftFixture.instantiate();
       // fake random
       element.getRandomNum = () => 0;
       element.comment = {__editing: true};
@@ -1226,7 +1216,7 @@
         setRespectfulTipVisibility() { return respectfulSetStub(); },
       });
       respectfulGetStub.returns(null);
-      element = fixture('draft');
+      element = draftFixture.instantiate();
       // fake random
       element.getRandomNum = () => 3;
       element.comment = {__editing: true};
@@ -1249,7 +1239,7 @@
         setRespectfulTipVisibility() { return respectfulSetStub(); },
       });
       respectfulGetStub.returns(null);
-      element = fixture('draft');
+      element = draftFixture.instantiate();
       // fake random
       element.getRandomNum = () => 0;
       element.comment = {__editing: false};
@@ -1281,7 +1271,7 @@
         setRespectfulTipVisibility() { return respectfulSetStub(); },
       });
       respectfulGetStub.returns({});
-      element = fixture('draft');
+      element = draftFixture.instantiate();
       // fake random
       element.getRandomNum = () => 0;
       element.comment = {__editing: true};
@@ -1296,4 +1286,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js
index 398f7f0..78be439 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.js
@@ -1,47 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-copy-clipboard</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-copy-clipboard></gr-copy-clipboard>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-copy-clipboard.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-copy-clipboard');
+
 suite('gr-copy-clipboard tests', () => {
   let element;
   let sandbox;
 
   setup(done => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.text = `git fetch http://gerrit@localhost:8080/a/test-project
         refs/changes/05/5/1 && git checkout FETCH_HEAD`;
     flushAsynchronousOperations();
@@ -102,4 +88,4 @@
     assert.isFalse(clickStub.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-count-string-formatter/gr-count-string-formatter_test.js b/polygerrit-ui/app/elements/shared/gr-count-string-formatter/gr-count-string-formatter_test.js
index 63435d2..36637ec 100644
--- a/polygerrit-ui/app/elements/shared/gr-count-string-formatter/gr-count-string-formatter_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-count-string-formatter/gr-count-string-formatter_test.js
@@ -1,31 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-count-string-formatter</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import {GrCountStringFormatter} from './gr-count-string-formatter.js';
 
 suite('gr-count-string-formatter tests', () => {
@@ -54,5 +44,4 @@
         '2 comments');
   });
 });
-</script>
 
diff --git a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.js b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.js
index 589a157..3ee3665 100644
--- a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.js
@@ -1,40 +1,29 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-date-formatter</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-date-formatter date-str="2015-09-24 23:30:17.033000000"></gr-date-formatter>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-date-formatter.js';
 import {parseDate} from '../../../utils/date-util.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-date-formatter date-str="2015-09-24 23:30:17.033000000"></gr-date-formatter>
+`);
+
 suite('gr-date-formatter tests', () => {
   let element;
   let sandbox;
@@ -93,7 +82,7 @@
       date_format: 'STD',
       relative_date_in_change_table: false,
     }).then(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       sandbox.stub(element, '_getUtcOffsetString').returns('');
       return element._loadPreferences();
     }));
@@ -142,7 +131,7 @@
       date_format: 'US',
       relative_date_in_change_table: false,
     }).then(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       sandbox.stub(element, '_getUtcOffsetString').returns('');
       return element._loadPreferences();
     }));
@@ -178,7 +167,7 @@
       date_format: 'ISO',
       relative_date_in_change_table: false,
     }).then(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       sandbox.stub(element, '_getUtcOffsetString').returns('');
       return element._loadPreferences();
     }));
@@ -214,7 +203,7 @@
       date_format: 'EURO',
       relative_date_in_change_table: false,
     }).then(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       sandbox.stub(element, '_getUtcOffsetString').returns('');
       return element._loadPreferences();
     }));
@@ -250,7 +239,7 @@
       date_format: 'UK',
       relative_date_in_change_table: false,
     }).then(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       sandbox.stub(element, '_getUtcOffsetString').returns('');
       return element._loadPreferences();
     }));
@@ -286,7 +275,7 @@
       stubRestAPI(
           {time_format: 'HHMM_12', date_format: 'STD'}
       ).then(() => {
-        element = fixture('basic');
+        element = basicFixture.instantiate();
         sandbox.stub(element, '_getUtcOffsetString').returns('');
         return element._loadPreferences();
       })
@@ -307,7 +296,7 @@
       stubRestAPI(
           {time_format: 'HHMM_12', date_format: 'US'}
       ).then(() => {
-        element = fixture('basic');
+        element = basicFixture.instantiate();
         sandbox.stub(element, '_getUtcOffsetString').returns('');
         return element._loadPreferences();
       })
@@ -328,7 +317,7 @@
       stubRestAPI(
           {time_format: 'HHMM_12', date_format: 'ISO'}
       ).then(() => {
-        element = fixture('basic');
+        element = basicFixture.instantiate();
         sandbox.stub(element, '_getUtcOffsetString').returns('');
         return element._loadPreferences();
       })
@@ -349,7 +338,7 @@
       stubRestAPI(
           {time_format: 'HHMM_12', date_format: 'EURO'}
       ).then(() => {
-        element = fixture('basic');
+        element = basicFixture.instantiate();
         sandbox.stub(element, '_getUtcOffsetString').returns('');
         return element._loadPreferences();
       })
@@ -370,7 +359,7 @@
       stubRestAPI(
           {time_format: 'HHMM_12', date_format: 'UK'}
       ).then(() => {
-        element = fixture('basic');
+        element = basicFixture.instantiate();
         sandbox.stub(element, '_getUtcOffsetString').returns('');
         return element._loadPreferences();
       })
@@ -391,7 +380,7 @@
       date_format: 'STD',
       relative_date_in_change_table: true,
     }).then(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       sandbox.stub(element, '_getUtcOffsetString').returns('');
       return element._loadPreferences();
     }));
@@ -419,7 +408,7 @@
       date_format: 'US',
       relative_date_in_change_table: true,
     }).then(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       return element._loadPreferences();
     }));
 
@@ -433,7 +422,7 @@
 
   suite('logged out', () => {
     setup(() => stubRestAPI(null).then(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       return element._loadPreferences();
     }));
 
@@ -445,4 +434,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.js b/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.js
index 1060e82..18f7690 100644
--- a/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.js
@@ -1,47 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-dialog</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-dialog></gr-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-dialog.js';
 import {isHidden} from '../../../test/test-utils.js';
+
+const basicFixture = fixtureFromElement('gr-dialog');
+
 suite('gr-dialog tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
@@ -108,4 +94,4 @@
     assert.isTrue(isHidden(element.$.cancel));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_test.js b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_test.js
index 2750d67..4dde2097 100644
--- a/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-diff-preferences/gr-diff-preferences_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-diff-preferences</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-diff-preferences></gr-diff-preferences>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-diff-preferences.js';
+
+const basicFixture = fixtureFromElement('gr-diff-preferences');
+
 suite('gr-diff-preferences tests', () => {
   let element;
   let sandbox;
@@ -70,7 +56,7 @@
       },
     });
 
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     return element.loadData();
   });
@@ -121,4 +107,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.js b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.js
index 237fbe0..181e00b 100644
--- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-download-commands</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-download-commands></gr-download-commands>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-download-commands.js';
 import {isHidden} from '../../../test/test-utils.js';
+
+const basicFixture = fixtureFromElement('gr-download-commands');
+
 suite('gr-download-commands', () => {
   let element;
   let sandbox;
@@ -68,7 +54,7 @@
 
   suite('unauthenticated', () => {
     setup(done => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       element.schemes = SCHEMES;
       element.commands = COMMANDS;
       element.selectedScheme = SELECTED_SCHEME;
@@ -152,4 +138,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.js b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.js
index b64d5f7..6e9b57f 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-dropdown-list</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-dropdown-list></gr-dropdown-list>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-dropdown-list.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-dropdown-list');
+
 suite('gr-dropdown-list tests', () => {
   let element;
   let sandbox;
@@ -43,7 +29,7 @@
     stub('gr-rest-api-interface', {
       getConfig() { return Promise.resolve({}); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -169,4 +155,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.js b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.js
index d17cc1a..8f23bb5 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.js
@@ -1,40 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-dropdown</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-dropdown></gr-dropdown>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-dropdown.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+
+const basicFixture = fixtureFromElement('gr-dropdown');
+
 suite('gr-dropdown tests', () => {
   let element;
   let sandbox;
@@ -43,7 +29,7 @@
     stub('gr-rest-api-interface', {
       getConfig() { return Promise.resolve({}); },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -205,4 +191,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js
index c50920e..82c4eff 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.js
@@ -1,52 +1,31 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-editable-content</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<!-- Can't use absolute path below for mock-interaction.js.
-Web component tester(wct) has a built-in http server and it serves "/components" directory (which is
-actually /node_modules directory). Also, wct patches some files to load modules from /components.
-With the absolute path, browser tries to load dom-module from 2 different places (/component/... and
-/node_modules/...) though this is actually the same file. This leads to a run-time error.
--->
-<script src="../../../node_modules/iron-test-helpers/mock-interactions.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-editable-content></gr-editable-content>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-editable-content.js';
+
+const basicFixture = fixtureFromElement('gr-editable-content');
+
 suite('gr-editable-content tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -163,4 +142,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.js b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.js
index 1d1bce8..6a4ccb0 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.js
@@ -1,64 +1,42 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../../../test/common-test-setup-karma.js';
+import './gr-editable-label.js';
+import {flush as flush$0} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-editable-label</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<!-- Can't use absolute path below for mock-interaction.js.
-Web component tester(wct) has a built-in http server and it serves "/components" directory (which is
-actually /node_modules directory). Also, wct patches some files to load modules from /components.
-With the absolute path, browser tries to load dom-module from 2 different places (/component/... and
-/node_modules/...) though this is actually the same file. This leads to a run-time error.
--->
-<script src="../../../node_modules/iron-test-helpers/mock-interactions.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-editable-label
+const basicFixture = fixtureFromTemplate(html`
+<gr-editable-label
         value="value text"
         placeholder="label text"></gr-editable-label>
-  </template>
-</test-fixture>
+`);
 
-<test-fixture id="no-placeholder">
-  <template>
-    <gr-editable-label value=""></gr-editable-label>
-  </template>
-</test-fixture>
+const noPlaceholderFixture = fixtureFromTemplate(html`
+<gr-editable-label value=""></gr-editable-label>
+`);
 
-<test-fixture id="read-only">
-  <template>
-    <gr-editable-label
+const readOnlyFixture = fixtureFromTemplate(html`
+<gr-editable-label
         read-only
         value="value text"
         placeholder="label text"></gr-editable-label>
-  </template>
-</test-fixture>
+`);
 
-<script type="module">
-import '../../../test/common-test-setup.js';
-import './gr-editable-label.js';
-import {flush as flush$0} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 suite('gr-editable-label tests', () => {
   let element;
   let elementNoPlaceholder;
@@ -67,8 +45,8 @@
   let sandbox;
 
   setup(done => {
-    element = fixture('basic');
-    elementNoPlaceholder = fixture('no-placeholder');
+    element = basicFixture.instantiate();
+    elementNoPlaceholder = noPlaceholderFixture.instantiate();
 
     label = element.shadowRoot
         .querySelector('label');
@@ -229,7 +207,7 @@
     let label;
 
     setup(() => {
-      element = fixture('read-only');
+      element = readOnlyFixture.instantiate();
       label = element.shadowRoot
           .querySelector('label');
     });
@@ -250,4 +228,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel_test.js b/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel_test.js
index ef31382..13cbd75 100644
--- a/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-fixed-panel/gr-fixed-panel_test.js
@@ -1,56 +1,37 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../../../test/common-test-setup-karma.js';
+import './gr-fixed-panel.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-fixed-panel</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<style>
-  /* Prevent horizontal scrolling on page.
-   New version of web-component-tester creates body with margins */
-  body {
-    margin: 0px;
-    padding: 0px;
-  }
-</style>
-
-<test-fixture id="basic">
-  <template>
-    <gr-fixed-panel>
+const basicFixture = fixtureFromTemplate(html`
+<gr-fixed-panel>
       <div style="height: 100px"></div>
     </gr-fixed-panel>
-  </template>
-</test-fixture>
+`);
 
-<script type="module">
-import '../../../test/common-test-setup.js';
-import './gr-fixed-panel.js';
 suite('gr-fixed-panel', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.readyForMeasure = true;
   });
 
@@ -121,4 +102,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.js b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.js
index 083eac4..3b7f716 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.js
@@ -1,39 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-editable-label</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-formatted-text></gr-formatted-text>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-formatted-text.js';
+
+const basicFixture = fixtureFromElement('gr-formatted-text');
+
 suite('gr-formatted-text tests', () => {
   let element;
   let sandbox;
@@ -49,7 +35,7 @@
   }
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -423,4 +409,4 @@
     assert.isTrue(contentConfigStub.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.js b/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.js
index a321b43..1b7bcec 100644
--- a/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-hovercard-account/gr-hovercard-account_test.js
@@ -1,96 +1,87 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2020 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../../../test/common-test-setup-karma.js';
+import './gr-hovercard-account.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 
-http://www.apache.org/licenses/LICENSE-2.0
+const basicFixture = fixtureFromTemplate(html`
+<gr-hovercard-account class="hovered"></gr-hovercard-account>
+`);
 
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
+suite('gr-hovercard-account tests', () => {
+  let element;
+  let sandbox;
+  const ACCOUNT = {
+    email: 'kermit@gmail.com',
+    username: 'kermit',
+    name: 'Kermit The Frog',
+    _account_id: '31415926535',
+  };
 
-<meta name="viewport"
-      content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<title>gr-hovercard-account</title>
+  setup(() => {
+    sandbox = sinon.sandbox.create();
+    element = basicFixture.instantiate();
+    sandbox.stub(element.$.restAPI, 'getAccount').returns(
+        new Promise(resolve => { '2'; })
+    );
 
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script src="../../../node_modules/iron-test-helpers/mock-interactions.js" type="module"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-hovercard-account class="hovered"></gr-hovercard-account>
-  </template>
-</test-fixture>
-
-
-<script type="module">
-  import '../../../test/common-test-setup.js';
-  import './gr-hovercard-account.js';
-
-  suite('gr-hovercard-account tests', () => {
-    let element;
-    let sandbox;
-    const ACCOUNT = {
-      email: 'kermit@gmail.com',
-      username: 'kermit',
-      name: 'Kermit The Frog',
-      _account_id: '31415926535',
-    };
-
-    setup(() => {
-      sandbox = sinon.sandbox.create();
-      element = fixture('basic');
-      sandbox.stub(element.$.restAPI, 'getAccount').returns(
-          new Promise(resolve => { '2'; })
-      );
-      element.account = Object.assign({}, ACCOUNT);
-      element.show({});
-      flushAsynchronousOperations();
-    });
-
-    test('account name is shown', () => {
-      assert.equal(element.shadowRoot.querySelector('.name').innerText,
-          'Kermit The Frog');
-    });
-
-    test('_computeText', () => {
-      let account = {_account_id: '1'};
-      const selfAccount = {_account_id: '1'};
-      assert.equal(element._computeText(account, selfAccount), 'Your');
-      account = {_account_id: '2'};
-      assert.equal(element._computeText(account, selfAccount), 'Their');
-    });
-
-    test('account status is not shown if the property is not set', () => {
-      assert.isNull(element.shadowRoot.querySelector('.status'));
-    });
-
-    test('account status is displayed', () => {
-      element.account = Object.assign({status: 'OOO'}, ACCOUNT);
-      flushAsynchronousOperations();
-      assert.equal(element.shadowRoot.querySelector('.status .value').innerText,
-          'OOO');
-    });
-
-    test('voteable div is not shown if the property is not set', () => {
-      assert.isNull(element.shadowRoot.querySelector('.voteable'));
-    });
-
-    test('voteable div is displayed', () => {
-      element.voteableText = 'CodeReview: +2';
-      flushAsynchronousOperations();
-      assert.equal(element.shadowRoot.querySelector('.voteable .value').innerText,
-          element.voteableText);
-    });
+    element.account = Object.assign({}, ACCOUNT);
+    element.show({});
+    flushAsynchronousOperations();
   });
-</script>
+
+  teardown(() => {
+    element.hide({});
+  });
+
+  test('account name is shown', () => {
+    assert.equal(element.shadowRoot.querySelector('.name').innerText,
+        'Kermit The Frog');
+  });
+
+  test('_computeText', () => {
+    let account = {_account_id: '1'};
+    const selfAccount = {_account_id: '1'};
+    assert.equal(element._computeText(account, selfAccount), 'Your');
+    account = {_account_id: '2'};
+    assert.equal(element._computeText(account, selfAccount), 'Their');
+  });
+
+  test('account status is not shown if the property is not set', () => {
+    assert.isNull(element.shadowRoot.querySelector('.status'));
+  });
+
+  test('account status is displayed', () => {
+    element.account = Object.assign({status: 'OOO'}, ACCOUNT);
+    flushAsynchronousOperations();
+    assert.equal(element.shadowRoot.querySelector('.status .value').innerText,
+        'OOO');
+  });
+
+  test('voteable div is not shown if the property is not set', () => {
+    assert.isNull(element.shadowRoot.querySelector('.voteable'));
+  });
+
+  test('voteable div is displayed', () => {
+    element.voteableText = 'CodeReview: +2';
+    flushAsynchronousOperations();
+    assert.equal(element.shadowRoot.querySelector('.voteable .value').innerText,
+        element.voteableText);
+  });
+});
+
diff --git a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard_test.js b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard_test.js
index 21f692d..0d5a3f0 100644
--- a/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-hovercard/gr-hovercard_test.js
@@ -1,58 +1,52 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-hovercard</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<!-- Can't use absolute path below for mock-interaction.js.
-Web component tester(wct) has a built-in http server and it serves "/components" directory (which is
-actually /node_modules directory). Also, wct patches some files to load modules from /components.
-With the absolute path, browser tries to load dom-module from 2 different places (/component/... and
-/node_modules/...) though this is actually the same file. This leads to a run-time error.
--->
-<script src="../../../node_modules/iron-test-helpers/mock-interactions.js"></script>
-
-<button id="foo">Hello</button>
-<test-fixture id="basic">
-  <template>
-    <gr-hovercard for="foo" id="bar"></gr-hovercard>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-hovercard.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+//
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-hovercard for="foo" id="bar"></gr-hovercard>
+`);
+
 suite('gr-hovercard tests', () => {
   let element;
   let sandbox;
+  let button;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+
+    button = document.createElement('button');
+    button.innerHTML = 'Hello';
+    button.setAttribute('id', 'foo');
+    document.body.appendChild(button);
+
+    element = basicFixture.instantiate();
   });
 
-  teardown(() => { sandbox.restore(); });
+  teardown(() => {
+    sandbox.restore();
+    element.hide({});
+    button.remove();
+  });
 
   test('updatePosition', () => {
     // Test that the correct style properties have at least been set.
@@ -156,4 +150,4 @@
     button.dispatchEvent(new CustomEvent('mouseenter'));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-context_test.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-context_test.js
index a14612b..4f931f9 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-context_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-context_test.js
@@ -1,42 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-annotation-actions-context</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <div></div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-js-api-interface.js';
 import {GrAnnotation} from '../../diff/gr-diff-highlight/gr-annotation.js';
 import {GrAnnotationActionsContext} from './gr-annotation-actions-context.js';
 import {_testOnly_initGerritPluginApi} from './gr-gerrit.js';
+
 const pluginApi = _testOnly_initGerritPluginApi();
 
 suite('gr-annotation-actions-context tests', () => {
@@ -65,6 +49,7 @@
 
   teardown(() => {
     sandbox.restore();
+    el.remove();
   });
 
   test('test annotateRange', () => {
@@ -101,4 +86,4 @@
     assert.isTrue(lineNumberEl.classList.contains(className));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api_test.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api_test.js
index e72fc63..4bbe7e5 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-annotation-actions-js-api_test.js
@@ -1,44 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-annotation-actions-js-api-js-api</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<test-fixture id="basic">
-  <template>
-    <span hidden id="annotation-span">
-      <label for="annotation-checkbox" id="annotation-label"></label>
-      <iron-input type="checkbox" disabled>
-        <input is="iron-input" type="checkbox" id="annotation-checkbox" disabled>
-      </iron-input>
-    </span>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../../change/gr-change-actions/gr-change-actions.js';
 import {_testOnly_initGerritPluginApi} from './gr-gerrit.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+  <span hidden id="annotation-span">
+    <label for="annotation-checkbox" id="annotation-label"></label>
+    <iron-input type="checkbox" disabled>
+      <input is="iron-input" type="checkbox" id="annotation-checkbox" disabled>
+    </iron-input>
+  </span>
+`);
 
 const pluginApi = _testOnly_initGerritPluginApi();
 
@@ -122,7 +111,7 @@
   });
 
   test('toggle checkbox', () => {
-    const fakeEl = {content: fixture('basic')};
+    const fakeEl = {content: basicFixture.instantiate()};
     const hookStub = {onAttached: sandbox.stub()};
     sandbox.stub(plugin, 'hook').returns(hookStub);
 
@@ -189,4 +178,4 @@
     assert.equal(listenerCalledTimes, 3);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-api-utils_test.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-api-utils_test.js
index d01566a..85c62cb 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-api-utils_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-api-utils_test.js
@@ -1,32 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-api-interface</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-js-api-interface.js';
 import {getPluginNameFromUrl} from './gr-api-utils.js';
 
@@ -82,4 +71,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.js
index 1d5e423..231830bd 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.js
@@ -1,50 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-change-actions-js-api</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<!--
-This must refer to the element this interface is wrapping around. Otherwise
-breaking changes to gr-change-actions won’t be noticed.
--->
-
-<test-fixture id="basic">
-  <template>
-    <gr-change-actions></gr-change-actions>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../../change/gr-change-actions/gr-change-actions.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {resetPlugins} from '../../../test/test-utils.js';
 import {pluginLoader} from './gr-plugin-loader.js';
 import {_testOnly_initGerritPluginApi} from './gr-gerrit.js';
+
+const basicFixture = fixtureFromElement('gr-change-actions');
+
 const pluginApi = _testOnly_initGerritPluginApi();
 
-suite('gr-js-api-interface tests', () => {
+suite('gr-change-actions-js-api-interface tests', () => {
   let element;
   let changeActions;
   let plugin;
@@ -65,7 +47,7 @@
       // Mimic all plugins loaded.
       pluginLoader.loadPlugins([]);
       changeActions = plugin.changeActions();
-      element = fixture('basic');
+      element = basicFixture.instantiate();
     });
 
     teardown(() => {
@@ -83,7 +65,7 @@
   suite('normal init', () => {
     setup(() => {
       resetPlugins();
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       sinon.stub(element, '_editStatusChanged');
       element.change = {};
       element._hasKnownChainState = false;
@@ -229,4 +211,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-reply-js-api_test.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-reply-js-api_test.js
index 0360f85..f545a38 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-reply-js-api_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-reply-js-api_test.js
@@ -1,45 +1,26 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-change-reply-js-api</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<!--
-This must refer to the element this interface is wrapping around. Otherwise
-breaking changes to gr-reply-dialog won’t be noticed.
--->
-
-<test-fixture id="basic">
-  <template>
-    <gr-reply-dialog></gr-reply-dialog>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import '../../change/gr-reply-dialog/gr-reply-dialog.js';
 import {_testOnly_initGerritPluginApi} from './gr-gerrit.js';
 
+const basicFixture = fixtureFromElement('gr-reply-dialog');
+
 const pluginApi = _testOnly_initGerritPluginApi();
 
 suite('gr-change-reply-js-api tests', () => {
@@ -65,7 +46,7 @@
       pluginApi.install(p => { plugin = p; }, '0.1',
           'http://test.com/plugins/testplugin/static/test.js');
       changeReply = plugin.changeReply();
-      element = fixture('basic');
+      element = basicFixture.instantiate();
     });
 
     teardown(() => {
@@ -93,7 +74,7 @@
 
   suite('normal init', () => {
     setup(() => {
-      element = fixture('basic');
+      element = basicFixture.instantiate();
       pluginApi.install(p => { plugin = p; }, '0.1',
           'http://test.com/plugins/testplugin/static/test.js');
       changeReply = plugin.changeReply();
@@ -122,4 +103,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-gerrit_test.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-gerrit_test.js
index 2d87497..d8f240c 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-gerrit_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-gerrit_test.js
@@ -1,43 +1,28 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-api-interface</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-js-api-interface></gr-js-api-interface>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-js-api-interface.js';
 import {pluginLoader} from './gr-plugin-loader.js';
 import {resetPlugins} from '../../../test/test-utils.js';
 import {_testOnly_initGerritPluginApi} from './gr-gerrit.js';
 
+const basicFixture = fixtureFromElement('gr-js-api-interface');
+
 const pluginApi = _testOnly_initGerritPluginApi();
 
 suite('gr-gerrit tests', () => {
@@ -57,7 +42,7 @@
         return sendStub(...args);
       },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -102,4 +87,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.js
index ea1ac91..0c41180 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-js-api-interface_test.js
@@ -1,38 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-api-interface</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-js-api-interface></gr-js-api-interface>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-js-api-interface.js';
 import {BaseUrlBehavior} from '../../../behaviors/base-url-behavior/base-url-behavior.js';
 import {GrPopupInterface} from '../../plugins/gr-popup-interface/gr-popup-interface.js';
@@ -42,6 +25,8 @@
 import {pluginLoader} from './gr-plugin-loader.js';
 import {_testOnly_initGerritPluginApi} from './gr-gerrit.js';
 
+const basicFixture = fixtureFromElement('gr-js-api-interface');
+
 const pluginApi = _testOnly_initGerritPluginApi();
 
 suite('gr-js-api-interface tests', () => {
@@ -70,7 +55,7 @@
         return sendStub(...args);
       },
     });
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     errorStub = sandbox.stub(console, 'error');
     pluginApi.install(p => { plugin = p; }, '0.1',
         'http://test.com/plugins/testplugin/static/test.js');
@@ -585,4 +570,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context_test.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context_test.js
index 08c784ab..dda560f 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-action-context_test.js
@@ -1,38 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-plugin-action-context</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <div></div>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-js-api-interface.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {GrPluginActionContext} from './gr-plugin-action-context.js';
@@ -93,17 +76,28 @@
     assert.equal(div.textContent, 'foobar');
   });
 
-  test('button', done => {
-    const clickStub = sandbox.stub();
-    const button = instance.button('foo', {onclick: clickStub});
-    // If you don't attach a Polymer element to the DOM, then the ready()
-    // callback will not be called and then e.g. this.$ is undefined.
-    dom(document.body).appendChild(button);
-    MockInteractions.tap(button);
-    flush(() => {
-      assert.isTrue(clickStub.called);
-      assert.equal(button.textContent, 'foo');
-      done();
+  suite('button', () => {
+    let clickStub;
+    let button;
+    setup(() => {
+      clickStub = sandbox.stub();
+      button = instance.button('foo', {onclick: clickStub});
+      // If you don't attach a Polymer element to the DOM, then the ready()
+      // callback will not be called and then e.g. this.$ is undefined.
+      dom(document.body).appendChild(button);
+    });
+
+    test('click', done => {
+      MockInteractions.tap(button);
+      flush(() => {
+        assert.isTrue(clickStub.called);
+        assert.equal(button.textContent, 'foo');
+        done();
+      });
+    });
+
+    teardown(() => {
+      button.remove();
     });
   });
 
@@ -160,4 +154,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-loader_test.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-loader_test.js
index f10916d..5f0ee0f 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-loader_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-loader_test.js
@@ -1,38 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-plugin-host</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-js-api-interface></gr-js-api-interface>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-js-api-interface.js';
 import {BaseUrlBehavior} from '../../../behaviors/base-url-behavior/base-url-behavior.js';
 import {PRELOADED_PROTOCOL, PLUGIN_LOADING_TIMEOUT_MS} from './gr-api-utils.js';
@@ -41,6 +24,8 @@
 import {_testOnly_flushPreinstalls} from './gr-gerrit.js';
 import {_testOnly_initGerritPluginApi} from './gr-gerrit.js';
 
+const basicFixture = fixtureFromElement('gr-js-api-interface');
+
 const pluginApi = _testOnly_initGerritPluginApi();
 
 suite('gr-plugin-loader tests', () => {
@@ -64,7 +49,7 @@
     });
     pluginLoader = _testOnly_resetPluginLoader();
     sandbox.stub(document.body, 'appendChild');
-    fixture('basic');
+    basicFixture.instantiate();
     url = window.location.origin;
   });
 
@@ -502,6 +487,9 @@
   });
 
   suite('preloaded plugins', () => {
+    teardown(() => {
+      window.Gerrit._preloadedPlugins = null;
+    });
     test('skips preloaded plugins when load plugins', () => {
       const importHtmlPluginStub = sandbox.stub();
       sandbox.stub(pluginLoader, '_importHtmlPlugin', url => {
@@ -534,7 +522,6 @@
       assert.isTrue(
           pluginLoader.isPluginPreloaded(PRELOADED_PROTOCOL + 'baz')
       );
-      window.Gerrit._preloadedPlugins = null;
     });
 
     test('preloaded plugins are installed', () => {
@@ -555,4 +542,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.js
index fcc3b669..69c8c44 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api_test.js
@@ -1,31 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-plugin-rest-api</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-js-api-interface.js';
 import {GrPluginRestApi} from './gr-plugin-rest-api.js';
 import {_testOnly_initGerritPluginApi} from './gr-gerrit.js';
@@ -157,4 +147,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.js b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.js
index b97b5b3..0f2ea78 100644
--- a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.js
@@ -1,46 +1,33 @@
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-label-info</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-label-info></gr-label-info>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-label-info.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {isHidden} from '../../../test/test-utils.js';
+
+const basicFixture = fixtureFromElement('gr-label-info');
+
 suite('gr-account-link tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     // Needed to trigger computed bindings.
     element.account = {};
@@ -246,4 +233,4 @@
         .querySelector('.placeholder')));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete_test.js b/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete_test.js
index 99a038e..24830ed 100644
--- a/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-labeled-autocomplete/gr-labeled-autocomplete_test.js
@@ -1,45 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-labeled-autocomplete</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-labeled-autocomplete></gr-labeled-autocomplete>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-labeled-autocomplete.js';
+
+const basicFixture = fixtureFromElement('gr-labeled-autocomplete');
+
 suite('gr-labeled-autocomplete tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
@@ -59,4 +46,4 @@
     assert.isTrue(element.$.autocomplete.setText.calledWith('foo-bar'));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader_test.js b/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader_test.js
index 6208252..8577c9a 100644
--- a/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-lib-loader/gr-lib-loader_test.js
@@ -130,4 +130,4 @@
       });
     });
   });
-});
\ No newline at end of file
+});
diff --git a/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text_test.js b/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text_test.js
index 889b786..cb88df9 100644
--- a/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-limited-text/gr-limited-text_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-limited-text</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-limited-text></gr-limited-text>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-limited-text.js';
+
+const basicFixture = fixtureFromElement('gr-limited-text');
+
 suite('gr-limited-text tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -100,4 +86,4 @@
     assert.equal(element.getAttribute('title'), null);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.js b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.js
index c8de3df..e4c277c 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-linked-chip/gr-linked-chip_test.js
@@ -1,52 +1,31 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-linked-chip</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<!-- Can't use absolute path below for mock-interaction.js.
-Web component tester(wct) has a built-in http server and it serves "/components" directory (which is
-actually /node_modules directory). Also, wct patches some files to load modules from /components.
-With the absolute path, browser tries to load dom-module from 2 different places (/component/... and
-/node_modules/...) though this is actually the same file. This leads to a run-time error.
--->
-<script src="../../../node_modules/iron-test-helpers/mock-interactions.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-linked-chip></gr-linked-chip>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-linked-chip.js';
+
+const basicFixture = fixtureFromElement('gr-linked-chip');
+
 suite('gr-linked-chip tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
   });
 
@@ -62,4 +41,4 @@
     assert.isTrue(spy.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.js b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.js
index 4fa4390..054e293 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.js
@@ -1,50 +1,40 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2015 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-linked-text</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-linked-text>
-      <div id="output"></div>
-    </gr-linked-text>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-linked-text.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
 import {GerritNav} from '../../core/gr-navigation/gr-navigation.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-linked-text>
+      <div id="output"></div>
+    </gr-linked-text>
+`);
 
 suite('gr-linked-text tests', () => {
   let element;
   let sandbox;
+  let originalCanonicalPath;
 
   setup(() => {
-    element = fixture('basic');
+    originalCanonicalPath = window.CANONICAL_PATH;
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     sandbox.stub(GerritNav, 'mapCommentlinks', x => x);
     element.config = {
@@ -91,6 +81,7 @@
 
   teardown(() => {
     sandbox.restore();
+    window.CANONICAL_PATH = originalCanonicalPath;
   });
 
   test('URL pattern was parsed and linked.', () => {
@@ -373,4 +364,4 @@
     assert.isTrue(contentConfigStub.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.js b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.js
index 55aab82..ee8f78b 100644
--- a/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-list-view/gr-list-view_test.js
@@ -1,48 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-list-view</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-list-view></gr-list-view>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-list-view.js';
 import page from 'page/page.mjs';
 
+const basicFixture = fixtureFromElement('gr-list-view');
+
 suite('gr-list-view tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -163,4 +148,4 @@
     assert.equal(element._computePage(50, 25), 3);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay_test.js b/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay_test.js
index d43c739..f0d5267 100644
--- a/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-overlay/gr-overlay_test.js
@@ -1,49 +1,37 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../../../test/common-test-setup-karma.js';
+import './gr-overlay.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-overlay</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-overlay>
+const basicFixture = fixtureFromTemplate(html`
+<gr-overlay>
       <div>content</div>
     </gr-overlay>
-  </template>
-</test-fixture>
+`);
 
-<script type="module">
-import '../../../test/common-test-setup.js';
-import './gr-overlay.js';
 suite('gr-overlay tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => {
@@ -88,4 +76,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav_test.js b/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav_test.js
index a54d7a3..6ee4f71 100644
--- a/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-page-nav/gr-page-nav_test.js
@@ -1,51 +1,39 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../../../test/common-test-setup-karma.js';
+import './gr-page-nav.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-page-nav</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/page/page.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-page-nav>
+const basicFixture = fixtureFromTemplate(html`
+<gr-page-nav>
       <ul>
         <li>item</li>
       </ul>
     </gr-page-nav>
-  </template>
-</test-fixture>
+`);
 
-<script type="module">
-import '../../../test/common-test-setup.js';
-import './gr-page-nav.js';
 suite('gr-page-nav tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     flushAsynchronousOperations();
   });
 
@@ -86,4 +74,4 @@
     assert.isTrue(element.$.nav.classList.contains('pinned'));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.js b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.js
index 67b82f9..111843b 100644
--- a/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-repo-branch-picker/gr-repo-branch-picker_test.js
@@ -1,45 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-repo-branch-picker</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-repo-branch-picker></gr-repo-branch-picker>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-repo-branch-picker.js';
+
+const basicFixture = fixtureFromElement('gr-repo-branch-picker');
+
 suite('gr-repo-branch-picker tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   teardown(() => { sandbox.restore(); });
@@ -140,4 +127,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.js
index f3abdb0..b40daaa 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-auth_test.js
@@ -1,31 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-auth</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import {BaseUrlBehavior} from '../../../behaviors/base-url-behavior/base-url-behavior.js';
 import {Auth, authService} from './gr-auth.js';
 import {appContext} from '../../../services/app-context.js';
@@ -391,4 +381,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.js
index cfa164f..3ddc42b 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-etag-decorator_test.js
@@ -1,31 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-etag-decorator</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import {GrEtagDecorator} from './gr-etag-decorator.js';
 
 suite('gr-etag-decorator', () => {
@@ -96,4 +86,4 @@
     assert.strictEqual(etag.getCachedPayload('/foo'), 'new payload');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.js
index 0a51d26..8dd4ff9 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.js
@@ -1,51 +1,38 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-rest-api-interface</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-rest-api-interface></gr-rest-api-interface>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-rest-api-interface.js';
 import {mockPromise} from '../../../test/test-utils.js';
 import {GrReviewerUpdatesParser} from './gr-reviewer-updates-parser.js';
 import {authService} from './gr-auth.js';
 
+const basicFixture = fixtureFromElement('gr-rest-api-interface');
+
 suite('gr-rest-api-interface tests', () => {
   let element;
   let sandbox;
   let ctr = 0;
+  let originalCanonicalPath;
 
   setup(() => {
     // Modify CANONICAL_PATH to effectively reset cache.
     ctr += 1;
+    originalCanonicalPath = window.CANONICAL_PATH;
     window.CANONICAL_PATH = `test${ctr}`;
 
     sandbox = sinon.sandbox.create();
@@ -58,12 +45,13 @@
     }));
     // fake auth
     sandbox.stub(authService, 'authCheck').returns(Promise.resolve(true));
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element._projectLookup = {};
   });
 
   teardown(() => {
     sandbox.restore();
+    window.CANONICAL_PATH = originalCanonicalPath;
   });
 
   test('parent diff comments are properly grouped', done => {
@@ -1446,4 +1434,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper_test.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper_test.js
index 32d2166..076f0bd 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper_test.js
@@ -1,32 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-rest-api-helper</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<script type="module">
-import '../../../../test/common-test-setup.js';
+import '../../../../test/common-test-setup-karma.js';
 import {SiteBasedCache} from './gr-rest-api-helper.js';
 import {FetchPromisesCache, GrRestApiHelper} from './gr-rest-api-helper.js';
 import {authService} from '../gr-auth.js';
@@ -36,12 +25,14 @@
   let sandbox;
   let cache;
   let fetchPromisesCache;
+  let originalCanonicalPath;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
     cache = new SiteBasedCache();
     fetchPromisesCache = new FetchPromisesCache();
 
+    originalCanonicalPath = window.CANONICAL_PATH;
     window.CANONICAL_PATH = 'testhelper';
 
     const mockRestApiInterface = {
@@ -63,6 +54,7 @@
 
   teardown(() => {
     sandbox.restore();
+    window.CANONICAL_PATH = originalCanonicalPath;
   });
 
   suite('fetchJSON()', () => {
@@ -171,4 +163,4 @@
         });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.js
index fa54d6b..f6da64b 100644
--- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-reviewer-updates-parser_test.js
@@ -1,31 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-reviewer-updates-parser</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import {GrReviewerUpdatesParser} from './gr-reviewer-updates-parser.js';
 import {parseDate} from '../../../utils/date-util.js';
 
@@ -303,4 +293,4 @@
     assert.equal(updates[3].date, tplus(500));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.js b/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.js
index 670f383..c697850 100644
--- a/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-select/gr-select_test.js
@@ -1,59 +1,46 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../../../test/common-test-setup-karma.js';
+import './gr-select.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
 
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-select</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-select>
+const basicFixture = fixtureFromTemplate(html`
+<gr-select>
       <select>
         <option value="1">One</option>
         <option value="2">Two</option>
         <option value="3">Three</option>
       </select>
     </gr-select>
-  </template>
-</test-fixture>
+`);
 
-<test-fixture id="noOptions">
-  <template>
-    <gr-select>
+const noOptionsFixture = fixtureFromTemplate(html`
+<gr-select>
       <select>
       </select>
     </gr-select>
-  </template>
-</test-fixture>
+`);
 
-<script type="module">
-import '../../../test/common-test-setup.js';
-import './gr-select.js';
 suite('gr-select tests', () => {
   let element;
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('bindValue must be set to the first option value', () => {
@@ -109,7 +96,7 @@
     let element;
 
     setup(() => {
-      element = fixture('noOptions');
+      element = noOptionsFixture.instantiate();
     });
 
     test('bindValue must not be changed', () => {
@@ -117,4 +104,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.js b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.js
index ee0b64f..f0266fd 100644
--- a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.js
@@ -1,46 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2018 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-shell-command</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-shell-command></gr-shell-command>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-shell-command.js';
+
+const basicFixture = fixtureFromElement('gr-shell-command');
+
 suite('gr-shell-command tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     element.text = `git fetch http://gerrit@localhost:8080/a/test-project
         refs/changes/05/5/1 && git checkout FETCH_HEAD`;
     flushAsynchronousOperations();
@@ -58,4 +44,4 @@
     assert.isTrue(focusStub.called);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js
index b560c56..94691d5 100644
--- a/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-storage/gr-storage_test.js
@@ -1,38 +1,25 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-storage</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-storage></gr-storage>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-storage.js';
+
+const basicFixture = fixtureFromElement('gr-storage');
+
 suite('gr-storage tests', () => {
   let element;
   let sandbox;
@@ -50,7 +37,7 @@
   }
 
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox = sinon.sandbox.create();
     element._storage = mockStorage();
   });
@@ -192,4 +179,4 @@
     assert.isNotOk(element._storage.getItem(computedKey));
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea_test.js b/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea_test.js
index bcf1207..693da27 100644
--- a/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-textarea/gr-textarea_test.js
@@ -1,58 +1,41 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-textarea</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-textarea></gr-textarea>
-  </template>
-</test-fixture>
-
-<test-fixture id="monospace">
-  <template>
-    <gr-textarea monospace="true"></gr-textarea>
-  </template>
-</test-fixture>
-
-<test-fixture id="hideBorder">
-  <template>
-    <gr-textarea hide-border="true"></gr-textarea>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-textarea.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromElement('gr-textarea');
+
+const monospaceFixture = fixtureFromTemplate(html`
+<gr-textarea monospace="true"></gr-textarea>
+`);
+
+const hideBorderFixture = fixtureFromTemplate(html`
+<gr-textarea hide-border="true"></gr-textarea>
+`);
+
 suite('gr-textarea tests', () => {
   let element;
   let sandbox;
 
   setup(() => {
     sandbox = sinon.sandbox.create();
-    element = fixture('basic');
+    element = basicFixture.instantiate();
     sandbox.stub(element.reporting, 'reportInteraction');
   });
 
@@ -339,7 +322,7 @@
 
     setup(() => {
       sandbox = sinon.sandbox.create();
-      element = fixture('monospace');
+      element = monospaceFixture.instantiate();
     });
 
     teardown(() => {
@@ -363,7 +346,7 @@
 
     setup(() => {
       sandbox = sinon.sandbox.create();
-      element = fixture('hideBorder');
+      element = hideBorderFixture.instantiate();
     });
 
     teardown(() => {
@@ -375,4 +358,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.js b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.js
index a8fc18a..f905eaa 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip-content/gr-tooltip-content_test.js
@@ -1,44 +1,34 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-storage</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-tooltip-content>
-    </gr-tooltip-content>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-tooltip-content.js';
 import {dom} from '@polymer/polymer/lib/legacy/polymer.dom.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-tooltip-content>
+    </gr-tooltip-content>
+`);
+
 suite('gr-tooltip-content tests', () => {
   let element;
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('icon is not visible by default', () => {
@@ -58,4 +48,4 @@
         .querySelector('iron-icon').hidden, false);
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.js b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.js
index b69d945..b5f068c 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.js
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.js
@@ -1,43 +1,33 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-storage</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-tooltip>
-    </gr-tooltip>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './gr-tooltip.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-tooltip>
+    </gr-tooltip>
+`);
+
 suite('gr-tooltip tests', () => {
   let element;
   setup(() => {
-    element = fixture('basic');
+    element = basicFixture.instantiate();
   });
 
   test('max-width is respected if set', () => {
@@ -63,4 +53,4 @@
         .display, 'none');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/elements/shared/revision-info/revision-info_test.js b/polygerrit-ui/app/elements/shared/revision-info/revision-info_test.js
index 2d89b30..7d0dd4f 100644
--- a/polygerrit-ui/app/elements/shared/revision-info/revision-info_test.js
+++ b/polygerrit-ui/app/elements/shared/revision-info/revision-info_test.js
@@ -1,32 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2017 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>revision-info</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<script type="module">
-import '../../../test/common-test-setup.js';
+import '../../../test/common-test-setup-karma.js';
 import './revision-info.js';
 import {RevisionInfo} from './revision-info.js';
 suite('revision-info tests', () => {
@@ -87,4 +76,4 @@
     assert.deepEqual(ri.getParentId(3, 0), 'p5');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/embed/gr-diff-app-context-init_test.js b/polygerrit-ui/app/embed/gr-diff-app-context-init_test.js
index 3aed13f..832c931 100644
--- a/polygerrit-ui/app/embed/gr-diff-app-context-init_test.js
+++ b/polygerrit-ui/app/embed/gr-diff-app-context-init_test.js
@@ -1,42 +1,35 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2020 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../test/common-test-setup-karma.js';
+import {appContext} from '../services/app-context.js';
+import {initDiffAppContext} from './gr-diff-app-context-init.js';
+suite('gr diff app context initializer tests', () => {
+  setup(() => {
+    initDiffAppContext();
+  });
 
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<script type="module">
-  import '../test/common-test-setup.js';
-  import {appContext} from '../services/app-context.js';
-  import {initDiffAppContext} from './gr-diff-app-context-init.js';
-  suite('gr diff app context initializer tests', () => {
-    setup(() => {
-      initDiffAppContext();
-    });
-
-    test('all services initialized and are singletons', () => {
-      Object.keys(appContext).forEach(serviceName => {
-        const service = appContext[serviceName];
-        assert.isNotNull(service);
-        const service2 = appContext[serviceName];
-        assert.strictEqual(service, service2);
-      });
+  test('all services initialized and are singletons', () => {
+    Object.keys(appContext).forEach(serviceName => {
+      const service = appContext[serviceName];
+      assert.isNotNull(service);
+      const service2 = appContext[serviceName];
+      assert.strictEqual(service, service2);
     });
   });
-</script>
\ No newline at end of file
+});
+
diff --git a/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils_test.js b/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils_test.js
index 818ddaa..94d96ad 100644
--- a/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils_test.js
+++ b/polygerrit-ui/app/scripts/gr-display-name-utils/gr-display-name-utils_test.js
@@ -1,31 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-display-name-utils</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {GrDisplayNameUtils} from './gr-display-name-utils.js';
 
 suite('gr-display-name-utils tests', () => {
@@ -200,4 +190,4 @@
     assert.equal(GrDisplayNameUtils._accountEmail(undefined), '');
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/scripts/gr-email-suggestions-provider/gr-email-suggestions-provider_test.js b/polygerrit-ui/app/scripts/gr-email-suggestions-provider/gr-email-suggestions-provider_test.js
index 80d3590..b0868a8 100644
--- a/polygerrit-ui/app/scripts/gr-email-suggestions-provider/gr-email-suggestions-provider_test.js
+++ b/polygerrit-ui/app/scripts/gr-email-suggestions-provider/gr-email-suggestions-provider_test.js
@@ -1,40 +1,28 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-email-suggestions-provider</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import '../../elements/shared/gr-rest-api-interface/gr-rest-api-interface.js';
 import {GrEmailSuggestionsProvider} from './gr-email-suggestions-provider.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
+`);
 
 suite('GrEmailSuggestionsProvider tests', () => {
   let sandbox;
@@ -55,7 +43,7 @@
     stub('gr-rest-api-interface', {
       getConfig() { return Promise.resolve({}); },
     });
-    restAPI = fixture('basic');
+    restAPI = basicFixture.instantiate();
     provider = new GrEmailSuggestionsProvider(restAPI);
   });
 
@@ -94,4 +82,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/scripts/gr-group-suggestions-provider/gr-group-suggestions-provider_test.js b/polygerrit-ui/app/scripts/gr-group-suggestions-provider/gr-group-suggestions-provider_test.js
index 2111b7e..dda9f7d 100644
--- a/polygerrit-ui/app/scripts/gr-group-suggestions-provider/gr-group-suggestions-provider_test.js
+++ b/polygerrit-ui/app/scripts/gr-group-suggestions-provider/gr-group-suggestions-provider_test.js
@@ -1,40 +1,28 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-group-suggestions-provider</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import '../../elements/shared/gr-rest-api-interface/gr-rest-api-interface.js';
 import {GrGroupSuggestionsProvider} from './gr-group-suggestions-provider.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
+`);
 
 suite('GrGroupSuggestionsProvider tests', () => {
   let sandbox;
@@ -56,7 +44,7 @@
     stub('gr-rest-api-interface', {
       getConfig() { return Promise.resolve({}); },
     });
-    restAPI = fixture('basic');
+    restAPI = basicFixture.instantiate();
     provider = new GrGroupSuggestionsProvider(restAPI);
   });
 
@@ -102,4 +90,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/scripts/gr-reviewer-suggestions-provider/gr-reviewer-suggestions-provider_test.js b/polygerrit-ui/app/scripts/gr-reviewer-suggestions-provider/gr-reviewer-suggestions-provider_test.js
index 8774d48..d3eed6b 100644
--- a/polygerrit-ui/app/scripts/gr-reviewer-suggestions-provider/gr-reviewer-suggestions-provider_test.js
+++ b/polygerrit-ui/app/scripts/gr-reviewer-suggestions-provider/gr-reviewer-suggestions-provider_test.js
@@ -1,41 +1,29 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-reviewer-suggestions-provider</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import '../../elements/shared/gr-rest-api-interface/gr-rest-api-interface.js';
 import {GrDisplayNameUtils} from '../gr-display-name-utils/gr-display-name-utils.js';
 import {GrReviewerSuggestionsProvider, SUGGESTIONS_PROVIDERS_USERS_TYPES} from './gr-reviewer-suggestions-provider.js';
+import {html} from '@polymer/polymer/lib/utils/html-tag.js';
+
+const basicFixture = fixtureFromTemplate(html`
+<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
+`);
 
 suite('GrReviewerSuggestionsProvider tests', () => {
   let sandbox;
@@ -91,7 +79,7 @@
       getConfig() { return Promise.resolve({}); },
     });
 
-    restAPI = fixture('basic');
+    restAPI = basicFixture.instantiate();
     change = {
       _number: 42,
       owner,
@@ -258,4 +246,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/services/app-context-init_test.js b/polygerrit-ui/app/services/app-context-init_test.js
index f5dc7d1..9d22ec2 100644
--- a/polygerrit-ui/app/services/app-context-init_test.js
+++ b/polygerrit-ui/app/services/app-context-init_test.js
@@ -1,43 +1,35 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2020 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../test/common-test-setup-karma.js';
+import {appContext} from './app-context.js';
+import {initAppContext} from './app-context-init.js';
+suite('app context initializer tests', () => {
+  setup(() => {
+    initAppContext();
+  });
 
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<script type="module">
-  import '../test/common-test-setup.js';
-  import {appContext} from './app-context.js';
-  import {initAppContext} from './app-context-init.js';
-  suite('app context initializer tests', () => {
-    setup(() => {
-      initAppContext();
-    });
-
-    test('all services initialized and are singletons', () => {
-      Object.keys(appContext).forEach(serviceName => {
-        const service = appContext[serviceName];
-        assert.isNotNull(service);
-        const service2 = appContext[serviceName];
-        assert.strictEqual(service, service2);
-      });
+  test('all services initialized and are singletons', () => {
+    Object.keys(appContext).forEach(serviceName => {
+      const service = appContext[serviceName];
+      assert.isNotNull(service);
+      const service2 = appContext[serviceName];
+      assert.strictEqual(service, service2);
     });
   });
-</script>
\ No newline at end of file
+});
+
diff --git a/polygerrit-ui/app/services/flags_test.js b/polygerrit-ui/app/services/flags_test.js
index 51efb0d..ae1033e 100644
--- a/polygerrit-ui/app/services/flags_test.js
+++ b/polygerrit-ui/app/services/flags_test.js
@@ -1,44 +1,44 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2020 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
+import '../test/common-test-setup-karma.js';
+import {FlagsService} from './flags.js';
 
-http://www.apache.org/licenses/LICENSE-2.0
+suite('flags tests', () => {
+  let originalEnabledExperiments;
+  let flags;
 
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<script>
-  window.ENABLED_EXPERIMENTS = ['a', 'a'];
-</script>
-
-<script type="module">
-  import '../test/common-test-setup.js';
-  import {FlagsService} from './flags.js';
-  suite('flags tests', () => {
-    const flags = new FlagsService();
-
-    test('isEnabled', () => {
-      assert.equal(flags.isEnabled('a'), true);
-      assert.equal(flags.isEnabled('random'), false);
-    });
-
-    test('enabledExperiments', () => {
-      assert.deepEqual(flags.enabledExperiments, ['a']);
-    });
+  suiteSetup(() => {
+    originalEnabledExperiments = window.ENABLED_EXPERIMENTS;
+    window.ENABLED_EXPERIMENTS = ['a', 'a'];
+    flags = new FlagsService();
   });
-</script>
\ No newline at end of file
+
+  suiteTeardown(() => {
+    window.ENABLED_EXPERIMENTS = originalEnabledExperiments;
+  });
+
+  test('isEnabled', () => {
+    assert.equal(flags.isEnabled('a'), true);
+    assert.equal(flags.isEnabled('random'), false);
+  });
+
+  test('enabledExperiments', () => {
+    assert.deepEqual(flags.enabledExperiments, ['a']);
+  });
+});
+
diff --git a/polygerrit-ui/app/services/gr-event-interface/gr-event-interface_test.js b/polygerrit-ui/app/services/gr-event-interface/gr-event-interface_test.js
index ef2c539..4830b17 100644
--- a/polygerrit-ui/app/services/gr-event-interface/gr-event-interface_test.js
+++ b/polygerrit-ui/app/services/gr-event-interface/gr-event-interface_test.js
@@ -1,40 +1,27 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2019 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-api-interface</title>
-
-<script src="../../../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<test-fixture id="basic">
-  <template>
-    <gr-js-api-interface></gr-js-api-interface>
-  </template>
-</test-fixture>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import '../../elements/shared/gr-js-api-interface/gr-js-api-interface.js';
 import {EventEmitter} from './gr-event-interface.js';
 import {_testOnly_initGerritPluginApi} from '../../elements/shared/gr-js-api-interface/gr-gerrit.js';
 
+const basicFixture = fixtureFromElement('gr-js-api-interface');
+
 const pluginApi = _testOnly_initGerritPluginApi();
 
 suite('gr-event-interface tests', () => {
@@ -50,7 +37,7 @@
 
   suite('test on Gerrit', () => {
     setup(() => {
-      fixture('basic');
+      basicFixture.instantiate();
       pluginApi.removeAllListeners();
     });
 
@@ -149,4 +136,4 @@
     });
   });
 });
-</script>
+
diff --git a/polygerrit-ui/app/services/gr-reporting/gr-reporting_mock_test.js b/polygerrit-ui/app/services/gr-reporting/gr-reporting_mock_test.js
index e33a214..7c70e10 100644
--- a/polygerrit-ui/app/services/gr-reporting/gr-reporting_mock_test.js
+++ b/polygerrit-ui/app/services/gr-reporting/gr-reporting_mock_test.js
@@ -1,39 +1,32 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2020 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-elements-es5-adapter.js"></script>
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<script type="module">
-  import '../../test/common-test-setup.js';
-  import {GrReporting} from './gr-reporting.js';
-  import {grReportingMock} from './gr-reporting_mock.js';
-  suite('gr-reporting_mock tests', () => {
-    test('mocks all public methods', () => {
-      const methods = Object.getOwnPropertyNames(GrReporting.prototype)
-          .filter(name => typeof GrReporting.prototype[name] === 'function')
-          .filter(name => !name.startsWith('_') && name !== 'constructor')
-          .sort();
-      const mockMethods = Object.getOwnPropertyNames(grReportingMock)
-          .sort();
-      assert.deepEqual(methods, mockMethods);
-    });
+import '../../test/common-test-setup-karma.js';
+import {GrReporting} from './gr-reporting.js';
+import {grReportingMock} from './gr-reporting_mock.js';
+suite('gr-reporting_mock tests', () => {
+  test('mocks all public methods', () => {
+    const methods = Object.getOwnPropertyNames(GrReporting.prototype)
+        .filter(name => typeof GrReporting.prototype[name] === 'function')
+        .filter(name => !name.startsWith('_') && name !== 'constructor')
+        .sort();
+    const mockMethods = Object.getOwnPropertyNames(grReportingMock)
+        .sort();
+    assert.deepEqual(methods, mockMethods);
   });
-</script>
\ No newline at end of file
+});
+
diff --git a/polygerrit-ui/app/services/gr-reporting/gr-reporting_test.js b/polygerrit-ui/app/services/gr-reporting/gr-reporting_test.js
index e309c8c..bd19c0b 100644
--- a/polygerrit-ui/app/services/gr-reporting/gr-reporting_test.js
+++ b/polygerrit-ui/app/services/gr-reporting/gr-reporting_test.js
@@ -1,32 +1,21 @@
-<!DOCTYPE html>
-<!--
-@license
-Copyright (C) 2016 The Android Open Source Project
+/**
+ * @license
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
-<meta charset="utf-8">
-<title>gr-reporting</title>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/custom-services-es5-adapter.js"></script>
-
-<script src="/node_modules/@webcomponents/webcomponentsjs/webcomponents-lite.js"></script>
-<script src="/components/wct-browser-legacy/browser.js"></script>
-
-<script type="module">
-import '../../test/common-test-setup.js';
+import '../../test/common-test-setup-karma.js';
 import {GrReporting, DEFAULT_STARTUP_TIMERS, initErrorReporter} from './gr-reporting.js';
 import {appContext} from '../app-context.js';
 suite('gr-reporting tests', () => {
@@ -510,4 +499,4 @@
     });
   });
 });
-</script>
+