Merge "Null-terminate passwords by default before hashing them"
diff --git a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html
index 78694b7..2a3044e 100644
--- a/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-access-section/gr-access-section_test.html
@@ -536,7 +536,8 @@
         test('removing an added permission', () => {
           element.editing = true;
           assert.equal(element._permissions.length, 1);
-          element.$$('gr-permission').fire('added-permission-removed');
+          element.shadowRoot
+              .querySelector('gr-permission').fire('added-permission-removed');
           flushAsynchronousOperations();
           assert.equal(element._permissions.length, 0);
         });
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html
index 098ef14..c0558d2 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list_test.html
@@ -163,7 +163,8 @@
     suite('create new', () => {
       test('_handleCreateClicked called when create-click fired', () => {
         sandbox.stub(element, '_handleCreateClicked');
-        element.$$('gr-list-view').fire('create-clicked');
+        element.shadowRoot
+            .querySelector('gr-list-view').fire('create-clicked');
         assert.isTrue(element._handleCreateClicked.called);
       });
 
diff --git a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
index 8436cf1..416099d 100644
--- a/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-admin-view/gr-admin-view_test.html
@@ -95,8 +95,10 @@
       flushAsynchronousOperations();
       assert.equal(Polymer.dom(element.root).querySelectorAll(
           '.selected').length, 1);
-      assert.ok(element.$$('gr-repo-list'));
-      assert.isNotOk(element.$$('gr-admin-create-repo'));
+      assert.ok(element.shadowRoot
+          .querySelector('gr-repo-list'));
+      assert.isNotOk(element.shadowRoot
+          .querySelector('gr-admin-create-repo'));
     });
 
     test('_filteredLinks admin', done => {
@@ -203,7 +205,8 @@
         flushAsynchronousOperations();
         assert.equal(Polymer.dom(element.root)
             .querySelectorAll('.sectionTitle').length, 3);
-        assert.equal(element.$$('.breadcrumbText').innerText, 'Test Repo');
+        assert.equal(element.shadowRoot
+            .querySelector('.breadcrumbText').innerText, 'Test Repo');
         assert.equal(
             element.shadowRoot.querySelector('#pageSelect').items.length,
             6
@@ -297,11 +300,13 @@
       element.params = {group: 1, view: Gerrit.Nav.View.GROUP};
       element._groupName = 'oldName';
       flushAsynchronousOperations();
-      element.$$('gr-group').fire('name-changed', {name: newName});
+      element.shadowRoot
+          .querySelector('gr-group').fire('name-changed', {name: newName});
     });
 
     test('dropdown displays if there is a subsection', () => {
-      assert.isNotOk(element.$$('.mainHeader'));
+      assert.isNotOk(element.shadowRoot
+          .querySelector('.mainHeader'));
       element._subsectionLinks = [
         {
           text: 'Home',
@@ -313,11 +318,13 @@
         },
       ];
       flushAsynchronousOperations();
-      assert.isOk(element.$$('.mainHeader'));
+      assert.isOk(element.shadowRoot
+          .querySelector('.mainHeader'));
       element._subsectionLinks = undefined;
       flushAsynchronousOperations();
       assert.equal(
-          getComputedStyle(element.$$('.mainHeader')).display,
+          getComputedStyle(element.shadowRoot
+              .querySelector('.mainHeader')).display,
           'none');
     });
 
@@ -521,7 +528,8 @@
             openCreateModal: false,
           };
           flushAsynchronousOperations();
-          const selected = element.$$('gr-page-nav .selected');
+          const selected = element.shadowRoot
+              .querySelector('gr-page-nav .selected');
           assert.isOk(selected);
           assert.equal(selected.textContent.trim(), 'Repositories');
         });
@@ -534,7 +542,8 @@
           element._repoName = 'foo';
           return element.reload().then(() => {
             flushAsynchronousOperations();
-            const selected = element.$$('gr-page-nav .selected');
+            const selected = element.shadowRoot
+                .querySelector('gr-page-nav .selected');
             assert.isOk(selected);
             assert.equal(selected.textContent.trim(), 'foo');
           });
@@ -549,7 +558,8 @@
           element._repoName = 'foo';
           return element.reload().then(() => {
             flushAsynchronousOperations();
-            const selected = element.$$('gr-page-nav .selected');
+            const selected = element.shadowRoot
+                .querySelector('gr-page-nav .selected');
             assert.isOk(selected);
             assert.equal(selected.textContent.trim(), 'Access');
           });
@@ -564,7 +574,8 @@
           element._repoName = 'foo';
           return element.reload().then(() => {
             flushAsynchronousOperations();
-            const selected = element.$$('gr-page-nav .selected');
+            const selected = element.shadowRoot
+                .querySelector('gr-page-nav .selected');
             assert.isOk(selected);
             assert.equal(selected.textContent.trim(), 'Dashboards');
           });
@@ -597,7 +608,8 @@
             openCreateModal: false,
           };
           flushAsynchronousOperations();
-          const selected = element.$$('gr-page-nav .selected');
+          const selected = element.shadowRoot
+              .querySelector('gr-page-nav .selected');
           assert.isOk(selected);
           assert.equal(selected.textContent.trim(), 'Groups');
         });
@@ -614,7 +626,8 @@
                 .querySelectorAll('.subsectionItem');
             assert.equal(subsectionItems.length, 2);
             assert.isTrue(element._groupIsInternal);
-            const selected = element.$$('gr-page-nav .selected');
+            const selected = element.shadowRoot
+                .querySelector('gr-page-nav .selected');
             assert.isOk(selected);
             assert.equal(selected.textContent.trim(), 'foo');
           });
@@ -638,7 +651,8 @@
                 .querySelectorAll('.subsectionItem');
             assert.equal(subsectionItems.length, 0);
             assert.isFalse(element._groupIsInternal);
-            const selected = element.$$('gr-page-nav .selected');
+            const selected = element.shadowRoot
+                .querySelector('gr-page-nav .selected');
             assert.isOk(selected);
             assert.equal(selected.textContent.trim(), 'foo');
           });
@@ -653,7 +667,8 @@
           element._groupName = 'foo';
           return element.reload().then(() => {
             flushAsynchronousOperations();
-            const selected = element.$$('gr-page-nav .selected');
+            const selected = element.shadowRoot
+                .querySelector('gr-page-nav .selected');
             assert.isOk(selected);
             assert.equal(selected.textContent.trim(), 'Members');
           });
diff --git a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html
index 6919d3c..b937e76 100644
--- a/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-confirm-delete-item-dialog/gr-confirm-delete-item-dialog_test.html
@@ -54,7 +54,8 @@
       const confirmHandler = sandbox.stub();
       element.addEventListener('confirm', confirmHandler);
       sandbox.spy(element, '_handleConfirmTap');
-      element.$$('gr-dialog').fire('confirm');
+      element.shadowRoot
+          .querySelector('gr-dialog').fire('confirm');
       assert.isTrue(confirmHandler.called);
       assert.isTrue(confirmHandler.calledOnce);
       assert.isTrue(element._handleConfirmTap.called);
@@ -65,7 +66,8 @@
       const cancelHandler = sandbox.stub();
       element.addEventListener('cancel', cancelHandler);
       sandbox.spy(element, '_handleCancelTap');
-      element.$$('gr-dialog').fire('cancel');
+      element.shadowRoot
+          .querySelector('gr-dialog').fire('cancel');
       assert.isTrue(cancelHandler.called);
       assert.isTrue(cancelHandler.calledOnce);
       assert.isTrue(element._handleCancelTap.called);
diff --git a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
index 80c05d3..f3c1e4f 100644
--- a/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-permission/gr-permission_test.html
@@ -345,7 +345,8 @@
         element.groups = {};
         element.$.groupAutocomplete.text = 'new group name';
         assert.equal(element._rules.length, 2);
-        element.$$('gr-rule-editor').fire('added-rule-removed');
+        element.shadowRoot
+            .querySelector('gr-rule-editor').fire('added-rule-removed');
         flushAsynchronousOperations();
         assert.equal(element._rules.length, 1);
       });
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html
index fa06437..2fc31f7 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-access/gr-repo-access_test.html
@@ -158,15 +158,17 @@
         assert.deepEqual(element._sections,
             element.toSortedArray(accessRes.local));
         assert.deepEqual(element._labels, repoRes.labels);
-        assert.equal(getComputedStyle(element.$$('.weblinks')).display,
-            'block');
+        assert.equal(getComputedStyle(element.shadowRoot
+            .querySelector('.weblinks')).display,
+        'block');
         return element._repoChanged('Another New Repo');
       })
           .then(() => {
             assert.deepEqual(element._sections,
                 element.toSortedArray(accessRes2.local));
-            assert.equal(getComputedStyle(element.$$('.weblinks')).display,
-                'none');
+            assert.equal(getComputedStyle(element.shadowRoot
+                .querySelector('.weblinks')).display,
+            'none');
             done();
           });
     });
@@ -332,7 +334,8 @@
       test('removing an added section', () => {
         element.editing = true;
         assert.equal(element._sections.length, 1);
-        element.$$('gr-access-section').fire('added-section-removed');
+        element.shadowRoot
+            .querySelector('gr-access-section').fire('added-section-removed');
         flushAsynchronousOperations();
         assert.equal(element._sections.length, 0);
       });
@@ -581,7 +584,9 @@
           remove: {},
         };
 
-        element.$$('gr-access-section').$$('gr-permission')
+        element.shadowRoot
+            .querySelector('gr-access-section').shadowRoot
+            .querySelector('gr-permission')
             ._handleAddRuleItem(
                 {detail: {value: {id: 'Maintainers'}}});
 
@@ -651,7 +656,8 @@
           },
           remove: {},
         };
-        element.$$('gr-access-section')._handleAddPermission();
+        element.shadowRoot
+            .querySelector('gr-access-section')._handleAddPermission();
         flushAsynchronousOperations();
         assert.deepEqual(element._computeAddAndRemove(), expectedInput);
 
@@ -678,7 +684,8 @@
           remove: {},
         };
         const newPermission =
-            Polymer.dom(element.$$('gr-access-section').root).querySelectorAll(
+            Polymer.dom(element.shadowRoot
+                .querySelector('gr-access-section').root).querySelectorAll(
                 'gr-permission')[2];
         newPermission._handleAddRuleItem(
             {detail: {value: {id: 'Maintainers'}}});
@@ -799,8 +806,9 @@
           remove: {},
         };
 
-        newSection.$$('gr-permission')._handleAddRuleItem(
-            {detail: {value: {id: 'Maintainers'}}});
+        newSection.shadowRoot
+            .querySelector('gr-permission')._handleAddRuleItem(
+                {detail: {value: {id: 'Maintainers'}}});
 
         flushAsynchronousOperations();
         assert.deepEqual(element._computeAddAndRemove(), expectedInput);
@@ -911,7 +919,8 @@
 
         // Add a rule to the existing permission;
         const readPermission =
-            Polymer.dom(element.$$('gr-access-section').root).querySelectorAll(
+            Polymer.dom(element.shadowRoot
+                .querySelector('gr-access-section').root).querySelectorAll(
                 'gr-permission')[1];
         readPermission._handleAddRuleItem(
             {detail: {value: {id: 'Maintainers'}}});
@@ -988,8 +997,9 @@
             .querySelectorAll('gr-access-section')[1];
         newSection._handleAddPermission();
         flushAsynchronousOperations();
-        newSection.$$('gr-permission')._handleAddRuleItem(
-            {detail: {value: {id: 'Maintainers'}}});
+        newSection.shadowRoot
+            .querySelector('gr-permission')._handleAddRuleItem(
+                {detail: {value: {id: 'Maintainers'}}});
         // Modify a the reference from the default value.
         element._local['refs/for/*'].updatedId = 'refs/for/new';
 
@@ -1061,8 +1071,9 @@
             .querySelectorAll('gr-access-section')[2];
         newSection._handleAddPermission();
         flushAsynchronousOperations();
-        newSection.$$('gr-permission')._handleAddRuleItem(
-            {detail: {value: {id: 'Maintainers'}}});
+        newSection.shadowRoot
+            .querySelector('gr-permission')._handleAddRuleItem(
+                {detail: {value: {id: 'Maintainers'}}});
         // Modify a the reference from the default value.
         element._local['refs/for/**'].updatedId = 'refs/for/new2';
         expectedInput = {
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.html b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.html
index 830660b..da8b57f 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-commands/gr-repo-commands_test.html
@@ -94,7 +94,8 @@
       test('successful creation of change', () => {
         const change = {_number: '1'};
         createChangeStub.returns(Promise.resolve(change));
-        MockInteractions.tap(element.$.editRepoConfig.$$('gr-button'));
+        MockInteractions.tap(element.$.editRepoConfig.shadowRoot
+            .querySelector('gr-button'));
         return handleSpy.lastCall.returnValue.then(() => {
           flushAsynchronousOperations();
 
@@ -109,7 +110,8 @@
 
       test('unsuccessful creation of change', () => {
         createChangeStub.returns(Promise.resolve(null));
-        MockInteractions.tap(element.$.editRepoConfig.$$('gr-button'));
+        MockInteractions.tap(element.$.editRepoConfig.shadowRoot
+            .querySelector('gr-button'));
         return handleSpy.lastCall.returnValue.then(() => {
           flushAsynchronousOperations();
 
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.html b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.html
index 1f10a97..d466f28 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-detail-list/gr-repo-detail-list_test.html
@@ -511,7 +511,8 @@
       suite('create new', () => {
         test('_handleCreateClicked called when create-click fired', () => {
           sandbox.stub(element, '_handleCreateClicked');
-          element.$$('gr-list-view').fire('create-clicked');
+          element.shadowRoot
+              .querySelector('gr-list-view').fire('create-clicked');
           assert.isTrue(element._handleCreateClicked.called);
         });
 
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html
index 64215e2..4003b15 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list_test.html
@@ -174,7 +174,8 @@
     suite('create new', () => {
       test('_handleCreateClicked called when create-click fired', () => {
         sandbox.stub(element, '_handleCreateClicked');
-        element.$$('gr-list-view').fire('create-clicked');
+        element.shadowRoot
+            .querySelector('gr-list-view').fire('create-clicked');
         assert.isTrue(element._handleCreateClicked.called);
       });
 
diff --git a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html
index d0a7a66..8313edf 100644
--- a/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html
+++ b/polygerrit-ui/app/elements/admin/gr-repo-plugin-config/gr-repo-plugin-config_test.html
@@ -100,7 +100,8 @@
         };
         flushAsynchronousOperations();
 
-        const editor = element.$$('gr-plugin-config-array-editor');
+        const editor = element.shadowRoot
+            .querySelector('gr-plugin-config-array-editor');
         assert.ok(editor);
         element._handleArrayChange({detail: 'test'});
         assert.isTrue(changeStub.called);
@@ -114,7 +115,8 @@
         };
         flushAsynchronousOperations();
 
-        const toggle = element.$$('paper-toggle-button');
+        const toggle = element.shadowRoot
+            .querySelector('paper-toggle-button');
         assert.ok(toggle);
         toggle.click();
         flushAsynchronousOperations();
@@ -132,7 +134,8 @@
         };
         flushAsynchronousOperations();
 
-        const input = element.$$('input');
+        const input = element.shadowRoot
+            .querySelector('input');
         assert.ok(input);
         input.value = 'newTest';
         input.dispatchEvent(new Event('input'));
@@ -152,7 +155,8 @@
         };
         flushAsynchronousOperations();
 
-        const select = element.$$('select');
+        const select = element.shadowRoot
+            .querySelector('select');
         assert.ok(select);
         select.value = 'newTest';
         select.dispatchEvent(new Event(
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
index 41f422a..076c478 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list-item/gr-change-list-item_test.html
@@ -139,9 +139,11 @@
 
       for (const column of element.columnNames) {
         const elementClass = '.' + column.toLowerCase();
-        assert.isOk(element.$$(elementClass),
-            `Expect ${elementClass} element to be found`);
-        assert.isFalse(element.$$(elementClass).hidden);
+        assert.isOk(element.shadowRoot
+            .querySelector(elementClass),
+        `Expect ${elementClass} element to be found`);
+        assert.isFalse(element.shadowRoot
+            .querySelector(elementClass).hidden);
       }
     });
 
@@ -161,9 +163,11 @@
       for (const column of element.columnNames) {
         const elementClass = '.' + column.toLowerCase();
         if (column === 'Repo') {
-          assert.isTrue(element.$$(elementClass).hidden);
+          assert.isTrue(element.shadowRoot
+              .querySelector(elementClass).hidden);
         } else {
-          assert.isFalse(element.$$(elementClass).hidden);
+          assert.isFalse(element.shadowRoot
+              .querySelector(elementClass).hidden);
         }
       }
     });
@@ -175,14 +179,17 @@
 
       flushAsynchronousOperations();
       const elementClass = '.bad';
-      assert.isNotOk(element.$$(elementClass));
+      assert.isNotOk(element.shadowRoot
+          .querySelector(elementClass));
     });
 
     test('assignee only displayed if there is one', () => {
       element.change = {};
       flushAsynchronousOperations();
-      assert.isNotOk(element.$$('.assignee gr-account-link'));
-      assert.equal(element.$$('.assignee').textContent.trim(), '--');
+      assert.isNotOk(element.shadowRoot
+          .querySelector('.assignee gr-account-link'));
+      assert.equal(element.shadowRoot
+          .querySelector('.assignee').textContent.trim(), '--');
       element.change = {
         assignee: {
           name: 'test',
@@ -190,7 +197,8 @@
         },
       };
       flushAsynchronousOperations();
-      assert.isOk(element.$$('.assignee gr-account-link'));
+      assert.isOk(element.shadowRoot
+          .querySelector('.assignee gr-account-link'));
     });
 
     test('TShirt sizing tooltip', () => {
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
index 8fd4214..30df8fd 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list.js
@@ -378,7 +378,8 @@
       }
 
       const changeEl = changeEls[index];
-      changeEl.$$('gr-change-star').toggleStar();
+      changeEl.shadowRoot
+          .querySelector('gr-change-star').toggleStar();
     }
 
     _changeForIndex(index) {
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
index 8e48dc2..23a5046 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.html
@@ -347,7 +347,8 @@
       test('all columns visible', () => {
         for (const column of element.columnNames) {
           const elementClass = '.' + element._lowerCase(column);
-          assert.isFalse(element.$$(elementClass).hidden);
+          assert.isFalse(element.shadowRoot
+              .querySelector(elementClass).hidden);
         }
       });
     });
@@ -381,7 +382,8 @@
       test('all columns visible', () => {
         for (const column of element.changeTableColumns) {
           const elementClass = '.' + element._lowerCase(column);
-          assert.isFalse(element.$$(elementClass).hidden);
+          assert.isFalse(element.shadowRoot
+              .querySelector(elementClass).hidden);
         }
       });
     });
@@ -415,9 +417,11 @@
         for (const column of element.changeTableColumns) {
           const elementClass = '.' + column.toLowerCase();
           if (column === 'Repo') {
-            assert.isTrue(element.$$(elementClass).hidden);
+            assert.isTrue(element.shadowRoot
+                .querySelector(elementClass).hidden);
           } else {
-            assert.isFalse(element.$$(elementClass).hidden);
+            assert.isFalse(element.shadowRoot
+                .querySelector(elementClass).hidden);
           }
         }
       });
@@ -443,7 +447,8 @@
 
       test('bad column does not exist', () => {
         const elementClass = '.bad';
-        assert.isNotOk(element.$$(elementClass));
+        assert.isNotOk(element.shadowRoot
+            .querySelector(elementClass));
       });
     });
 
diff --git a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html
index fd8efe2..abc4a9b 100644
--- a/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-create-change-help/gr-create-change-help_test.html
@@ -48,7 +48,8 @@
 
     test('Create change tap', done => {
       element.addEventListener('create-tap', () => done());
-      MockInteractions.tap(element.$$('gr-button'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('gr-button'));
     });
   });
 </script>
diff --git a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
index fbc2c78..3d83e99 100644
--- a/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
+++ b/polygerrit-ui/app/elements/change-list/gr-dashboard-view/gr-dashboard-view_test.html
@@ -103,11 +103,13 @@
       test('_showDraftsBanner', () => {
         element._showDraftsBanner = false;
         flushAsynchronousOperations();
-        assert.isTrue(isHidden(element.$$('.banner')));
+        assert.isTrue(isHidden(element.shadowRoot
+            .querySelector('.banner')));
 
         element._showDraftsBanner = true;
         flushAsynchronousOperations();
-        assert.isFalse(isHidden(element.$$('.banner')));
+        assert.isFalse(isHidden(element.shadowRoot
+            .querySelector('.banner')));
       });
 
       test('delete tap opens dialog', () => {
@@ -115,7 +117,8 @@
         element._showDraftsBanner = true;
         flushAsynchronousOperations();
 
-        MockInteractions.tap(element.$$('.banner .delete'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.banner .delete'));
         assert.isTrue(element._handleOpenDeleteDialog.called);
       });
 
@@ -330,12 +333,14 @@
       flushAsynchronousOperations();
 
       assert.equal(element.$.emptyOutgoing.textContent.trim(), 'No changes');
-      assert.isNotOk(element.$$('gr-create-change-help'));
+      assert.isNotOk(element.shadowRoot
+          .querySelector('gr-create-change-help'));
       element._showNewUserHelp = true;
       flushAsynchronousOperations();
 
       assert.notEqual(element.$.emptyOutgoing.textContent.trim(), 'No changes');
-      assert.isOk(element.$$('gr-create-change-help'));
+      assert.isOk(element.shadowRoot
+          .querySelector('gr-create-change-help'));
     });
 
     test('_computeUserHeaderClass', () => {
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
index 2a76f27..12c6b58 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions.js
@@ -1254,7 +1254,8 @@
       }
 
       // Otherwise it's a top-level action.
-      const buttonEl = this.$$(`[data-action-key="${buttonKey}"]`);
+      const buttonEl = this.shadowRoot
+          .querySelector(`[data-action-key="${buttonKey}"]`);
       buttonEl.setAttribute('loading', true);
       buttonEl.disabled = true;
       return function() {
diff --git a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
index c669217..ee036cf 100644
--- a/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-actions/gr-change-actions_test.html
@@ -201,7 +201,8 @@
 
       test('hide revision action', done => {
         flush(() => {
-          const buttonEl = element.$$('[data-action-key="submit"]');
+          const buttonEl = element.shadowRoot
+              .querySelector('[data-action-key="submit"]');
           assert.isOk(buttonEl);
           assert.throws(element.setActionHidden.bind(element, 'invalid type'));
           element.setActionHidden(element.ActionType.REVISION,
@@ -211,13 +212,15 @@
               element.RevisionActions.SUBMIT, true);
           assert.lengthOf(element._hiddenActions, 1);
           flush(() => {
-            const buttonEl = element.$$('[data-action-key="submit"]');
+            const buttonEl = element.shadowRoot
+                .querySelector('[data-action-key="submit"]');
             assert.isNotOk(buttonEl);
 
             element.setActionHidden(element.ActionType.REVISION,
                 element.RevisionActions.SUBMIT, false);
             flush(() => {
-              const buttonEl = element.$$('[data-action-key="submit"]');
+              const buttonEl = element.shadowRoot
+                  .querySelector('[data-action-key="submit"]');
               assert.isOk(buttonEl);
               assert.isFalse(buttonEl.hasAttribute('hidden'));
               done();
@@ -294,7 +297,8 @@
         };
         element.latestPatchNum = '2';
 
-        const submitButton = element.$$('gr-button[data-action-key="submit"]');
+        const submitButton = element.shadowRoot
+            .querySelector('gr-button[data-action-key="submit"]');
         assert.ok(submitButton);
         MockInteractions.tap(submitButton);
 
@@ -318,7 +322,8 @@
         element.latestPatchNum = '2';
 
         const submitIcon =
-            element.$$('gr-button[data-action-key="submit"] iron-icon');
+            element.shadowRoot
+                .querySelector('gr-button[data-action-key="submit"] iron-icon');
         assert.ok(submitIcon);
         MockInteractions.tap(submitIcon);
       });
@@ -344,7 +349,8 @@
             () => false);
         const fireActionStub = sandbox.stub(element, '_fireAction');
         flush(() => {
-          const submitButton = element.$$('gr-button[data-action-key="submit"]');
+          const submitButton = element.shadowRoot
+              .querySelector('gr-button[data-action-key="submit"]');
           assert.ok(submitButton);
           MockInteractions.tap(submitButton);
           assert.equal(fireActionStub.callCount, 0);
@@ -386,7 +392,8 @@
             'fetchRecentChanges').returns(Promise.resolve([]));
         element._hasKnownChainState = true;
         flush(() => {
-          const rebaseButton = element.$$('gr-button[data-action-key="rebase"]');
+          const rebaseButton = element.shadowRoot
+              .querySelector('gr-button[data-action-key="rebase"]');
           MockInteractions.tap(rebaseButton);
           const rebaseAction = {
             __key: 'rebase',
@@ -410,7 +417,8 @@
         const fetchChangesStub = sandbox.stub(element.$.confirmRebase,
             'fetchRecentChanges').returns(Promise.resolve([]));
         element._hasKnownChainState = true;
-        const rebaseButton = element.$$('gr-button[data-action-key="rebase"]');
+        const rebaseButton = element.shadowRoot
+            .querySelector('gr-button[data-action-key="rebase"]');
         MockInteractions.tap(rebaseButton);
         assert.isTrue(fetchChangesStub.calledOnce);
 
@@ -425,7 +433,8 @@
       test('two dialogs are not shown at the same time', done => {
         element._hasKnownChainState = true;
         flush(() => {
-          const rebaseButton = element.$$('gr-button[data-action-key="rebase"]');
+          const rebaseButton = element.shadowRoot
+              .querySelector('gr-button[data-action-key="rebase"]');
           assert.ok(rebaseButton);
           MockInteractions.tap(rebaseButton);
           flushAsynchronousOperations();
@@ -474,11 +483,16 @@
           element.set('disableEdit', true);
           flushAsynchronousOperations();
 
-          assert.isNotOk(element.$$('gr-button[data-action-key="publishEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="rebaseEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="deleteEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="edit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="stopEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="publishEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="rebaseEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="deleteEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="edit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="stopEdit"]'));
         });
 
         test('shows confirm dialog for delete edit', () => {
@@ -491,7 +505,8 @@
           MockInteractions.tap(
               element.shadowRoot
                   .querySelector('#confirmDeleteEditDialog')
-                  .$$('gr-button[primary]'));
+                  .shadowRoot
+                  .querySelector('gr-button[primary]'));
           flushAsynchronousOperations();
 
           assert.equal(fireActionStub.lastCall.args[0], '/edit');
@@ -503,10 +518,14 @@
           element.change = {status: 'MERGED'};
           flushAsynchronousOperations();
 
-          assert.isNotOk(element.$$('gr-button[data-action-key="publishEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="rebaseEdit"]'));
-          assert.isOk(element.$$('gr-button[data-action-key="deleteEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="edit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="publishEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="rebaseEdit"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="deleteEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="edit"]'));
         });
 
         test('edit patchset is loaded, needs rebase', () => {
@@ -516,11 +535,16 @@
           element.editBasedOnCurrentPatchSet = false;
           flushAsynchronousOperations();
 
-          assert.isNotOk(element.$$('gr-button[data-action-key="publishEdit"]'));
-          assert.isOk(element.$$('gr-button[data-action-key="rebaseEdit"]'));
-          assert.isOk(element.$$('gr-button[data-action-key="deleteEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="edit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="stopEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="publishEdit"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="rebaseEdit"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="deleteEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="edit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="stopEdit"]'));
         });
 
         test('edit patchset is loaded, does not need rebase', () => {
@@ -530,11 +554,16 @@
           element.editBasedOnCurrentPatchSet = true;
           flushAsynchronousOperations();
 
-          assert.isOk(element.$$('gr-button[data-action-key="publishEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="rebaseEdit"]'));
-          assert.isOk(element.$$('gr-button[data-action-key="deleteEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="edit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="stopEdit"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="publishEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="rebaseEdit"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="deleteEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="edit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="stopEdit"]'));
         });
 
         test('edit mode is loaded, no edit patchset', () => {
@@ -543,11 +572,16 @@
           element.change = {status: 'NEW'};
           flushAsynchronousOperations();
 
-          assert.isNotOk(element.$$('gr-button[data-action-key="publishEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="rebaseEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="deleteEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="edit"]'));
-          assert.isOk(element.$$('gr-button[data-action-key="stopEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="publishEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="rebaseEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="deleteEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="edit"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="stopEdit"]'));
         });
 
         test('normal patch set', () => {
@@ -556,11 +590,16 @@
           element.change = {status: 'NEW'};
           flushAsynchronousOperations();
 
-          assert.isNotOk(element.$$('gr-button[data-action-key="publishEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="rebaseEdit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="deleteEdit"]'));
-          assert.isOk(element.$$('gr-button[data-action-key="edit"]'));
-          assert.isNotOk(element.$$('gr-button[data-action-key="stopEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="publishEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="rebaseEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="deleteEdit"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="edit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="stopEdit"]'));
         });
 
         test('edit action', done => {
@@ -569,17 +608,21 @@
           element.change = {status: 'NEW'};
           flushAsynchronousOperations();
 
-          assert.isNotOk(element.$$('gr-button[data-action-key="edit"]'));
-          assert.isOk(element.$$('gr-button[data-action-key="stopEdit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="edit"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="stopEdit"]'));
           element.change = {status: 'MERGED'};
           flushAsynchronousOperations();
 
-          assert.isNotOk(element.$$('gr-button[data-action-key="edit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('gr-button[data-action-key="edit"]'));
           element.change = {status: 'NEW'};
           element.set('editMode', false);
           flushAsynchronousOperations();
 
-          const editButton = element.$$('gr-button[data-action-key="edit"]');
+          const editButton = element.shadowRoot
+              .querySelector('gr-button[data-action-key="edit"]');
           assert.isOk(editButton);
           MockInteractions.tap(editButton);
         });
@@ -708,12 +751,14 @@
           assert.equal(e.detail.node.getAttribute('data-action-key'), key);
           element.removeActionButton(key);
           flush(() => {
-            assert.notOk(element.$$('[data-action-key="' + key + '"]'));
+            assert.notOk(element.shadowRoot
+                .querySelector('[data-action-key="' + key + '"]'));
             done();
           });
         });
         flush(() => {
-          MockInteractions.tap(element.$$('[data-action-key="' + key + '"]'));
+          MockInteractions.tap(element.shadowRoot
+              .querySelector('[data-action-key="' + key + '"]'));
         });
       });
 
@@ -723,7 +768,8 @@
         const cleanup = element._setLoadingOnButtonWithKey(type, key);
         assert.equal(element._actionLoadingMessage, 'Rebasing...');
 
-        const button = element.$$('[data-action-key="' + key + '"]');
+        const button = element.shadowRoot
+            .querySelector('[data-action-key="' + key + '"]');
         assert.isTrue(button.hasAttribute('loading'));
         assert.isTrue(button.disabled);
 
@@ -773,7 +819,8 @@
           element.$.confirmAbandonDialog.message = newAbandonMsg;
           flush(() => {
             const abandonButton =
-                element.$$('gr-button[data-action-key="abandon"]');
+                element.shadowRoot
+                    .querySelector('gr-button[data-action-key="abandon"]');
             MockInteractions.tap(abandonButton);
 
             assert.equal(element.$.confirmAbandonDialog.message, newAbandonMsg);
@@ -784,7 +831,8 @@
         test('abandon change with no message', done => {
           flush(() => {
             const abandonButton =
-                element.$$('gr-button[data-action-key="abandon"]');
+                element.shadowRoot
+                    .querySelector('gr-button[data-action-key="abandon"]');
             MockInteractions.tap(abandonButton);
 
             assert.isUndefined(element.$.confirmAbandonDialog.message);
@@ -795,7 +843,8 @@
         test('works', () => {
           element.$.confirmAbandonDialog.message = 'original message';
           const restoreButton =
-              element.$$('gr-button[data-action-key="abandon"]');
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key="abandon"]');
           MockInteractions.tap(restoreButton);
 
           element.$.confirmAbandonDialog.message = 'foo message';
@@ -1059,7 +1108,8 @@
         test('make sure the mark private change button is not outside of the ' +
              'overflow menu', done => {
           flush(() => {
-            assert.isNotOk(element.$$('[data-action-key="private"]'));
+            assert.isNotOk(element.shadowRoot
+                .querySelector('[data-action-key="private"]'));
             done();
           });
         });
@@ -1067,12 +1117,15 @@
         test('private change', done => {
           flush(() => {
             assert.isOk(
-                element.$.moreActions.$$('span[data-id="private-change"]'));
+                element.$.moreActions.shadowRoot
+                    .querySelector('span[data-id="private-change"]'));
             element.setActionOverflow('change', 'private', false);
             flushAsynchronousOperations();
-            assert.isOk(element.$$('[data-action-key="private"]'));
+            assert.isOk(element.shadowRoot
+                .querySelector('[data-action-key="private"]'));
             assert.isNotOk(
-                element.$.moreActions.$$('span[data-id="private-change"]'));
+                element.$.moreActions.shadowRoot
+                    .querySelector('span[data-id="private-change"]'));
             done();
           });
         });
@@ -1105,7 +1158,8 @@
         test('make sure the unmark private change button is not outside of the ' +
              'overflow menu', done => {
           flush(() => {
-            assert.isNotOk(element.$$('[data-action-key="private.delete"]'));
+            assert.isNotOk(element.shadowRoot
+                .querySelector('[data-action-key="private.delete"]'));
             done();
           });
         });
@@ -1113,13 +1167,16 @@
         test('unmark the private change', done => {
           flush(() => {
             assert.isOk(
-                element.$.moreActions.$$('span[data-id="private.delete-change"]')
+                element.$.moreActions.shadowRoot
+                    .querySelector('span[data-id="private.delete-change"]')
             );
             element.setActionOverflow('change', 'private.delete', false);
             flushAsynchronousOperations();
-            assert.isOk(element.$$('[data-action-key="private.delete"]'));
+            assert.isOk(element.shadowRoot
+                .querySelector('[data-action-key="private.delete"]'));
             assert.isNotOk(
-                element.$.moreActions.$$('span[data-id="private.delete-change"]')
+                element.$.moreActions.shadowRoot
+                    .querySelector('span[data-id="private.delete-change"]')
             );
             done();
           });
@@ -1158,7 +1215,8 @@
           MockInteractions.tap(
               element.shadowRoot
                   .querySelector('#confirmDeleteDialog')
-                  .$$('gr-button[primary]'));
+                  .shadowRoot
+                  .querySelector('gr-button[primary]'));
           flushAsynchronousOperations();
           assert.isTrue(fireActionStub.calledWith('/', deleteAction, false));
         });
@@ -1168,7 +1226,8 @@
           MockInteractions.tap(
               element.shadowRoot
                   .querySelector('#confirmDeleteDialog')
-                  .$$('gr-button:not([primary])'));
+                  .shadowRoot
+                  .querySelector('gr-button:not([primary])'));
           flushAsynchronousOperations();
           assert.isTrue(element.shadowRoot
               .querySelector('#confirmDeleteDialog').hidden);
@@ -1202,16 +1261,20 @@
 
         test('make sure the ignore button is not outside of the overflow menu',
             () => {
-              assert.isNotOk(element.$$('[data-action-key="ignore"]'));
+              assert.isNotOk(element.shadowRoot
+                  .querySelector('[data-action-key="ignore"]'));
             });
 
         test('ignoring change', () => {
-          assert.isOk(element.$.moreActions.$$('span[data-id="ignore-change"]'));
+          assert.isOk(element.$.moreActions.shadowRoot
+              .querySelector('span[data-id="ignore-change"]'));
           element.setActionOverflow('change', 'ignore', false);
           flushAsynchronousOperations();
-          assert.isOk(element.$$('[data-action-key="ignore"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('[data-action-key="ignore"]'));
           assert.isNotOk(
-              element.$.moreActions.$$('span[data-id="ignore-change"]'));
+              element.$.moreActions.shadowRoot
+                  .querySelector('span[data-id="ignore-change"]'));
         });
       });
 
@@ -1240,17 +1303,21 @@
         });
 
         test('unignore button is not outside of the overflow menu', () => {
-          assert.isNotOk(element.$$('[data-action-key="unignore"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('[data-action-key="unignore"]'));
         });
 
         test('unignoring change', () => {
           assert.isOk(
-              element.$.moreActions.$$('span[data-id="unignore-change"]'));
+              element.$.moreActions.shadowRoot
+                  .querySelector('span[data-id="unignore-change"]'));
           element.setActionOverflow('change', 'unignore', false);
           flushAsynchronousOperations();
-          assert.isOk(element.$$('[data-action-key="unignore"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('[data-action-key="unignore"]'));
           assert.isNotOk(
-              element.$.moreActions.$$('span[data-id="unignore-change"]'));
+              element.$.moreActions.shadowRoot
+                  .querySelector('span[data-id="unignore-change"]'));
         });
       });
 
@@ -1280,17 +1347,21 @@
 
         test('make sure the reviewed button is not outside of the overflow menu',
             () => {
-              assert.isNotOk(element.$$('[data-action-key="reviewed"]'));
+              assert.isNotOk(element.shadowRoot
+                  .querySelector('[data-action-key="reviewed"]'));
             });
 
         test('reviewing change', () => {
           assert.isOk(
-              element.$.moreActions.$$('span[data-id="reviewed-change"]'));
+              element.$.moreActions.shadowRoot
+                  .querySelector('span[data-id="reviewed-change"]'));
           element.setActionOverflow('change', 'reviewed', false);
           flushAsynchronousOperations();
-          assert.isOk(element.$$('[data-action-key="reviewed"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('[data-action-key="reviewed"]'));
           assert.isNotOk(
-              element.$.moreActions.$$('span[data-id="reviewed-change"]'));
+              element.$.moreActions.shadowRoot
+                  .querySelector('span[data-id="reviewed-change"]'));
         });
       });
 
@@ -1319,17 +1390,21 @@
         });
 
         test('unreviewed button not outside of the overflow menu', () => {
-          assert.isNotOk(element.$$('[data-action-key="unreviewed"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('[data-action-key="unreviewed"]'));
         });
 
         test('unreviewed change', () => {
           assert.isOk(
-              element.$.moreActions.$$('span[data-id="unreviewed-change"]'));
+              element.$.moreActions.shadowRoot
+                  .querySelector('span[data-id="unreviewed-change"]'));
           element.setActionOverflow('change', 'unreviewed', false);
           flushAsynchronousOperations();
-          assert.isOk(element.$$('[data-action-key="unreviewed"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('[data-action-key="unreviewed"]'));
           assert.isNotOk(
-              element.$.moreActions.$$('span[data-id="unreviewed-change"]'));
+              element.$.moreActions.shadowRoot
+                  .querySelector('span[data-id="unreviewed-change"]'));
         });
       });
 
@@ -1358,13 +1433,15 @@
 
         test('added when can approve', () => {
           const approveButton =
-              element.$$('gr-button[data-action-key=\'review\']');
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key=\'review\']');
           assert.isNotNull(approveButton);
         });
 
         test('hide quick approve', () => {
           const approveButton =
-              element.$$('gr-button[data-action-key=\'review\']');
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key=\'review\']');
           assert.isNotNull(approveButton);
           assert.isFalse(element._hideQuickApproveAction);
 
@@ -1372,7 +1449,8 @@
           element.hideQuickApproveAction();
           flushAsynchronousOperations();
           const approveButtonUpdated =
-              element.$$('gr-button[data-action-key=\'review\']');
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key=\'review\']');
           assert.isNull(approveButtonUpdated);
           assert.isTrue(element._hideQuickApproveAction);
         });
@@ -1398,7 +1476,8 @@
           };
           flushAsynchronousOperations();
           const approveButton =
-              element.$$('gr-button[data-action-key=\'review\']');
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key=\'review\']');
           assert.isNull(approveButton);
         });
 
@@ -1414,14 +1493,16 @@
           };
           flushAsynchronousOperations();
           const approveButton =
-              element.$$('gr-button[data-action-key=\'review\']');
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key=\'review\']');
           assert.isNull(approveButton);
         });
 
         test('approves when tapped', () => {
           const fireActionStub = sandbox.stub(element, '_fireAction');
           MockInteractions.tap(
-              element.$$('gr-button[data-action-key=\'review\']'));
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key=\'review\']'));
           flushAsynchronousOperations();
           assert.isTrue(fireActionStub.called);
           assert.isTrue(fireActionStub.calledWith('/review'));
@@ -1443,7 +1524,8 @@
           };
           flushAsynchronousOperations();
           const approveButton =
-              element.$$('gr-button[data-action-key=\'review\']');
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key=\'review\']');
           assert.isNull(approveButton);
         });
 
@@ -1466,7 +1548,8 @@
           };
           flushAsynchronousOperations();
           const approveButton =
-              element.$$('gr-button[data-action-key=\'review\']');
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key=\'review\']');
           assert.equal(approveButton.getAttribute('data-label'), 'foo+1');
         });
 
@@ -1489,7 +1572,8 @@
           };
           flushAsynchronousOperations();
           const approveButton =
-              element.$$('gr-button[data-action-key=\'review\']');
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key=\'review\']');
           assert.isNull(approveButton);
         });
 
@@ -1512,7 +1596,8 @@
           };
           flushAsynchronousOperations();
           const approveButton =
-              element.$$('gr-button[data-action-key=\'review\']');
+              element.shadowRoot
+                  .querySelector('gr-button[data-action-key=\'review\']');
           assert.equal(approveButton.getAttribute('data-label'), 'bar+2');
         });
       });
@@ -1545,21 +1630,25 @@
 
       suite('setActionOverflow', () => {
         test('move action from overflow', () => {
-          assert.isNotOk(element.$$('[data-action-key="cherrypick"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('[data-action-key="cherrypick"]'));
           assert.strictEqual(
               element.$.moreActions.items[0].id, 'cherrypick-revision');
           element.setActionOverflow('revision', 'cherrypick', false);
           flushAsynchronousOperations();
-          assert.isOk(element.$$('[data-action-key="cherrypick"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('[data-action-key="cherrypick"]'));
           assert.notEqual(
               element.$.moreActions.items[0].id, 'cherrypick-revision');
         });
 
         test('move action to overflow', () => {
-          assert.isOk(element.$$('[data-action-key="submit"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('[data-action-key="submit"]'));
           element.setActionOverflow('revision', 'submit', true);
           flushAsynchronousOperations();
-          assert.isNotOk(element.$$('[data-action-key="submit"]'));
+          assert.isNotOk(element.shadowRoot
+              .querySelector('[data-action-key="submit"]'));
           assert.strictEqual(
               element.$.moreActions.items[3].id, 'submit-revision');
         });
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
index 0f31f91..ea11514 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata.js
@@ -491,7 +491,7 @@
       if (this._topicReadOnly || this.change.topic) { return; }
       // Cannot use `this.$.ID` syntax because the element exists inside of a
       // dom-if.
-      this.$$('.topicEditableLabel').open();
+      this.shadowRoot.querySelector('.topicEditableLabel').open();
     }
 
     _getReviewerSuggestionsProvider(change) {
diff --git a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
index 0ae0898..055f3f0 100644
--- a/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-metadata/gr-change-metadata_test.html
@@ -109,7 +109,8 @@
     test('show strategy for open change', () => {
       element.change = {status: 'NEW', submit_type: 'CHERRY_PICK', labels: {}};
       flushAsynchronousOperations();
-      const strategy = element.$$('.strategy');
+      const strategy = element.shadowRoot
+          .querySelector('.strategy');
       assert.ok(strategy);
       assert.isFalse(strategy.hasAttribute('hidden'));
       assert.equal(strategy.children[1].innerHTML, 'Cherry Pick');
@@ -118,7 +119,8 @@
     test('hide strategy for closed change', () => {
       element.change = {status: 'MERGED', labels: {}};
       flushAsynchronousOperations();
-      assert.isTrue(element.$$('.strategy').hasAttribute('hidden'));
+      assert.isTrue(element.shadowRoot
+          .querySelector('.strategy').hasAttribute('hidden'));
     });
 
     test('weblinks use Gerrit.Nav interface', () => {
@@ -520,7 +522,9 @@
         element.account = {};
         element.change = change;
         flushAsynchronousOperations();
-        const button = element.$$('gr-linked-chip').$$('gr-button');
+        const button = element.shadowRoot
+            .querySelector('gr-linked-chip').shadowRoot
+            .querySelector('gr-button');
         assert.isTrue(button.hasAttribute('hidden'));
       });
 
@@ -529,7 +533,9 @@
         change.actions.topic.enabled = true;
         element.change = change;
         flushAsynchronousOperations();
-        const button = element.$$('gr-linked-chip').$$('gr-button');
+        const button = element.shadowRoot
+            .querySelector('gr-linked-chip').shadowRoot
+            .querySelector('gr-button');
         assert.isFalse(button.hasAttribute('hidden'));
       });
     });
@@ -574,7 +580,9 @@
         element.account = {};
         element.change = change;
         flushAsynchronousOperations();
-        const button = element.$$('gr-linked-chip').$$('gr-button');
+        const button = element.shadowRoot
+            .querySelector('gr-linked-chip').shadowRoot
+            .querySelector('gr-button');
         assert.isTrue(button.hasAttribute('hidden'));
       });
 
@@ -584,7 +592,9 @@
         change.actions.hashtags.enabled = true;
         element.change = change;
         flushAsynchronousOperations();
-        const button = element.$$('gr-linked-chip').$$('gr-button');
+        const button = element.shadowRoot
+            .querySelector('gr-linked-chip').shadowRoot
+            .querySelector('gr-button');
         assert.isFalse(button.hasAttribute('hidden'));
       });
     });
@@ -683,7 +693,8 @@
       test('topic removal', () => {
         sandbox.stub(element.$.restAPI, 'setChangeTopic').returns(
             Promise.resolve());
-        const chip = element.$$('gr-linked-chip');
+        const chip = element.shadowRoot
+            .querySelector('gr-linked-chip');
         const remove = chip.$.remove;
         const topicChangedSpy = sandbox.spy();
         element.addEventListener('topic-changed', topicChangedSpy);
@@ -720,7 +731,8 @@
       element.change = {actions: {topic: {enabled: true}}};
       flushAsynchronousOperations();
 
-      const label = element.$$('.topicEditableLabel');
+      const label = element.shadowRoot
+          .querySelector('.topicEditableLabel');
       assert.ok(label);
       sandbox.stub(label, 'open');
       element.editTopic();
diff --git a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html
index 6f0d0c7..10466db 100644
--- a/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-requirements/gr-change-requirements_test.html
@@ -101,12 +101,15 @@
       element._optionalLabels = [{label: 'test'}];
       flushAsynchronousOperations();
 
-      assert.ok(element.$$('section.optional'));
-      MockInteractions.tap(element.$$('.showHide'));
+      assert.ok(element.shadowRoot
+          .querySelector('section.optional'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('.showHide'));
       flushAsynchronousOperations();
 
       assert.isFalse(element._showOptionalLabels);
-      assert.isTrue(isHidden(element.$$('section.optional')));
+      assert.isTrue(isHidden(element.shadowRoot
+          .querySelector('section.optional')));
     });
 
     test('properly converts satisfied labels', () => {
@@ -121,9 +124,12 @@
       };
       flushAsynchronousOperations();
 
-      assert.ok(element.$$('.approved'));
-      assert.ok(element.$$('.name'));
-      assert.equal(element.$$('.name').text, 'Verified');
+      assert.ok(element.shadowRoot
+          .querySelector('.approved'));
+      assert.ok(element.shadowRoot
+          .querySelector('.name'));
+      assert.equal(element.shadowRoot
+          .querySelector('.name').text, 'Verified');
     });
 
     test('properly converts unsatisfied labels', () => {
@@ -137,7 +143,8 @@
       };
       flushAsynchronousOperations();
 
-      const name = element.$$('.name');
+      const name = element.shadowRoot
+          .querySelector('.name');
       assert.ok(name);
       assert.isFalse(name.hasAttribute('hidden'));
       assert.equal(name.text, 'Verified');
@@ -152,7 +159,8 @@
       };
       flushAsynchronousOperations();
 
-      const changeIsWip = element.$$('.title');
+      const changeIsWip = element.shadowRoot
+          .querySelector('.title');
       assert.ok(changeIsWip);
     });
 
@@ -167,7 +175,8 @@
       };
       flushAsynchronousOperations();
 
-      const requirement = element.$$('.requirement');
+      const requirement = element.shadowRoot
+          .querySelector('.requirement');
       assert.ok(requirement);
       assert.isFalse(requirement.hasAttribute('hidden'));
       assert.ok(requirement.querySelector('.approved'));
@@ -186,7 +195,8 @@
       };
       flushAsynchronousOperations();
 
-      const requirement = element.$$('.requirement');
+      const requirement = element.shadowRoot
+          .querySelector('.requirement');
       assert.ok(requirement);
       assert.ok(requirement.querySelector('.approved'));
     });
@@ -202,7 +212,8 @@
       };
       flushAsynchronousOperations();
 
-      const requirement = element.$$('.requirement');
+      const requirement = element.shadowRoot
+          .querySelector('.requirement');
       assert.ok(requirement);
       assert.strictEqual(requirement.querySelector('.approved'), null);
     });
@@ -218,7 +229,8 @@
       };
       flushAsynchronousOperations();
 
-      const requirement = element.$$('.requirement');
+      const requirement = element.shadowRoot
+          .querySelector('.requirement');
       assert.ok(requirement);
       assert.strictEqual(requirement.querySelector('.approved'), null);
     });
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
index 0a7e38e..58505ff 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.js
@@ -471,11 +471,11 @@
     }
 
     get messagesList() {
-      return this.$$('gr-messages-list');
+      return this.shadowRoot.querySelector('gr-messages-list');
     }
 
     get threadList() {
-      return this.$$('gr-thread-list');
+      return this.shadowRoot.querySelector('gr-thread-list');
     }
 
     /**
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
index ca2ab37..26bcbf2 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.html
@@ -725,26 +725,26 @@
 
       test('tab switch works correctly', done => {
         assert.isTrue(element._paramsChanged.called);
+        assert.equal(element.$.commentTabs.selected, CommentTabs.CHANGE_LOG);
+        assert.equal(element._currentView, CommentTabs.CHANGE_LOG);
 
-        // Wait for tab to get selected
+        const commentTab = element.shadowRoot.querySelector(
+            'paper-tab.commentThreads'
+        );
+        // Switch to comment thread tab
+        MockInteractions.tap(commentTab);
+        const commentTabs = element.$.commentTabs;
+        assert.equal(commentTabs.selected,
+            CommentTabs.COMMENT_THREADS);
+        assert.equal(element._currentView, CommentTabs.COMMENT_THREADS);
+
+        // Switch back to 'Change Log' tab
+        element._paramsChanged(element.params);
         flush(() => {
-          assert.equal(element.$.commentTabs.selected, CommentTabs.CHANGE_LOG);
+          assert.equal(commentTabs.selected,
+              CommentTabs.CHANGE_LOG);
           assert.equal(element._currentView, CommentTabs.CHANGE_LOG);
-
-          // Switch to comment thread tab
-          MockInteractions.tap(element.$$('paper-tab.commentThreads'));
-          assert.equal(element.$.commentTabs.selected,
-              CommentTabs.COMMENT_THREADS);
-          assert.equal(element._currentView, CommentTabs.COMMENT_THREADS);
-
-          // Switch back to 'Change Log' tab
-          element._paramsChanged(element.params);
-          flush(() => {
-            assert.equal(element.$.commentTabs.selected,
-                CommentTabs.CHANGE_LOG);
-            assert.equal(element._currentView, CommentTabs.CHANGE_LOG);
-            done();
-          });
+          done();
         });
       });
     });
@@ -793,6 +793,7 @@
         assert.equal(element._robotCommentThreads[1].comments[0].robot_id,
             'rc2');
       });
+
       test('changing patchsets resets robot comments', done => {
         element.set('_change.current_revision', 'rev3');
         flush(() => {
@@ -2191,7 +2192,8 @@
       const stub = sandbox.stub(element, '_handleToggleStar');
       flushAsynchronousOperations();
 
-      MockInteractions.tap(element.$.changeStar.$$('button'));
+      MockInteractions.tap(element.$.changeStar.shadowRoot
+          .querySelector('button'));
       assert.isTrue(stub.called);
     });
 
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.html
index 2a14cc3..3786174 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-abandon-dialog/gr-confirm-abandon-dialog_test.html
@@ -55,7 +55,8 @@
       element.addEventListener('confirm', confirmHandler);
       sandbox.spy(element, '_handleConfirmTap');
       sandbox.spy(element, '_confirm');
-      element.$$('gr-dialog').fire('confirm');
+      element.shadowRoot
+          .querySelector('gr-dialog').fire('confirm');
       assert.isTrue(confirmHandler.called);
       assert.isTrue(confirmHandler.calledOnce);
       assert.isTrue(element._handleConfirmTap.called);
@@ -68,7 +69,8 @@
       const cancelHandler = sandbox.stub();
       element.addEventListener('cancel', cancelHandler);
       sandbox.spy(element, '_handleCancelTap');
-      element.$$('gr-dialog').fire('cancel');
+      element.shadowRoot
+          .querySelector('gr-dialog').fire('cancel');
       assert.isTrue(cancelHandler.called);
       assert.isTrue(cancelHandler.calledOnce);
       assert.isTrue(element._handleCancelTap.called);
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.html
index 1dcc114..7c9896a 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-cherrypick-conflict-dialog/gr-confirm-cherrypick-conflict-dialog_test.html
@@ -52,7 +52,8 @@
       const confirmHandler = sandbox.stub();
       element.addEventListener('confirm', confirmHandler);
       sandbox.spy(element, '_handleConfirmTap');
-      element.$$('gr-dialog').fire('confirm');
+      element.shadowRoot
+          .querySelector('gr-dialog').fire('confirm');
       assert.isTrue(confirmHandler.called);
       assert.isTrue(confirmHandler.calledOnce);
       assert.isTrue(element._handleConfirmTap.called);
@@ -63,7 +64,8 @@
       const cancelHandler = sandbox.stub();
       element.addEventListener('cancel', cancelHandler);
       sandbox.spy(element, '_handleCancelTap');
-      element.$$('gr-dialog').fire('cancel');
+      element.shadowRoot
+          .querySelector('gr-dialog').fire('cancel');
       assert.isTrue(cancelHandler.called);
       assert.isTrue(cancelHandler.calledOnce);
       assert.isTrue(element._handleCancelTap.called);
diff --git a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.html b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.html
index ae19e4f..a5dffa8 100644
--- a/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-confirm-submit-dialog/gr-confirm-submit-dialog_test.html
@@ -56,10 +56,12 @@
       element.action = {label: 'my-label'};
       element.change = {subject: 'my-subject'};
       flushAsynchronousOperations();
-      const header = element.$$('.header');
+      const header = element.shadowRoot
+          .querySelector('.header');
       assert.equal(header.textContent.trim(), 'my-label');
 
-      const message = element.$$('.main p');
+      const message = element.shadowRoot
+          .querySelector('.main p');
       assert.notEqual(message.textContent.length, 0);
       assert.notEqual(message.textContent.indexOf('my-subject'), -1);
     });
diff --git a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
index 3c98fff..a3755ba 100644
--- a/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-download-dialog/gr-download-dialog_test.html
@@ -191,7 +191,8 @@
         element.addEventListener('close', () => {
           done();
         });
-        MockInteractions.tap(element.$$('.closeButtonContainer gr-button'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.closeButtonContainer gr-button'));
       });
     });
 
diff --git a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html
index 4979c32..f8a4e87 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list-header/gr-file-list-header_test.html
@@ -204,7 +204,8 @@
     });
 
     test('fileViewActions are properly hidden', () => {
-      const actions = element.$$('.fileViewActions');
+      const actions = element.shadowRoot
+          .querySelector('.fileViewActions');
       assert.equal(getComputedStyle(actions).display, 'none');
       element.filesExpanded = GrFileListConstants.FilesExpandedState.SOME;
       flushAsynchronousOperations();
@@ -286,12 +287,14 @@
         flushAsynchronousOperations();
 
         assert.isFalse(isVisible(element.$.diffPrefsContainer));
-        assert.isFalse(isVisible(element.$$('.descriptionContainer')));
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.descriptionContainer')));
 
         element.editMode = false;
         flushAsynchronousOperations();
 
-        assert.isTrue(isVisible(element.$$('.descriptionContainer')));
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.descriptionContainer')));
         assert.isTrue(isVisible(element.$.diffPrefsContainer));
       });
 
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
index a256a1b..0a1c8ec 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list_test.html
@@ -139,7 +139,8 @@
         assert.equal(
             Polymer.dom(element.root).querySelectorAll('.file-row').length,
             element.numFilesShown);
-        const controlRow = element.$$('.controlRow');
+        const controlRow = element.shadowRoot
+            .querySelector('.controlRow');
         assert.isFalse(controlRow.classList.contains('invisible'));
         assert.equal(element.$.incrementButton.textContent.trim(),
             'Show 300 more');
@@ -929,7 +930,8 @@
         const toggleExpandSpy = sandbox.spy(element, '_togglePathExpanded');
 
         // Tap the edit controls. Should be ignored by _handleFileListClick.
-        MockInteractions.tap(element.$$('.editFileControls'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.editFileControls'));
         assert.isTrue(clickSpy.calledOnce);
         assert.isFalse(toggleExpandSpy.called);
       });
@@ -1010,7 +1012,8 @@
         element._filesByPath = {
           '/COMMIT_MSG': {},
         };
-        assert.isNotOk(element.$$('.expanded'));
+        assert.isNotOk(element.shadowRoot
+            .querySelector('.expanded'));
       });
 
       test('tapping row ignores links', () => {
@@ -1034,9 +1037,11 @@
         MockInteractions.tap(commitMsgFile);
         flushAsynchronousOperations();
         assert(togglePathSpy.notCalled, 'file is opened as diff view');
-        assert.isNotOk(element.$$('.expanded'));
-        assert.notEqual(getComputedStyle(element.$$('.show-hide')).display,
-            'none');
+        assert.isNotOk(element.shadowRoot
+            .querySelector('.expanded'));
+        assert.notEqual(getComputedStyle(element.shadowRoot
+            .querySelector('.show-hide')).display,
+        'none');
       });
 
       test('_togglePathExpanded', () => {
@@ -1045,19 +1050,22 @@
         const renderSpy = sandbox.spy(element, '_renderInOrder');
         const collapseStub = sandbox.stub(element, '_clearCollapsedDiffs');
 
-        assert.equal(element.$$('iron-icon').icon, 'gr-icons:expand-more');
+        assert.equal(element.shadowRoot
+            .querySelector('iron-icon').icon, 'gr-icons:expand-more');
         assert.equal(element._expandedFilePaths.length, 0);
         element._togglePathExpanded(path);
         flushAsynchronousOperations();
         assert.equal(collapseStub.lastCall.args[0].length, 0);
-        assert.equal(element.$$('iron-icon').icon, 'gr-icons:expand-less');
+        assert.equal(element.shadowRoot
+            .querySelector('iron-icon').icon, 'gr-icons:expand-less');
 
         assert.equal(renderSpy.callCount, 1);
         assert.include(element._expandedFilePaths, path);
         element._togglePathExpanded(path);
         flushAsynchronousOperations();
 
-        assert.equal(element.$$('iron-icon').icon, 'gr-icons:expand-more');
+        assert.equal(element.shadowRoot
+            .querySelector('iron-icon').icon, 'gr-icons:expand-more');
         assert.equal(renderSpy.callCount, 1);
         assert.notInclude(element._expandedFilePaths, path);
         assert.equal(collapseStub.lastCall.args[0].length, 1);
diff --git a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
index c363982..b10b932 100644
--- a/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
+++ b/polygerrit-ui/app/elements/change/gr-label-score-row/gr-label-score-row_test.html
@@ -111,8 +111,9 @@
       const labelsChangedHandler = sandbox.stub();
       element.addEventListener('labels-changed', labelsChangedHandler);
       assert.ok(element.$.labelSelector);
-      MockInteractions.tap(element.$$(
-          'gr-button[data-value="-1"]'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector(
+              'gr-button[data-value="-1"]'));
       flushAsynchronousOperations();
       assert.strictEqual(element.selectedValue, '-1');
       assert.strictEqual(element.selectedItem
@@ -168,8 +169,9 @@
     });
 
     test('do not display tooltips on touch devices', () => {
-      const verifiedBtn = element.$$(
-          'iron-selector > gr-button[data-value="-1"]');
+      const verifiedBtn = element.shadowRoot
+          .querySelector(
+              'iron-selector > gr-button[data-value="-1"]');
 
       // On touch devices, tooltips should not be shown.
       verifiedBtn._isTouchDevice = true;
diff --git a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js
index 0cbf2c7..dbfdb6a 100644
--- a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js
+++ b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores.js
@@ -47,7 +47,8 @@
       for (const label in this.permittedLabels) {
         if (!this.permittedLabels.hasOwnProperty(label)) { continue; }
 
-        const selectorEl = this.$$(`gr-label-score-row[name="${label}"]`);
+        const selectorEl = this.shadowRoot
+            .querySelector(`gr-label-score-row[name="${label}"]`);
         if (!selectorEl) { continue; }
 
         // The user may have not voted on this label.
diff --git a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.html b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.html
index 22849f8..9e93110 100644
--- a/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.html
+++ b/polygerrit-ui/app/elements/change/gr-label-scores/gr-label-scores_test.html
@@ -111,7 +111,8 @@
     test('get and set label scores', () => {
       for (const label in element.permittedLabels) {
         if (element.permittedLabels.hasOwnProperty(label)) {
-          const row = element.$$('gr-label-score-row[name="' + label + '"]');
+          const row = element.shadowRoot
+              .querySelector('gr-label-score-row[name="' + label + '"]');
           row.setSelectedValue(-1);
         }
       }
diff --git a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html
index b23c797..f22f17e 100644
--- a/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html
+++ b/polygerrit-ui/app/elements/change/gr-message/gr-message_test.html
@@ -225,7 +225,8 @@
         flushAsynchronousOperations();
         const stub = sinon.stub();
         element.addEventListener('message-anchor-tap', stub);
-        const dateEl = element.$$('.date');
+        const dateEl = element.shadowRoot
+            .querySelector('.date');
         assert.ok(dateEl);
         MockInteractions.tap(dateEl);
 
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.js b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.js
index c637870..6f74e4b 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.js
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list.js
@@ -93,7 +93,8 @@
     }
 
     scrollToMessage(messageID) {
-      let el = this.$$('[data-message-id="' + messageID + '"]');
+      let el = this.shadowRoot
+          .querySelector('[data-message-id="' + messageID + '"]');
       // If the message is hidden, expand the hidden messages back to that
       // point.
       if (!el) {
@@ -111,7 +112,8 @@
         this.splice(...['_visibleMessages', 0, 0].concat(newMessages));
         // Allow the dom-repeat to stamp.
         Polymer.dom.flush();
-        el = this.$$('[data-message-id="' + messageID + '"]');
+        el = this.shadowRoot
+            .querySelector('[data-message-id="' + messageID + '"]');
       }
 
       el.set('message.expanded', true);
diff --git a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.html b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.html
index 0c9a71a..2ee2a81 100644
--- a/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-messages-list/gr-messages-list_test.html
@@ -352,7 +352,9 @@
         const messageID = messages[1].id;
         element.scrollToMessage(messageID);
         assert.isTrue(
-            element.$$('[data-message-id="' + messageID + '"]')._expanded);
+            element.shadowRoot
+                .querySelector('[data-message-id="' + messageID + '"]')
+                ._expanded);
 
         assert.isTrue(scrollToStub.calledOnce);
         assert.isTrue(highlightStub.calledOnce);
@@ -372,7 +374,9 @@
         assert.isTrue(highlightStub.calledOnce);
         assert.equal(element._visibleMessages.length, 24);
         assert.isTrue(
-            element.$$('[data-message-id="' + messageID + '"]')._expanded);
+            element.shadowRoot
+                .querySelector('[data-message-id="' + messageID + '"]')
+                ._expanded);
       });
 
       test('messages', () => {
diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
index 8d900af..9b8ebed 100644
--- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list_test.html
@@ -526,7 +526,8 @@
         element._submittedTogether = {changes: [change]};
         flushAsynchronousOperations();
         assert.notInclude(element.$.submittedTogether.className, 'hidden');
-        assert.isNull(element.$$('.note'));
+        assert.isNull(element.shadowRoot
+            .querySelector('.note'));
       });
 
       test('no visible submitted together changes', () => {
@@ -534,18 +535,22 @@
         element._submittedTogether = {changes: [], non_visible_changes: 1};
         flushAsynchronousOperations();
         assert.notInclude(element.$.submittedTogether.className, 'hidden');
-        assert.isNotNull(element.$$('.note'));
+        assert.isNotNull(element.shadowRoot
+            .querySelector('.note'));
         assert.strictEqual(
-            element.$$('.note').innerText, '(+ 1 non-visible change)');
+            element.shadowRoot
+                .querySelector('.note').innerText, '(+ 1 non-visible change)');
       });
 
       test('visible and non-visible submitted together changes', () => {
         element._submittedTogether = {changes: [change], non_visible_changes: 2};
         flushAsynchronousOperations();
         assert.notInclude(element.$.submittedTogether.className, 'hidden');
-        assert.isNotNull(element.$$('.note'));
+        assert.isNotNull(element.shadowRoot
+            .querySelector('.note'));
         assert.strictEqual(
-            element.$$('.note').innerText, '(+ 2 non-visible changes)');
+            element.shadowRoot
+                .querySelector('.note').innerText, '(+ 2 non-visible changes)');
       });
     });
   });
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html
index ef0504e..5fd3795 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog-it_test.html
@@ -123,12 +123,14 @@
       sandbox.stub(element, '_purgeReviewersPendingRemove');
 
       element.$.ccs.$.entry.setText('test');
-      MockInteractions.tap(element.$$('gr-button.send'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('gr-button.send'));
       assert.isFalse(sendStub.called);
       flushAsynchronousOperations();
 
       element.$.ccs.$.entry.setText('test@test.test');
-      MockInteractions.tap(element.$$('gr-button.send'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('gr-button.send'));
       assert.isTrue(sendStub.called);
     });
 
@@ -147,7 +149,8 @@
       element = fixture('basic');
       setupElement(element);
       const importSpy =
-          sandbox.spy(element.$$('gr-endpoint-decorator'), '_import');
+          sandbox.spy(element.shadowRoot
+              .querySelector('gr-endpoint-decorator'), '_import');
       Gerrit.awaitPluginsLoaded().then(() => {
         Promise.all(importSpy.returnValues).then(() => {
           flush(() => {
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
index 3aada1c..b1a05f5 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.js
@@ -304,14 +304,16 @@
 
     setLabelValue(label, value) {
       const selectorEl =
-          this.$.labelScores.$$(`gr-label-score-row[name="${label}"]`);
+          this.$.labelScores.shadowRoot
+              .querySelector(`gr-label-score-row[name="${label}"]`);
       if (!selectorEl) { return; }
       selectorEl.setSelectedValue(value);
     }
 
     getLabelValue(label) {
       const selectorEl =
-          this.$.labelScores.$$(`gr-label-score-row[name="${label}"]`);
+          this.$.labelScores.shadowRoot
+              .querySelector(`gr-label-score-row[name="${label}"]`);
       if (!selectorEl) { return null; }
 
       return selectorEl.selectedValue;
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
index 555a76af..b7c2330 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog_test.html
@@ -184,7 +184,8 @@
           // This is needed on non-Blink engines most likely due to the ways in
           // which the dom-repeat elements are stamped.
           flush(() => {
-            MockInteractions.tap(element.$$('.send'));
+            MockInteractions.tap(element.shadowRoot
+                .querySelector('.send'));
           });
         });
       });
@@ -218,7 +219,8 @@
           // This is needed on non-Blink engines most likely due to the ways in
           // which the dom-repeat elements are stamped.
           flush(() => {
-            MockInteractions.tap(element.$$('.send'));
+            MockInteractions.tap(element.shadowRoot
+                .querySelector('.send'));
           });
         });
       });
@@ -258,14 +260,18 @@
       // This is needed on non-Blink engines most likely due to the ways in
       // which the dom-repeat elements are stamped.
       flush(() => {
-        MockInteractions.tap(element.$$('.send'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.send'));
         assert.isTrue(element.disabled);
       });
     });
 
     test('getlabelValue returns value', done => {
       flush(() => {
-        element.$$('gr-label-scores').$$(`gr-label-score-row[name="Verified"]`)
+        element.shadowRoot
+            .querySelector('gr-label-scores')
+            .shadowRoot
+            .querySelector(`gr-label-score-row[name="Verified"]`)
             .setSelectedValue(-1);
         assert.equal('-1', element.getLabelValue('Verified'));
         done();
@@ -274,8 +280,10 @@
 
     test('getlabelValue when no score is selected', done => {
       flush(() => {
-        element.$$('gr-label-scores')
-            .$$(`gr-label-score-row[name="Code-Review"]`)
+        element.shadowRoot
+            .querySelector('gr-label-scores')
+            .shadowRoot
+            .querySelector(`gr-label-score-row[name="Code-Review"]`)
             .setSelectedValue(-1);
         assert.strictEqual(element.getLabelValue('Verified'), ' 0');
         done();
@@ -338,10 +346,12 @@
     }
 
     function testConfirmationDialog(done, cc) {
-      const yesButton =
-          element.$$('.reviewerConfirmationButtons gr-button:first-child');
-      const noButton =
-          element.$$('.reviewerConfirmationButtons gr-button:last-child');
+      const yesButton = element
+          .shadowRoot
+          .querySelector('.reviewerConfirmationButtons gr-button:first-child');
+      const noButton = element
+          .shadowRoot
+          .querySelector('.reviewerConfirmationButtons gr-button:last-child');
 
       element._ccPendingConfirmation = null;
       element._reviewerPendingConfirmation = null;
@@ -691,10 +701,13 @@
         // The send button can be tapped before the others, causing the test to
         // fail.
 
-        element.$$('gr-label-scores').$$(
-            'gr-label-score-row[name="Verified"]')
+        element.shadowRoot
+            .querySelector('gr-label-scores').shadowRoot
+            .querySelector(
+                'gr-label-score-row[name="Verified"]')
             .setSelectedValue(-1);
-        MockInteractions.tap(element.$$('.send'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.send'));
       });
     });
 
@@ -1024,13 +1037,15 @@
       });
 
       test('start review sets ready', () => {
-        MockInteractions.tap(element.$$('.send'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.send'));
         flushAsynchronousOperations();
         assert.isTrue(sendStub.calledWith(true, true));
       });
 
       test('save review doesn\'t set ready', () => {
-        MockInteractions.tap(element.$$('.save'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.save'));
         flushAsynchronousOperations();
         assert.isTrue(sendStub.calledWith(true, false));
       });
@@ -1187,13 +1202,15 @@
       element.draftCommentThreads = [];
       flushAsynchronousOperations();
 
-      MockInteractions.tap(element.$$('gr-button.send'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('gr-button.send'));
       assert.isFalse(sendStub.called);
 
       element.draftCommentThreads = [{comments: [{__draft: true}]}];
       flushAsynchronousOperations();
 
-      MockInteractions.tap(element.$$('gr-button.send'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('gr-button.send'));
       assert.isTrue(sendStub.called);
     });
 
diff --git a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html
index 60343e4..be65a86 100644
--- a/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-reviewer-list/gr-reviewer-list_test.html
@@ -58,16 +58,19 @@
 
     test('controls hidden on immutable element', () => {
       element.mutable = false;
-      assert.isTrue(element.$$('.controlsContainer').hasAttribute('hidden'));
+      assert.isTrue(element.shadowRoot
+          .querySelector('.controlsContainer').hasAttribute('hidden'));
       element.mutable = true;
-      assert.isFalse(element.$$('.controlsContainer').hasAttribute('hidden'));
+      assert.isFalse(element.shadowRoot
+          .querySelector('.controlsContainer').hasAttribute('hidden'));
     });
 
     test('add reviewer button opens reply dialog', done => {
       element.addEventListener('show-reply-dialog', () => {
         done();
       });
-      MockInteractions.tap(element.$$('.addReviewer'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('.addReviewer'));
     });
 
     test('only show remove for removable reviewers', () => {
@@ -123,7 +126,8 @@
         const accountID = el.account._account_id || el.account.email;
         assert.ok(accountID);
 
-        const buttonEl = el.$$('gr-button');
+        const buttonEl = el.shadowRoot
+            .querySelector('gr-button');
         assert.isNotNull(buttonEl);
         if (accountID == 2) {
           assert.isTrue(buttonEl.hasAttribute('hidden'));
@@ -213,7 +217,8 @@
       assert.equal(element._hiddenReviewerCount, 0);
       assert.equal(element._displayedReviewers.length, 6);
       assert.equal(element._reviewers.length, 6);
-      assert.isTrue(element.$$('.hiddenReviewers').hidden);
+      assert.isTrue(element.shadowRoot
+          .querySelector('.hiddenReviewers').hidden);
     });
 
     test('show all reviewers button with 8 reviewers', () => {
@@ -236,7 +241,8 @@
       assert.equal(element._hiddenReviewerCount, 3);
       assert.equal(element._displayedReviewers.length, 5);
       assert.equal(element._reviewers.length, 8);
-      assert.isFalse(element.$$('.hiddenReviewers').hidden);
+      assert.isFalse(element.shadowRoot
+          .querySelector('.hiddenReviewers').hidden);
     });
 
     test('no maxReviewersDisplayed', () => {
@@ -258,7 +264,8 @@
       assert.equal(element._hiddenReviewerCount, 0);
       assert.equal(element._displayedReviewers.length, 7);
       assert.equal(element._reviewers.length, 7);
-      assert.isTrue(element.$$('.hiddenReviewers').hidden);
+      assert.isTrue(element.shadowRoot
+          .querySelector('.hiddenReviewers').hidden);
     });
 
     test('show all reviewers button', () => {
@@ -281,14 +288,17 @@
       assert.equal(element._hiddenReviewerCount, 95);
       assert.equal(element._displayedReviewers.length, 5);
       assert.equal(element._reviewers.length, 100);
-      assert.isFalse(element.$$('.hiddenReviewers').hidden);
+      assert.isFalse(element.shadowRoot
+          .querySelector('.hiddenReviewers').hidden);
 
-      MockInteractions.tap(element.$$('.hiddenReviewers'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('.hiddenReviewers'));
 
       assert.equal(element._hiddenReviewerCount, 0);
       assert.equal(element._displayedReviewers.length, 100);
       assert.equal(element._reviewers.length, 100);
-      assert.isTrue(element.$$('.hiddenReviewers').hidden);
+      assert.isTrue(element.shadowRoot
+          .querySelector('.hiddenReviewers').hidden);
     });
 
     test('votable labels', () => {
diff --git a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.html b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.html
index f703547..30c598a 100644
--- a/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.html
+++ b/polygerrit-ui/app/elements/change/gr-thread-list/gr-thread-list_test.html
@@ -246,11 +246,13 @@
     });
 
     test('draft toggle only appears when logged in', () => {
-      assert.equal(getComputedStyle(element.$$('.draftToggle')).display,
-          'none');
+      assert.equal(getComputedStyle(element.shadowRoot
+          .querySelector('.draftToggle')).display,
+      'none');
       element.loggedIn = true;
-      assert.notEqual(getComputedStyle(element.$$('.draftToggle')).display,
-          'none');
+      assert.notEqual(getComputedStyle(element.shadowRoot
+          .querySelector('.draftToggle')).display,
+      'none');
     });
 
     test('there are five threads by default', () => {
diff --git a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
index 2518d77..e984577 100644
--- a/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
+++ b/polygerrit-ui/app/elements/core/gr-error-manager/gr-error-manager_test.html
@@ -239,7 +239,8 @@
                 noInteractionOverlay.backdropElement.getAttribute('opened'),
                 '');
             assert.isFalse(windowOpen.called);
-            MockInteractions.tap(toast.$$('gr-button.action'));
+            MockInteractions.tap(toast.shadowRoot
+                .querySelector('gr-button.action'));
             assert.isTrue(windowOpen.called);
 
             // @see Issue 5822: noopener breaks closeAfterLogin
diff --git a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
index da8b783..8fe3fca 100644
--- a/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
+++ b/polygerrit-ui/app/elements/core/gr-main-header/gr-main-header_test.html
@@ -59,30 +59,40 @@
 
     test('link visibility', () => {
       element.loading = true;
-      assert.equal(getComputedStyle(element.$$('.accountContainer')).display,
-          'none');
+      assert.equal(getComputedStyle(element.shadowRoot
+          .querySelector('.accountContainer')).display,
+      'none');
       element.loading = false;
       element.loggedIn = false;
-      assert.notEqual(getComputedStyle(element.$$('.accountContainer')).display,
-          'none');
-      assert.notEqual(getComputedStyle(element.$$('.loginButton')).display,
-          'none');
-      assert.notEqual(getComputedStyle(element.$$('.registerButton')).display,
-          'none');
-      assert.equal(getComputedStyle(element.$$('gr-account-dropdown')).display,
-          'none');
-      assert.equal(getComputedStyle(element.$$('.settingsButton')).display,
-          'none');
+      assert.notEqual(getComputedStyle(element.shadowRoot
+          .querySelector('.accountContainer')).display,
+      'none');
+      assert.notEqual(getComputedStyle(element.shadowRoot
+          .querySelector('.loginButton')).display,
+      'none');
+      assert.notEqual(getComputedStyle(element.shadowRoot
+          .querySelector('.registerButton')).display,
+      'none');
+      assert.equal(getComputedStyle(element.shadowRoot
+          .querySelector('gr-account-dropdown')).display,
+      'none');
+      assert.equal(getComputedStyle(element.shadowRoot
+          .querySelector('.settingsButton')).display,
+      'none');
       element.loggedIn = true;
-      assert.equal(getComputedStyle(element.$$('.loginButton')).display,
-          'none');
-      assert.equal(getComputedStyle(element.$$('.registerButton')).display,
-          'none');
-      assert.notEqual(getComputedStyle(element.$$('gr-account-dropdown'))
+      assert.equal(getComputedStyle(element.shadowRoot
+          .querySelector('.loginButton')).display,
+      'none');
+      assert.equal(getComputedStyle(element.shadowRoot
+          .querySelector('.registerButton')).display,
+      'none');
+      assert.notEqual(getComputedStyle(element.shadowRoot
+          .querySelector('gr-account-dropdown'))
           .display,
       'none');
-      assert.notEqual(getComputedStyle(element.$$('.settingsButton')).display,
-          'none');
+      assert.notEqual(getComputedStyle(element.shadowRoot
+          .querySelector('.settingsButton')).display,
+      'none');
     });
 
     test('fix my menu item', () => {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html
index cd92d7e..02b1d572 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-cursor/gr-diff-cursor_test.html
@@ -96,7 +96,8 @@
       // The cursor has been initialized to the first delta.
       assert.isOk(cursorElement.diffRow);
 
-      const firstDeltaRow = diffElement.$$('.section.delta .diff-row');
+      const firstDeltaRow = diffElement.shadowRoot
+          .querySelector('.section.delta .diff-row');
       assert.equal(cursorElement.diffRow, firstDeltaRow);
 
       cursorElement.moveDown();
@@ -152,10 +153,12 @@
         // The cursor has been initialized to the first delta.
         assert.isOk(cursorElement.diffRow);
 
-        let firstDeltaRow = diffElement.$$('.section.delta .diff-row');
+        let firstDeltaRow = diffElement.shadowRoot
+            .querySelector('.section.delta .diff-row');
         assert.equal(cursorElement.diffRow, firstDeltaRow);
 
-        firstDeltaRow = diffElement.$$('.section.delta .diff-row');
+        firstDeltaRow = diffElement.shadowRoot
+            .querySelector('.section.delta .diff-row');
         assert.equal(cursorElement.diffRow, firstDeltaRow);
 
         cursorElement.moveDown();
@@ -175,7 +178,8 @@
       // mode.
       assert.equal(diffElement.viewMode, 'SIDE_BY_SIDE');
 
-      const firstDeltaSection = diffElement.$$('.section.delta');
+      const firstDeltaSection = diffElement.shadowRoot
+          .querySelector('.section.delta');
       const firstDeltaRow = firstDeltaSection.querySelector('.diff-row');
 
       // Because the first delta in this diff is on the right, it should be set
@@ -383,7 +387,8 @@
 
     test('expand context updates stops', done => {
       sandbox.spy(cursorElement, 'handleDiffUpdate');
-      MockInteractions.tap(diffElement.$$('.showContext'));
+      MockInteractions.tap(diffElement.shadowRoot
+          .querySelector('.showContext'));
       flush(() => {
         assert.isTrue(cursorElement.handleDiffUpdate.called);
         done();
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.js b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.js
index e524cd8..99bf1c8 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight.js
@@ -382,7 +382,7 @@
         return;
       }
 
-      let actionBox = this.$$('gr-selection-action-box');
+      let actionBox = this.shadowRoot.querySelector('gr-selection-action-box');
       if (!actionBox) {
         actionBox = document.createElement('gr-selection-action-box');
         const root = Polymer.dom(this.root);
@@ -429,7 +429,8 @@
 
     _removeActionBox() {
       this.selectedRange = undefined;
-      const actionBox = this.$$('gr-selection-action-box');
+      const actionBox = this.shadowRoot
+          .querySelector('gr-selection-action-box');
       if (actionBox) {
         Polymer.dom(this.root).removeChild(actionBox);
       }
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.html b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.html
index 6712ba2..02c2033 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff-highlight/gr-diff-highlight_test.html
@@ -316,7 +316,8 @@
         const content = stubContent(1, 'right');
         sandbox.spy(element, '_positionActionBox');
         emulateSelection(content.firstChild, 5, content.firstChild, 12);
-        const actionBox = element.$$('gr-selection-action-box');
+        const actionBox = element.shadowRoot
+            .querySelector('gr-selection-action-box');
         assert.isTrue(actionBox.positionBelow);
       });
 
@@ -326,7 +327,8 @@
         sandbox.spy(element, '_positionActionBox');
         emulateSelection(
             startContent.firstChild, 10, endContent.lastChild, 7);
-        const actionBox = element.$$('gr-selection-action-box');
+        const actionBox = element.shadowRoot
+            .querySelector('gr-selection-action-box');
         assert.isTrue(actionBox.positionBelow);
       });
 
@@ -334,7 +336,8 @@
         const content = stubContent(138, 'left');
         sandbox.spy(element, '_positionActionBox');
         emulateSelection(content.firstChild, 5, content.firstChild, 12);
-        const actionBox = element.$$('gr-selection-action-box');
+        const actionBox = element.shadowRoot
+            .querySelector('gr-selection-action-box');
         const {range, side} = element.selectedRange;
         assert.deepEqual(range, {
           start_line: 138,
@@ -352,7 +355,8 @@
         sandbox.spy(element, '_positionActionBox');
         emulateSelection(
             startContent.firstChild, 10, endContent.lastChild, 7);
-        const actionBox = element.$$('gr-selection-action-box');
+        const actionBox = element.shadowRoot
+            .querySelector('gr-selection-action-box');
         const {range, side} = element.selectedRange;
         assert.deepEqual(range, {
           start_line: 119,
diff --git a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
index 757acca..ba46549 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
+++ b/polygerrit-ui/app/elements/diff/gr-diff/gr-diff_test.html
@@ -212,7 +212,10 @@
 
       test('view does not start with displayLine classList', () => {
         assert.isFalse(
-            element.$$('.diffContainer').classList.contains('displayLine'));
+            element.shadowRoot
+                .querySelector('.diffContainer')
+                .classList
+                .contains('displayLine'));
       });
 
       test('displayLine class added called when displayLine is true', () => {
@@ -220,7 +223,10 @@
         element.displayLine = true;
         assert.isTrue(spy.called);
         assert.isTrue(
-            element.$$('.diffContainer').classList.contains('displayLine'));
+            element.shadowRoot
+                .querySelector('.diffContainer')
+                .classList
+                .contains('displayLine'));
       });
 
       test('thread groups', () => {
@@ -631,7 +637,8 @@
       test('adds .hiddenscroll', () => {
         Gerrit.hiddenscroll = true;
         element.displayLine = true;
-        assert.include(element.$$('.diffContainer').className, 'hiddenscroll');
+        assert.include(element.shadowRoot
+            .querySelector('.diffContainer').className, 'hiddenscroll');
       });
     });
 
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.html b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.html
index d66a8bb..80de093 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.html
+++ b/polygerrit-ui/app/elements/edit/gr-edit-controls/gr-edit-controls_test.html
@@ -94,7 +94,8 @@
           openAutoCcmplete.text = 'src/test.cpp';
           assert.isTrue(queryStub.called);
           assert.isFalse(element.$.openDialog.disabled);
-          MockInteractions.tap(element.$.openDialog.$$('gr-button[primary]'));
+          MockInteractions.tap(element.$.openDialog.shadowRoot
+              .querySelector('gr-button[primary]'));
           for (const stub of navStubs) { assert.isTrue(stub.called); }
           assert.deepEqual(Gerrit.Nav.getEditUrlForDiff.lastCall.args,
               [element.change, 'src/test.cpp', element.patchNum]);
@@ -109,7 +110,8 @@
           openAutoCcmplete.noDebounce = true;
           openAutoCcmplete.text = 'src/test.cpp';
           assert.isFalse(element.$.openDialog.disabled);
-          MockInteractions.tap(element.$.openDialog.$$('gr-button'));
+          MockInteractions.tap(element.$.openDialog.shadowRoot
+              .querySelector('gr-button'));
           for (const stub of navStubs) { assert.isFalse(stub.called); }
           assert.isTrue(closeDialogSpy.called);
           assert.equal(element._path, 'src/test.cpp');
@@ -139,7 +141,8 @@
           deleteAutocomplete.text = 'src/test.cpp';
           assert.isTrue(queryStub.called);
           assert.isFalse(element.$.deleteDialog.disabled);
-          MockInteractions.tap(element.$.deleteDialog.$$('gr-button[primary]'));
+          MockInteractions.tap(element.$.deleteDialog.shadowRoot
+              .querySelector('gr-button[primary]'));
           flushAsynchronousOperations();
   
           assert.isTrue(deleteStub.called);
@@ -162,7 +165,8 @@
           deleteAutocomplete.text = 'src/test.cpp';
           assert.isTrue(queryStub.called);
           assert.isFalse(element.$.deleteDialog.disabled);
-          MockInteractions.tap(element.$.deleteDialog.$$('gr-button[primary]'));
+          MockInteractions.tap(element.$.deleteDialog.shadowRoot
+              .querySelector('gr-button[primary]'));
           flushAsynchronousOperations();
   
           assert.isTrue(deleteStub.called);
@@ -181,7 +185,8 @@
           element.$.deleteDialog.querySelector('gr-autocomplete').text =
               'src/test.cpp';
           assert.isFalse(element.$.deleteDialog.disabled);
-          MockInteractions.tap(element.$.deleteDialog.$$('gr-button'));
+          MockInteractions.tap(element.$.deleteDialog.shadowRoot
+              .querySelector('gr-button'));
           assert.isFalse(navStub.called);
           assert.isTrue(closeDialogSpy.called);
           assert.equal(element._path, 'src/test.cpp');
@@ -219,7 +224,8 @@
               'src/test.newPath';
   
           assert.isFalse(element.$.renameDialog.disabled);
-          MockInteractions.tap(element.$.renameDialog.$$('gr-button[primary]'));
+          MockInteractions.tap(element.$.renameDialog.shadowRoot
+              .querySelector('gr-button[primary]'));
           flushAsynchronousOperations();
   
           assert.isTrue(renameStub.called);
@@ -247,7 +253,8 @@
               'src/test.newPath';
   
           assert.isFalse(element.$.renameDialog.disabled);
-          MockInteractions.tap(element.$.renameDialog.$$('gr-button[primary]'));
+          MockInteractions.tap(element.$.renameDialog.shadowRoot
+              .querySelector('gr-button[primary]'));
           flushAsynchronousOperations();
   
           assert.isTrue(renameStub.called);
@@ -268,7 +275,8 @@
           element.$.renameDialog.querySelector(inputSelector).bindValue =
               'src/test.newPath';
           assert.isFalse(element.$.renameDialog.disabled);
-          MockInteractions.tap(element.$.renameDialog.$$('gr-button'));
+          MockInteractions.tap(element.$.renameDialog.shadowRoot
+              .querySelector('gr-button'));
           assert.isFalse(navStub.called);
           assert.isTrue(closeDialogSpy.called);
           assert.equal(element._path, 'src/test.cpp');
@@ -296,7 +304,8 @@
         element._path = 'src/test.cpp';
         MockInteractions.tap(element.shadowRoot.querySelector('#restore'));
         return showDialogSpy.lastCall.returnValue.then(() => {
-          MockInteractions.tap(element.$.restoreDialog.$$('gr-button[primary]'));
+          MockInteractions.tap(element.$.restoreDialog.shadowRoot
+              .querySelector('gr-button[primary]'));
           flushAsynchronousOperations();
   
           assert.isTrue(restoreStub.called);
@@ -314,7 +323,8 @@
         element._path = 'src/test.cpp';
         MockInteractions.tap(element.shadowRoot.querySelector('#restore'));
         return showDialogSpy.lastCall.returnValue.then(() => {
-          MockInteractions.tap(element.$.restoreDialog.$$('gr-button[primary]'));
+          MockInteractions.tap(element.$.restoreDialog.shadowRoot
+              .querySelector('gr-button[primary]'));
           flushAsynchronousOperations();
   
           assert.isTrue(restoreStub.called);
@@ -330,7 +340,8 @@
         element._path = 'src/test.cpp';
         MockInteractions.tap(element.shadowRoot.querySelector('#restore'));
         return showDialogSpy.lastCall.returnValue.then(() => {
-          MockInteractions.tap(element.$.restoreDialog.$$('gr-button'));
+          MockInteractions.tap(element.$.restoreDialog.shadowRoot
+              .querySelector('gr-button'));
           assert.isFalse(navStub.called);
           assert.isTrue(closeDialogSpy.called);
           assert.equal(element._path, 'src/test.cpp');
diff --git a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html
index bc1ee35..392a105 100644
--- a/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html
+++ b/polygerrit-ui/app/elements/edit/gr-edit-file-controls/gr-edit-file-controls_test.html
@@ -58,7 +58,8 @@
       actions._open();
       flushAsynchronousOperations();
   
-      MockInteractions.tap(actions.$$('li [data-id="open"]'));
+      MockInteractions.tap(actions.shadowRoot
+          .querySelector('li [data-id="open"]'));
       assert.isTrue(fileActionHandler.called);
       assert.deepEqual(fileActionHandler.lastCall.args[0].detail,
           {action: GrEditConstants.Actions.OPEN.id, path: 'foo'});
@@ -70,7 +71,8 @@
       actions._open();
       flushAsynchronousOperations();
   
-      MockInteractions.tap(actions.$$('li [data-id="delete"]'));
+      MockInteractions.tap(actions.shadowRoot
+          .querySelector('li [data-id="delete"]'));
       assert.isTrue(fileActionHandler.called);
       assert.deepEqual(fileActionHandler.lastCall.args[0].detail,
           {action: GrEditConstants.Actions.DELETE.id, path: 'foo'});
@@ -82,7 +84,8 @@
       actions._open();
       flushAsynchronousOperations();
   
-      MockInteractions.tap(actions.$$('li [data-id="restore"]'));
+      MockInteractions.tap(actions.shadowRoot
+          .querySelector('li [data-id="restore"]'));
       assert.isTrue(fileActionHandler.called);
       assert.deepEqual(fileActionHandler.lastCall.args[0].detail,
           {action: GrEditConstants.Actions.RESTORE.id, path: 'foo'});
@@ -94,7 +97,8 @@
       actions._open();
       flushAsynchronousOperations();
   
-      MockInteractions.tap(actions.$$('li [data-id="rename"]'));
+      MockInteractions.tap(actions.shadowRoot
+          .querySelector('li [data-id="rename"]'));
       assert.isTrue(fileActionHandler.called);
       assert.deepEqual(fileActionHandler.lastCall.args[0].detail,
           {action: GrEditConstants.Actions.RENAME.id, path: 'foo'});
diff --git a/polygerrit-ui/app/elements/gr-app-element.js b/polygerrit-ui/app/elements/gr-app-element.js
index 306fbb9..ea5a180 100644
--- a/polygerrit-ui/app/elements/gr-app-element.js
+++ b/polygerrit-ui/app/elements/gr-app-element.js
@@ -470,7 +470,7 @@
     _handleAccountDetailUpdate(e) {
       this.$.mainHeader.reload();
       if (this.params.view === Gerrit.Nav.View.SETTINGS) {
-        this.$$('gr-settings-view').reloadAccountDetail();
+        this.shadowRoot.querySelector('gr-settings-view').reloadAccountDetail();
       }
     }
 
diff --git a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html
index 915bd02..adc1de5 100644
--- a/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-repo-api/gr-repo-api_test.html
@@ -70,13 +70,16 @@
       const element = fixture('basic');
       flush(() => {
         assert.isTrue(attachedStub.called);
-        const pluginCommand = element.$$('gr-plugin-repo-command');
+        const pluginCommand = element.shadowRoot
+            .querySelector('gr-plugin-repo-command');
         assert.isOk(pluginCommand);
-        const command = pluginCommand.$$('gr-repo-command');
+        const command = pluginCommand.shadowRoot
+            .querySelector('gr-repo-command');
         assert.isOk(command);
         assert.equal(command.title, 'foo');
         assert.isFalse(tapStub.called);
-        MockInteractions.tap(command.$$('gr-button'));
+        MockInteractions.tap(command.shadowRoot
+            .querySelector('gr-button'));
         assert.isTrue(tapStub.called);
         done();
       });
diff --git a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html
index 01278f1..2efd182 100644
--- a/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html
+++ b/polygerrit-ui/app/elements/plugins/gr-settings-api/gr-settings-api_test.html
@@ -72,11 +72,13 @@
       const element = fixture('basic');
       flush(() => {
         const [menuItemEl, itemEl] = element;
-        const menuItem = menuItemEl.$$('gr-settings-menu-item');
+        const menuItem = menuItemEl.shadowRoot
+            .querySelector('gr-settings-menu-item');
         assert.isOk(menuItem);
         assert.equal(menuItem.title, 'foo');
         assert.equal(menuItem.href, '#x/testplugin/bar');
-        const item = itemEl.$$('gr-settings-item');
+        const item = itemEl.shadowRoot
+            .querySelector('gr-settings-item');
         assert.isOk(item);
         assert.equal(item.title, 'foo');
         assert.equal(item.anchor, 'x/testplugin/bar');
diff --git a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html
index 7800d5a..460d6bc 100644
--- a/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-change-table-editor/gr-change-table-editor_test.html
@@ -66,7 +66,8 @@
     });
 
     test('renders', () => {
-      const rows = element.$$('tbody').querySelectorAll('tr');
+      const rows = element.shadowRoot
+          .querySelector('tbody').querySelectorAll('tr');
       let tds;
 
       // The `+ 1` is for the number column, which isn't included in the change
@@ -79,7 +80,8 @@
     });
 
     test('hide item', () => {
-      const checkbox = element.$$('table tr:nth-child(2) input');
+      const checkbox = element.shadowRoot
+          .querySelector('table tr:nth-child(2) input');
       const isChecked = checkbox.checked;
       const displayedLength = element.displayedColumns.length;
       assert.isTrue(isChecked);
@@ -100,11 +102,13 @@
         'Updated',
       ]);
       flushAsynchronousOperations();
-      const checkbox = element.$$('table tr:nth-child(2) input');
+      const checkbox = element.shadowRoot
+          .querySelector('table tr:nth-child(2) input');
       const isChecked = checkbox.checked;
       const displayedLength = element.displayedColumns.length;
       assert.isFalse(isChecked);
-      assert.equal(element.$$('table').style.display, '');
+      assert.equal(element.shadowRoot
+          .querySelector('table').style.display, '');
 
       MockInteractions.tap(checkbox);
       flushAsynchronousOperations();
@@ -116,7 +120,8 @@
     test('_getDisplayedColumns', () => {
       assert.deepEqual(element._getDisplayedColumns(), columns);
       MockInteractions.tap(
-          element.$$('.checkboxContainer input[name=Assignee]'));
+          element.shadowRoot
+              .querySelector('.checkboxContainer input[name=Assignee]'));
       assert.deepEqual(element._getDisplayedColumns(),
           columns.filter(c => c !== 'Assignee'));
     });
@@ -126,12 +131,14 @@
       sandbox.stub(element, '_handleTargetClick');
 
       MockInteractions.tap(
-          element.$$('table tr:first-of-type .checkboxContainer'));
+          element.shadowRoot
+              .querySelector('table tr:first-of-type .checkboxContainer'));
       assert.isTrue(element._handleNumberCheckboxClick.calledOnce);
       assert.isFalse(element._handleTargetClick.called);
 
       MockInteractions.tap(
-          element.$$('table tr:last-of-type .checkboxContainer'));
+          element.shadowRoot
+              .querySelector('table tr:last-of-type .checkboxContainer'));
       assert.isTrue(element._handleNumberCheckboxClick.calledOnce);
       assert.isTrue(element._handleTargetClick.calledOnce);
     });
@@ -140,12 +147,14 @@
       sandbox.spy(element, '_handleNumberCheckboxClick');
 
       MockInteractions
-          .tap(element.$$('.checkboxContainer input[name=number]'));
+          .tap(element.shadowRoot
+              .querySelector('.checkboxContainer input[name=number]'));
       assert.isTrue(element._handleNumberCheckboxClick.calledOnce);
       assert.isTrue(element.showNumber);
 
       MockInteractions
-          .tap(element.$$('.checkboxContainer input[name=number]'));
+          .tap(element.shadowRoot
+              .querySelector('.checkboxContainer input[name=number]'));
       assert.isTrue(element._handleNumberCheckboxClick.calledTwice);
       assert.isFalse(element.showNumber);
     });
@@ -154,7 +163,8 @@
       sandbox.spy(element, '_handleTargetClick');
       assert.include(element.displayedColumns, 'Assignee');
       MockInteractions
-          .tap(element.$$('.checkboxContainer input[name=Assignee]'));
+          .tap(element.shadowRoot
+              .querySelector('.checkboxContainer input[name=Assignee]'));
       assert.isTrue(element._handleTargetClick.calledOnce);
       assert.notInclude(element.displayedColumns, 'Assignee');
     });
diff --git a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.html b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.html
index 5d4a69e..ecb108d 100644
--- a/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-email-editor/gr-email-editor_test.html
@@ -57,7 +57,8 @@
     });
 
     test('renders', () => {
-      const rows = element.$$('table').querySelectorAll('tbody tr');
+      const rows = element.shadowRoot
+          .querySelector('table').querySelectorAll('tbody tr');
 
       assert.equal(rows.length, 3);
 
@@ -75,7 +76,8 @@
 
     test('edit preferred', () => {
       const preferredChangedSpy = sinon.spy(element, '_handlePreferredChange');
-      const radios = element.$$('table').querySelectorAll('input[type=radio]');
+      const radios = element.shadowRoot
+          .querySelector('table').querySelectorAll('input[type=radio]');
 
       assert.isFalse(element.hasUnsavedChanges);
       assert.isNotOk(element._newPreferred);
@@ -97,7 +99,8 @@
     });
 
     test('delete email', () => {
-      const buttons = element.$$('table').querySelectorAll('gr-button');
+      const buttons = element.shadowRoot
+          .querySelector('table').querySelectorAll('gr-button');
 
       assert.isFalse(element.hasUnsavedChanges);
       assert.isNotOk(element._newPreferred);
@@ -119,7 +122,8 @@
           sinon.stub(element.$.restAPI, 'deleteAccountEmail');
       const setPreferredStub = sinon.stub(element.$.restAPI,
           'setPreferredAccountEmail');
-      const rows = element.$$('table').querySelectorAll('tbody tr');
+      const rows = element.shadowRoot
+          .querySelector('table').querySelectorAll('tbody tr');
 
       assert.isFalse(element.hasUnsavedChanges);
       assert.isNotOk(element._newPreferred);
diff --git a/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.html b/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.html
index 4fae65a..a5f2074 100644
--- a/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-menu-editor/gr-menu-editor_test.html
@@ -55,8 +55,10 @@
       const selector = 'tr:nth-child(' + (index + 1) + ') .move' +
           direction + 'Button';
       const button =
-          element.$$('tbody').querySelector(selector)
-              .$$('paper-button');
+          element.shadowRoot
+              .querySelector('tbody').querySelector(selector)
+              .shadowRoot
+              .querySelector('paper-button');
       MockInteractions.tap(button);
     }
 
@@ -73,7 +75,8 @@
     });
 
     test('renders', () => {
-      const rows = element.$$('tbody').querySelectorAll('tr');
+      const rows = element.shadowRoot
+          .querySelector('tbody').querySelectorAll('tr');
       let tds;
 
       assert.equal(rows.length, menu.length);
@@ -149,17 +152,21 @@
           ['first name', 'second name', 'third name']);
 
       // Tap the delete button for the middle item.
-      MockInteractions.tap(element.$$('tbody')
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('tbody')
           .querySelector('tr:nth-child(2) .remove-button')
-          .$$('paper-button'));
+          .shadowRoot
+          .querySelector('paper-button'));
 
       assertMenuNamesEqual(element, ['first name', 'third name']);
 
       // Delete remaining items.
       for (let i = 0; i < 2; i++) {
-        MockInteractions.tap(element.$$('tbody')
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('tbody')
             .querySelector('tr:first-child .remove-button')
-            .$$('paper-button'));
+            .shadowRoot
+            .querySelector('paper-button'));
       }
       assertMenuNamesEqual(element, []);
 
diff --git a/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.html b/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.html
index 5f31f4a..c96d6a0 100644
--- a/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.html
+++ b/polygerrit-ui/app/elements/settings/gr-watched-projects-editor/gr-watched-projects-editor_test.html
@@ -84,7 +84,8 @@
     });
 
     test('renders', () => {
-      const rows = element.$$('table').querySelectorAll('tbody tr');
+      const rows = element.shadowRoot
+          .querySelector('table').querySelectorAll('tbody tr');
       assert.equal(rows.length, 4);
 
       function getKeysOfRow(row) {
@@ -200,12 +201,14 @@
 
     test('_handleRemoveProject', () => {
       assert.equal(element._projectsToRemove, 0);
-      const button = element.$$('table tbody tr:nth-child(2) gr-button');
+      const button = element.shadowRoot
+          .querySelector('table tbody tr:nth-child(2) gr-button');
       MockInteractions.tap(button);
 
       flushAsynchronousOperations();
 
-      const rows = element.$$('table tbody').querySelectorAll('tr');
+      const rows = element.shadowRoot
+          .querySelector('table tbody').querySelectorAll('tr');
       assert.equal(rows.length, 3);
 
       assert.equal(element._projectsToRemove.length, 1);
diff --git a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.html b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.html
index c933edc..f5a9b8d 100644
--- a/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-account-label/gr-account-label_test.html
@@ -166,7 +166,8 @@
 
       test('status text should not have tooltip', () => {
         flushAsynchronousOperations();
-        assert.deepEqual(element.$$('gr-limited-text').title, '');
+        assert.deepEqual(element.shadowRoot
+            .querySelector('gr-limited-text').title, '');
       });
 
       test('status text should honor the name length and total length', () => {
diff --git a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html
index 381fa6b..68d782b 100644
--- a/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-alert/gr-alert_test.html
@@ -54,7 +54,8 @@
     test('action event', done => {
       element.show();
       element._actionCallback = done;
-      MockInteractions.tap(element.$$('.action'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('.action'));
     });
   });
 </script>
diff --git a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
index 9dbeb5a..295572f 100644
--- a/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-autocomplete/gr-autocomplete_test.html
@@ -371,7 +371,8 @@
     test('_focused flag properly triggered', done => {
       flush(() => {
         assert.isFalse(element._focused);
-        const input = element.$$('paper-input').inputElement;
+        const input = element.shadowRoot
+            .querySelector('paper-input').inputElement;
         MockInteractions.focus(input);
         assert.isTrue(element._focused);
         done();
@@ -380,11 +381,13 @@
 
     test('search icon shows with showSearchIcon property', done => {
       flush(() => {
-        assert.equal(getComputedStyle(element.$$('iron-icon')).display,
-            'none');
+        assert.equal(getComputedStyle(element.shadowRoot
+            .querySelector('iron-icon')).display,
+        'none');
         element.showSearchIcon = true;
-        assert.notEqual(getComputedStyle(element.$$('iron-icon')).display,
-            'none');
+        assert.notEqual(getComputedStyle(element.shadowRoot
+            .querySelector('iron-icon')).display,
+        'none');
         done();
       });
     });
@@ -517,7 +520,8 @@
         assert.isFalse(element.$.suggestions.isHidden);
 
         MockInteractions.pressAndReleaseKeyOn(
-            element.$.suggestions.$$('li:first-child'), 9, null, 'tab');
+            element.$.suggestions.shadowRoot
+                .querySelector('li:first-child'), 9, null, 'tab');
         flushAsynchronousOperations();
         assert.isFalse(commitSpy.called);
         assert.isFalse(element._focused);
@@ -533,7 +537,8 @@
         assert.isFalse(element.$.suggestions.isHidden);
 
         MockInteractions.pressAndReleaseKeyOn(
-            element.$.suggestions.$$('li:first-child'), 9, null, 'tab');
+            element.$.suggestions.shadowRoot
+                .querySelector('li:first-child'), 9, null, 'tab');
         flushAsynchronousOperations();
 
         assert.isTrue(commitSpy.called);
@@ -546,7 +551,8 @@
         element._suggestions = [{name: 'first suggestion'}];
         Polymer.dom.flush();
         assert.isFalse(element.$.suggestions.isHidden);
-        MockInteractions.tap(element.$.suggestions.$$('li:first-child'));
+        MockInteractions.tap(element.$.suggestions.shadowRoot
+            .querySelector('li:first-child'));
         flushAsynchronousOperations();
 
         assert.isFalse(focusSpy.called);
diff --git a/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html b/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html
index 6f8cdf6..0aec751 100644
--- a/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-button/gr-button_test.html
@@ -61,13 +61,17 @@
     });
 
     test('disabled is set by disabled or loading', () => {
-      assert.isFalse(element.$$('paper-button').disabled);
+      assert.isFalse(element.shadowRoot
+          .querySelector('paper-button').disabled);
       element.disabled = true;
-      assert.isTrue(element.$$('paper-button').disabled);
+      assert.isTrue(element.shadowRoot
+          .querySelector('paper-button').disabled);
       element.disabled = false;
-      assert.isFalse(element.$$('paper-button').disabled);
+      assert.isFalse(element.shadowRoot
+          .querySelector('paper-button').disabled);
       element.loading = true;
-      assert.isTrue(element.$$('paper-button').disabled);
+      assert.isTrue(element.shadowRoot
+          .querySelector('paper-button').disabled);
     });
 
     test('tabindex should be -1 if disabled', () => {
diff --git a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.html b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.html
index f245dbc..b76ce4d 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-change-star/gr-change-star_test.html
@@ -50,12 +50,14 @@
 
     test('star visibility states', () => {
       element.set('change.starred', true);
-      let icon = element.$$('iron-icon');
+      let icon = element.shadowRoot
+          .querySelector('iron-icon');
       assert.isTrue(icon.classList.contains('active'));
       assert.equal(icon.icon, 'gr-icons:star');
 
       element.set('change.starred', false);
-      icon = element.$$('iron-icon');
+      icon = element.shadowRoot
+          .querySelector('iron-icon');
       assert.isFalse(icon.classList.contains('active'));
       assert.equal(icon.icon, 'gr-icons:star-border');
     });
@@ -66,7 +68,8 @@
         done();
       });
       element.set('change.starred', false);
-      MockInteractions.tap(element.$$('button'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('button'));
     });
 
     test('unstarring', done => {
@@ -75,7 +78,8 @@
         done();
       });
       element.set('change.starred', true);
-      MockInteractions.tap(element.$$('button'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('button'));
     });
   });
 </script>
diff --git a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.html b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.html
index 65dadf8..d78cc3a 100644
--- a/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-change-status/gr-change-status_test.html
@@ -63,7 +63,8 @@
 
     test('WIP', () => {
       element.status = 'WIP';
-      assert.equal(element.$$('.chip').innerText, 'Work in Progress');
+      assert.equal(element.shadowRoot
+          .querySelector('.chip').innerText, 'Work in Progress');
       assert.equal(element.tooltipText, WIP_TOOLTIP);
       assert.isTrue(element.classList.contains('wip'));
     });
@@ -71,7 +72,8 @@
     test('WIP flat', () => {
       element.flat = true;
       element.status = 'WIP';
-      assert.equal(element.$$('.chip').innerText, 'WIP');
+      assert.equal(element.shadowRoot
+          .querySelector('.chip').innerText, 'WIP');
       assert.isDefined(element.tooltipText);
       assert.isTrue(element.classList.contains('wip'));
       assert.isTrue(element.hasAttribute('flat'));
@@ -79,42 +81,48 @@
 
     test('merged', () => {
       element.status = 'Merged';
-      assert.equal(element.$$('.chip').innerText, element.status);
+      assert.equal(element.shadowRoot
+          .querySelector('.chip').innerText, element.status);
       assert.equal(element.tooltipText, '');
       assert.isTrue(element.classList.contains('merged'));
     });
 
     test('abandoned', () => {
       element.status = 'Abandoned';
-      assert.equal(element.$$('.chip').innerText, element.status);
+      assert.equal(element.shadowRoot
+          .querySelector('.chip').innerText, element.status);
       assert.equal(element.tooltipText, '');
       assert.isTrue(element.classList.contains('abandoned'));
     });
 
     test('merge conflict', () => {
       element.status = 'Merge Conflict';
-      assert.equal(element.$$('.chip').innerText, element.status);
+      assert.equal(element.shadowRoot
+          .querySelector('.chip').innerText, element.status);
       assert.equal(element.tooltipText, MERGE_CONFLICT_TOOLTIP);
       assert.isTrue(element.classList.contains('merge-conflict'));
     });
 
     test('private', () => {
       element.status = 'Private';
-      assert.equal(element.$$('.chip').innerText, element.status);
+      assert.equal(element.shadowRoot
+          .querySelector('.chip').innerText, element.status);
       assert.equal(element.tooltipText, PRIVATE_TOOLTIP);
       assert.isTrue(element.classList.contains('private'));
     });
 
     test('active', () => {
       element.status = 'Active';
-      assert.equal(element.$$('.chip').innerText, element.status);
+      assert.equal(element.shadowRoot
+          .querySelector('.chip').innerText, element.status);
       assert.equal(element.tooltipText, '');
       assert.isTrue(element.classList.contains('active'));
     });
 
     test('ready to submit', () => {
       element.status = 'Ready to submit';
-      assert.equal(element.$$('.chip').innerText, element.status);
+      assert.equal(element.shadowRoot
+          .querySelector('.chip').innerText, element.status);
       assert.equal(element.tooltipText, '');
       assert.isTrue(element.classList.contains('ready-to-submit'));
     });
diff --git a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html
index e6f4835..a17a174 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-comment-thread/gr-comment-thread_test.html
@@ -202,7 +202,8 @@
       test('optionally show file path', () => {
         // Path info doesn't exist when showFilePath is false. Because it's in a
         // dom-if it is not yet in the dom.
-        assert.isNotOk(element.$$('.pathInfo'));
+        assert.isNotOk(element.shadowRoot
+            .querySelector('.pathInfo'));
 
         sandbox.stub(Gerrit.Nav, 'getUrlForDiffById');
         element.changeNum = 123;
@@ -212,9 +213,11 @@
         element.lineNum = 5;
         element.showFilePath = true;
         flushAsynchronousOperations();
-        assert.isOk(element.$$('.pathInfo'));
-        assert.notEqual(getComputedStyle(element.$$('.pathInfo')).display,
-            'none');
+        assert.isOk(element.shadowRoot
+            .querySelector('.pathInfo'));
+        assert.notEqual(getComputedStyle(element.shadowRoot
+            .querySelector('.pathInfo')).display,
+        'none');
         assert.isTrue(Gerrit.Nav.getUrlForDiffById.lastCall.calledWithExactly(
             element.changeNum, element.projectName, element.path,
             element.patchNum, null, element.lineNum));
@@ -276,7 +279,8 @@
     });
 
     test('reply', () => {
-      const commentEl = element.$$('gr-comment');
+      const commentEl = element.shadowRoot
+          .querySelector('gr-comment');
       const reportStub = sandbox.stub(element.$.reporting,
           'recordDraftInteraction');
       assert.ok(commentEl);
@@ -293,7 +297,8 @@
     });
 
     test('quote reply', () => {
-      const commentEl = element.$$('gr-comment');
+      const commentEl = element.shadowRoot
+          .querySelector('gr-comment');
       const reportStub = sandbox.stub(element.$.reporting,
           'recordDraftInteraction');
       assert.ok(commentEl);
@@ -324,7 +329,8 @@
       }];
       flushAsynchronousOperations();
 
-      const commentEl = element.$$('gr-comment');
+      const commentEl = element.shadowRoot
+          .querySelector('gr-comment');
       assert.ok(commentEl);
 
       const quoteBtn = element.$.quoteBtn;
@@ -345,7 +351,8 @@
       element.changeNum = '42';
       element.patchNum = '1';
 
-      const commentEl = element.$$('gr-comment');
+      const commentEl = element.shadowRoot
+          .querySelector('gr-comment');
       assert.ok(commentEl);
 
       const ackBtn = element.$.ackBtn;
@@ -366,7 +373,8 @@
           'recordDraftInteraction');
       element.changeNum = '42';
       element.patchNum = '1';
-      const commentEl = element.$$('gr-comment');
+      const commentEl = element.shadowRoot
+          .querySelector('gr-comment');
       assert.ok(commentEl);
 
       const doneBtn = element.$.doneBtn;
@@ -386,12 +394,14 @@
       element.changeNum = '42';
       element.patchNum = '1';
       element.path = '/path/to/file.txt';
-      const commentEl = element.$$('gr-comment');
+      const commentEl = element.shadowRoot
+          .querySelector('gr-comment');
       assert.ok(commentEl);
 
       const saveOrDiscardStub = sandbox.stub();
       element.addEventListener('thread-changed', saveOrDiscardStub);
-      element.$$('gr-comment')._fireSave();
+      element.shadowRoot
+          .querySelector('gr-comment')._fireSave();
 
       flush(() => {
         assert.isTrue(saveOrDiscardStub.called);
@@ -407,7 +417,8 @@
     test('please fix', done => {
       element.changeNum = '42';
       element.patchNum = '1';
-      const commentEl = element.$$('gr-comment');
+      const commentEl = element.shadowRoot
+          .querySelector('gr-comment');
       assert.ok(commentEl);
       commentEl.addEventListener('create-fix-comment', () => {
         const drafts = element._orderedComments.filter(c => c.__draft == true);
@@ -558,7 +569,8 @@
     });
 
     test('comment-update', () => {
-      const commentEl = element.$$('gr-comment');
+      const commentEl = element.shadowRoot
+          .querySelector('gr-comment');
       const updatedComment = {
         id: element.comments[0].id,
         foo: 'bar',
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
index c744a6f..9880e88 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment.js
@@ -433,7 +433,7 @@
 
       this.$.container.classList.toggle('editing', editing);
       if (this.comment && this.comment.id) {
-        this.$$('.cancel').hidden = !editing;
+        this.shadowRoot.querySelector('.cancel').hidden = !editing;
       }
       if (this.comment) {
         this.comment.__editing = this.editing;
diff --git a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html
index 6d0a5e5..5e9d37a 100644
--- a/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-comment/gr-comment_test.html
@@ -81,34 +81,41 @@
       test('collapsible comments', () => {
         // When a comment (not draft) is loaded, it should be collapsed
         assert.isTrue(element.collapsed);
-        assert.isFalse(isVisible(element.$$('gr-formatted-text')),
-            'gr-formatted-text is not visible');
-        assert.isFalse(isVisible(element.$$('.actions')),
-            'actions are not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('gr-formatted-text')),
+        'gr-formatted-text is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.actions')),
+        'actions are not visible');
         assert.isNotOk(element.textarea, 'textarea is not visible');
 
         // The header middle content is only visible when comments are collapsed.
         // It shows the message in a condensed way, and limits to a single line.
-        assert.isTrue(isVisible(element.$$('.collapsedContent')),
-            'header middle content is visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.collapsedContent')),
+        'header middle content is visible');
 
         // When the header row is clicked, the comment should expand
         MockInteractions.tap(element.$.header);
         assert.isFalse(element.collapsed);
-        assert.isTrue(isVisible(element.$$('gr-formatted-text')),
-            'gr-formatted-text is visible');
-        assert.isTrue(isVisible(element.$$('.actions')),
-            'actions are visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('gr-formatted-text')),
+        'gr-formatted-text is visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.actions')),
+        'actions are visible');
         assert.isNotOk(element.textarea, 'textarea is not visible');
-        assert.isFalse(isVisible(element.$$('.collapsedContent')),
-            'header middle content is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.collapsedContent')),
+        'header middle content is not visible');
       });
 
       test('clicking on date link fires event', () => {
         element.side = 'PARENT';
         const stub = sinon.stub();
         element.addEventListener('comment-anchor-tap', stub);
-        const dateEl = element.$$('.date');
+        const dateEl = element.shadowRoot
+            .querySelector('.date');
         assert.ok(dateEl);
         MockInteractions.tap(dateEl);
 
@@ -168,23 +175,29 @@
 
       test('comment expand and collapse', () => {
         element.collapsed = true;
-        assert.isFalse(isVisible(element.$$('gr-formatted-text')),
-            'gr-formatted-text is not visible');
-        assert.isFalse(isVisible(element.$$('.actions')),
-            'actions are not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('gr-formatted-text')),
+        'gr-formatted-text is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.actions')),
+        'actions are not visible');
         assert.isNotOk(element.textarea, 'textarea is not visible');
-        assert.isTrue(isVisible(element.$$('.collapsedContent')),
-            'header middle content is visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.collapsedContent')),
+        'header middle content is visible');
 
         element.collapsed = false;
         assert.isFalse(element.collapsed);
-        assert.isTrue(isVisible(element.$$('gr-formatted-text')),
-            'gr-formatted-text is visible');
-        assert.isTrue(isVisible(element.$$('.actions')),
-            'actions are visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('gr-formatted-text')),
+        'gr-formatted-text is visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.actions')),
+        'actions are visible');
         assert.isNotOk(element.textarea, 'textarea is not visible');
-        assert.isFalse(isVisible(element.$$('.collapsedContent')),
-            'header middle content is is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.collapsedContent')),
+        'header middle content is is not visible');
       });
 
       suite('while editing', () => {
@@ -253,14 +266,16 @@
       });
       test('delete comment button for non-admins is hidden', () => {
         element._isAdmin = false;
-        assert.isFalse(element.$$('.action.delete')
+        assert.isFalse(element.shadowRoot
+            .querySelector('.action.delete')
             .classList.contains('showDeleteButtons'));
       });
 
       test('delete comment button for admins with draft is hidden', () => {
         element._isAdmin = false;
         element.draft = true;
-        assert.isFalse(element.$$('.action.delete')
+        assert.isFalse(element.shadowRoot
+            .querySelector('.action.delete')
             .classList.contains('showDeleteButtons'));
       });
 
@@ -271,9 +286,11 @@
         element.changeNum = 42;
         element.patchNum = 0xDEADBEEF;
         element._isAdmin = true;
-        assert.isTrue(element.$$('.action.delete')
+        assert.isTrue(element.shadowRoot
+            .querySelector('.action.delete')
             .classList.contains('showDeleteButtons'));
-        MockInteractions.tap(element.$$('.action.delete'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.action.delete'));
         flush(() => {
           element.confirmDeleteOverlay.open.lastCall.returnValue.then(() => {
             const dialog =
@@ -336,7 +353,8 @@
       test('edit reports interaction', () => {
         const reportStub = sandbox.stub(element.$.reporting,
             'recordDraftInteraction');
-        MockInteractions.tap(element.$$('.edit'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.edit'));
         assert.isTrue(reportStub.calledOnce);
       });
 
@@ -344,7 +362,8 @@
         const reportStub = sandbox.stub(element.$.reporting,
             'recordDraftInteraction');
         element.draft = true;
-        MockInteractions.tap(element.$$('.discard'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.discard'));
         assert.isTrue(reportStub.calledOnce);
       });
     });
@@ -400,77 +419,110 @@
 
       test('button visibility states', () => {
         element.showActions = false;
-        assert.isTrue(element.$$('.humanActions').hasAttribute('hidden'));
-        assert.isTrue(element.$$('.robotActions').hasAttribute('hidden'));
+        assert.isTrue(element.shadowRoot
+            .querySelector('.humanActions').hasAttribute('hidden'));
+        assert.isTrue(element.shadowRoot
+            .querySelector('.robotActions').hasAttribute('hidden'));
 
         element.showActions = true;
-        assert.isFalse(element.$$('.humanActions').hasAttribute('hidden'));
-        assert.isTrue(element.$$('.robotActions').hasAttribute('hidden'));
+        assert.isFalse(element.shadowRoot
+            .querySelector('.humanActions').hasAttribute('hidden'));
+        assert.isTrue(element.shadowRoot
+            .querySelector('.robotActions').hasAttribute('hidden'));
 
         element.draft = true;
-        assert.isTrue(isVisible(element.$$('.edit')), 'edit is visible');
-        assert.isTrue(isVisible(element.$$('.discard')), 'discard is visible');
-        assert.isFalse(isVisible(element.$$('.save')), 'save is not visible');
-        assert.isFalse(isVisible(element.$$('.cancel')), 'cancel is not visible');
-        assert.isTrue(isVisible(element.$$('.resolve')), 'resolve is visible');
-        assert.isFalse(element.$$('.humanActions').hasAttribute('hidden'));
-        assert.isTrue(element.$$('.robotActions').hasAttribute('hidden'));
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.edit')), 'edit is visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.discard')), 'discard is visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.save')), 'save is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.cancel')), 'cancel is not visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.resolve')), 'resolve is visible');
+        assert.isFalse(element.shadowRoot
+            .querySelector('.humanActions').hasAttribute('hidden'));
+        assert.isTrue(element.shadowRoot
+            .querySelector('.robotActions').hasAttribute('hidden'));
 
         element.editing = true;
         flushAsynchronousOperations();
-        assert.isFalse(isVisible(element.$$('.edit')), 'edit is not visible');
-        assert.isFalse(isVisible(element.$$('.discard')), 'discard not visible');
-        assert.isTrue(isVisible(element.$$('.save')), 'save is visible');
-        assert.isTrue(isVisible(element.$$('.cancel')), 'cancel is visible');
-        assert.isTrue(isVisible(element.$$('.resolve')), 'resolve is visible');
-        assert.isFalse(element.$$('.humanActions').hasAttribute('hidden'));
-        assert.isTrue(element.$$('.robotActions').hasAttribute('hidden'));
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.edit')), 'edit is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.discard')), 'discard not visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.save')), 'save is visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.cancel')), 'cancel is visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.resolve')), 'resolve is visible');
+        assert.isFalse(element.shadowRoot
+            .querySelector('.humanActions').hasAttribute('hidden'));
+        assert.isTrue(element.shadowRoot
+            .querySelector('.robotActions').hasAttribute('hidden'));
 
         element.draft = false;
         element.editing = false;
         flushAsynchronousOperations();
-        assert.isFalse(isVisible(element.$$('.edit')), 'edit is not visible');
-        assert.isFalse(isVisible(element.$$('.discard')),
-            'discard is not visible');
-        assert.isFalse(isVisible(element.$$('.save')), 'save is not visible');
-        assert.isFalse(isVisible(element.$$('.cancel')), 'cancel is not visible');
-        assert.isFalse(element.$$('.humanActions').hasAttribute('hidden'));
-        assert.isTrue(element.$$('.robotActions').hasAttribute('hidden'));
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.edit')), 'edit is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.discard')),
+        'discard is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.save')), 'save is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.cancel')), 'cancel is not visible');
+        assert.isFalse(element.shadowRoot
+            .querySelector('.humanActions').hasAttribute('hidden'));
+        assert.isTrue(element.shadowRoot
+            .querySelector('.robotActions').hasAttribute('hidden'));
 
         element.comment.id = 'foo';
         element.draft = true;
         element.editing = true;
         flushAsynchronousOperations();
-        assert.isTrue(isVisible(element.$$('.cancel')), 'cancel is visible');
-        assert.isFalse(element.$$('.humanActions').hasAttribute('hidden'));
-        assert.isTrue(element.$$('.robotActions').hasAttribute('hidden'));
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.cancel')), 'cancel is visible');
+        assert.isFalse(element.shadowRoot
+            .querySelector('.humanActions').hasAttribute('hidden'));
+        assert.isTrue(element.shadowRoot
+            .querySelector('.robotActions').hasAttribute('hidden'));
 
         // Delete button is not hidden by default
         assert.isFalse(element.shadowRoot.querySelector('#deleteBtn').hidden);
 
         element.isRobotComment = true;
         element.draft = true;
-        assert.isTrue(element.$$('.humanActions').hasAttribute('hidden'));
-        assert.isFalse(element.$$('.robotActions').hasAttribute('hidden'));
+        assert.isTrue(element.shadowRoot
+            .querySelector('.humanActions').hasAttribute('hidden'));
+        assert.isFalse(element.shadowRoot
+            .querySelector('.robotActions').hasAttribute('hidden'));
 
         // It is not expected to see Robot comment drafts, but if they appear,
         // they will behave the same as non-drafts.
         element.draft = false;
-        assert.isTrue(element.$$('.humanActions').hasAttribute('hidden'));
-        assert.isFalse(element.$$('.robotActions').hasAttribute('hidden'));
+        assert.isTrue(element.shadowRoot
+            .querySelector('.humanActions').hasAttribute('hidden'));
+        assert.isFalse(element.shadowRoot
+            .querySelector('.robotActions').hasAttribute('hidden'));
 
         // A robot comment with run ID should display plain text.
         element.set(['comment', 'robot_run_id'], 'text');
         element.editing = false;
         element.collapsed = false;
         flushAsynchronousOperations();
-        assert.isTrue(element.$$('.robotRun.link').textContent === 'Run Details');
+        assert.isTrue(element.shadowRoot
+            .querySelector('.robotRun.link').textContent === 'Run Details');
 
         // A robot comment with run ID and url should display a link.
         element.set(['comment', 'url'], '/path/to/run');
         flushAsynchronousOperations();
-        assert.notEqual(getComputedStyle(element.$$('.robotRun.link')).display,
-            'none');
+        assert.notEqual(getComputedStyle(element.shadowRoot
+            .querySelector('.robotRun.link')).display,
+        'none');
 
         // Delete button is hidden for robot comments
         assert.isTrue(element.shadowRoot.querySelector('#deleteBtn').hidden);
@@ -478,60 +530,77 @@
 
       test('collapsible drafts', () => {
         assert.isTrue(element.collapsed);
-        assert.isFalse(isVisible(element.$$('gr-formatted-text')),
-            'gr-formatted-text is not visible');
-        assert.isFalse(isVisible(element.$$('.actions')),
-            'actions are not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('gr-formatted-text')),
+        'gr-formatted-text is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.actions')),
+        'actions are not visible');
         assert.isNotOk(element.textarea, 'textarea is not visible');
-        assert.isTrue(isVisible(element.$$('.collapsedContent')),
-            'header middle content is visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.collapsedContent')),
+        'header middle content is visible');
 
         MockInteractions.tap(element.$.header);
         assert.isFalse(element.collapsed);
-        assert.isTrue(isVisible(element.$$('gr-formatted-text')),
-            'gr-formatted-text is visible');
-        assert.isTrue(isVisible(element.$$('.actions')),
-            'actions are visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('gr-formatted-text')),
+        'gr-formatted-text is visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.actions')),
+        'actions are visible');
         assert.isNotOk(element.textarea, 'textarea is not visible');
-        assert.isFalse(isVisible(element.$$('.collapsedContent')),
-            'header middle content is is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.collapsedContent')),
+        'header middle content is is not visible');
 
         // When the edit button is pressed, should still see the actions
         // and also textarea
-        MockInteractions.tap(element.$$('.edit'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.edit'));
         flushAsynchronousOperations();
         assert.isFalse(element.collapsed);
-        assert.isFalse(isVisible(element.$$('gr-formatted-text')),
-            'gr-formatted-text is not visible');
-        assert.isTrue(isVisible(element.$$('.actions')),
-            'actions are visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('gr-formatted-text')),
+        'gr-formatted-text is not visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.actions')),
+        'actions are visible');
         assert.isTrue(isVisible(element.textarea), 'textarea is visible');
-        assert.isFalse(isVisible(element.$$('.collapsedContent')),
-            'header middle content is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.collapsedContent')),
+        'header middle content is not visible');
 
         // When toggle again, everything should be hidden except for textarea
         // and header middle content should be visible
         MockInteractions.tap(element.$.header);
         assert.isTrue(element.collapsed);
-        assert.isFalse(isVisible(element.$$('gr-formatted-text')),
-            'gr-formatted-text is not visible');
-        assert.isFalse(isVisible(element.$$('.actions')),
-            'actions are not visible');
-        assert.isFalse(isVisible(element.$$('gr-textarea')),
-            'textarea is not visible');
-        assert.isTrue(isVisible(element.$$('.collapsedContent')),
-            'header middle content is visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('gr-formatted-text')),
+        'gr-formatted-text is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.actions')),
+        'actions are not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('gr-textarea')),
+        'textarea is not visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.collapsedContent')),
+        'header middle content is visible');
 
         // When toggle again, textarea should remain open in the state it was
         // before
         MockInteractions.tap(element.$.header);
-        assert.isFalse(isVisible(element.$$('gr-formatted-text')),
-            'gr-formatted-text is not visible');
-        assert.isTrue(isVisible(element.$$('.actions')),
-            'actions are visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('gr-formatted-text')),
+        'gr-formatted-text is not visible');
+        assert.isTrue(isVisible(element.shadowRoot
+            .querySelector('.actions')),
+        'actions are visible');
         assert.isTrue(isVisible(element.textarea), 'textarea is visible');
-        assert.isFalse(isVisible(element.$$('.collapsedContent')),
-            'header middle content is not visible');
+        assert.isFalse(isVisible(element.shadowRoot
+            .querySelector('.collapsedContent')),
+        'header middle content is not visible');
       });
 
       test('robot comment layout', () => {
@@ -547,37 +616,45 @@
         flushAsynchronousOperations();
 
         let runIdMessage;
-        runIdMessage = element.$$('.runIdMessage');
+        runIdMessage = element.shadowRoot
+            .querySelector('.runIdMessage');
         assert.isFalse(runIdMessage.hidden);
 
-        const runDetailsLink = element.$$('.robotRunLink');
+        const runDetailsLink = element.shadowRoot
+            .querySelector('.robotRunLink');
         assert.isTrue(runDetailsLink.href.indexOf(element.comment.url) !== -1);
 
-        const robotServiceName = element.$$('.authorName');
+        const robotServiceName = element.shadowRoot
+            .querySelector('.authorName');
         assert.isTrue(robotServiceName.textContent === 'happy_robot_id');
 
-        const authorName = element.$$('.robotId');
+        const authorName = element.shadowRoot
+            .querySelector('.robotId');
         assert.isTrue(authorName.innerText === 'Happy Robot');
 
         element.collapsed = true;
         flushAsynchronousOperations();
-        runIdMessage = element.$$('.runIdMessage');
+        runIdMessage = element.shadowRoot
+            .querySelector('.runIdMessage');
         assert.isTrue(runIdMessage.hidden);
       });
 
       test('draft creation/cancellation', done => {
         assert.isFalse(element.editing);
-        MockInteractions.tap(element.$$('.edit'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.edit'));
         assert.isTrue(element.editing);
 
         element._messageText = '';
         const eraseMessageDraftSpy = sandbox.spy(element, '_eraseDraftComment');
 
         // Save should be disabled on an empty message.
-        let disabled = element.$$('.save').hasAttribute('disabled');
+        let disabled = element.shadowRoot
+            .querySelector('.save').hasAttribute('disabled');
         assert.isTrue(disabled, 'save button should be disabled.');
         element._messageText = '     ';
-        disabled = element.$$('.save').hasAttribute('disabled');
+        disabled = element.shadowRoot
+            .querySelector('.save').hasAttribute('disabled');
         assert.isTrue(disabled, 'save button should be disabled.');
 
         const updateStub = sinon.stub();
@@ -592,7 +669,8 @@
             done();
           }
         });
-        MockInteractions.tap(element.$$('.cancel'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.cancel'));
         element.flushDebouncer('fire-update');
         element._messageText = '';
         flushAsynchronousOperations();
@@ -695,7 +773,8 @@
         const cancelDebounce = sandbox.stub(element, 'cancelDebouncer');
 
         element.draft = true;
-        MockInteractions.tap(element.$$('.edit'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.edit'));
         element._messageText = 'good news, everyone!';
         element.flushDebouncer('fire-update');
         element.flushDebouncer('store');
@@ -709,7 +788,8 @@
         assert.isTrue(fireStub.calledOnce,
             'No events should fire for text editing');
 
-        MockInteractions.tap(element.$$('.save'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.save'));
 
         assert.isTrue(element.disabled,
             'Element should be disabled when creating draft.');
@@ -737,10 +817,12 @@
           assert.equal(draft.message, 'saved!');
           assert.isFalse(element.editing);
         }).then(() => {
-          MockInteractions.tap(element.$$('.edit'));
+          MockInteractions.tap(element.shadowRoot
+              .querySelector('.edit'));
           element._messageText = 'You’ll be delivering a package to Chapek 9, ' +
               'a world where humans are killed on sight.';
-          MockInteractions.tap(element.$$('.save'));
+          MockInteractions.tap(element.shadowRoot
+              .querySelector('.save'));
           assert.isTrue(element.disabled,
               'Element should be disabled when updating draft.');
 
@@ -760,17 +842,20 @@
         element.showActions = true;
         element.draft = true;
         MockInteractions.tap(element.$.header);
-        MockInteractions.tap(element.$$('.edit'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.edit'));
         element._messageText = 'good news, everyone!';
         element.flushDebouncer('fire-update');
         element.flushDebouncer('store');
 
         element.disabled = true;
-        MockInteractions.tap(element.$$('.save'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.save'));
         assert.isFalse(saveStub.called);
 
         element.disabled = false;
-        MockInteractions.tap(element.$$('.save'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.save'));
         assert.isTrue(saveStub.calledOnce);
       });
 
@@ -781,15 +866,18 @@
           assert.isFalse(save.called);
           done();
         });
-        MockInteractions.tap(element.$$('.resolve input'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.resolve input'));
       });
 
       test('resolved comment state indicated by checkbox', () => {
         sandbox.stub(element, 'save');
         element.comment = {unresolved: false};
-        assert.isTrue(element.$$('.resolve input').checked);
+        assert.isTrue(element.shadowRoot
+            .querySelector('.resolve input').checked);
         element.comment = {unresolved: true};
-        assert.isFalse(element.$$('.resolve input').checked);
+        assert.isFalse(element.shadowRoot
+            .querySelector('.resolve input').checked);
       });
 
       test('resolved checkbox saves with tap when !editing', () => {
@@ -797,12 +885,15 @@
         const save = sandbox.stub(element, 'save');
 
         element.comment = {unresolved: false};
-        assert.isTrue(element.$$('.resolve input').checked);
+        assert.isTrue(element.shadowRoot
+            .querySelector('.resolve input').checked);
         element.comment = {unresolved: true};
-        assert.isFalse(element.$$('.resolve input').checked);
+        assert.isFalse(element.shadowRoot
+            .querySelector('.resolve input').checked);
         assert.isFalse(save.called);
         MockInteractions.tap(element.$.resolvedCheckbox);
-        assert.isTrue(element.$$('.resolve input').checked);
+        assert.isTrue(element.shadowRoot
+            .querySelector('.resolve input').checked);
         assert.isTrue(save.called);
       });
 
@@ -881,7 +972,8 @@
         element.comments = [element.comment];
         flushAsynchronousOperations();
 
-        MockInteractions.tap(element.$$('.fix'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.fix'));
       });
 
       test('do not show Please Fix button if human reply exists', () => {
@@ -955,7 +1047,8 @@
         ];
         element.comment = element.comments[0];
         flushAsynchronousOperations();
-        assert.isNull(element.$$('robotActions gr-button'));
+        assert.isNull(element.shadowRoot
+            .querySelector('robotActions gr-button'));
       });
 
       test('show Please Fix if no human reply', () => {
@@ -1016,7 +1109,8 @@
         ];
         element.comment = element.comments[0];
         flushAsynchronousOperations();
-        assert.isNotNull(element.$$('.robotActions gr-button'));
+        assert.isNotNull(element.shadowRoot
+            .querySelector('.robotActions gr-button'));
       });
 
       test('_handleShowFix fires open-fix-preview event', done => {
@@ -1028,7 +1122,8 @@
         element.isRobotComment = true;
         flushAsynchronousOperations();
 
-        MockInteractions.tap(element.$$('.show-fix'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('.show-fix'));
       });
     });
 
diff --git a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html
index 05014f1..45ade85 100644
--- a/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-copy-clipboard/gr-copy-clipboard_test.html
@@ -56,7 +56,8 @@
 
     test('copy to clipboard', () => {
       const clipboardSpy = sandbox.spy(element, '_copyToClipboard');
-      const copyBtn = element.$$('.copyToClipboard');
+      const copyBtn = element.shadowRoot
+          .querySelector('.copyToClipboard');
       MockInteractions.tap(copyBtn);
       assert.isTrue(clipboardSpy.called);
     });
@@ -64,7 +65,8 @@
     test('focusOnCopy', () => {
       element.focusOnCopy();
       assert.deepEqual(Polymer.dom(element.root).activeElement,
-          element.$$('.copyToClipboard'));
+          element.shadowRoot
+              .querySelector('.copyToClipboard'));
     });
 
     test('_handleInputClick', () => {
diff --git a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html
index 93e693c..0b572bf 100644
--- a/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-date-formatter/gr-date-formatter_test.html
@@ -70,7 +70,8 @@
       sandbox.useFakeTimers(normalizedDate(nowStr).getTime());
       element.dateStr = dateStr;
       flush(() => {
-        const span = element.$$('span');
+        const span = element.shadowRoot
+            .querySelector('span');
         assert.equal(span.textContent.trim(), expected);
         assert.equal(element.title, expectedTooltip);
         element.showDateAndTime = true;
diff --git a/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.html b/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.html
index 13553ba..ad93962 100644
--- a/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-dialog/gr-dialog_test.html
@@ -55,24 +55,28 @@
       element.addEventListener('confirm', handler);
       element.addEventListener('cancel', handler);
 
-      MockInteractions.tap(element.$$('gr-button[primary]'));
-      MockInteractions.tap(element.$$('gr-button:not([primary])'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('gr-button[primary]'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('gr-button:not([primary])'));
     });
 
     test('confirmOnEnter', () => {
       element.confirmOnEnter = false;
       const handleConfirmStub = sandbox.stub(element, '_handleConfirm');
       const handleKeydownSpy = sandbox.spy(element, '_handleKeydown');
-      MockInteractions.pressAndReleaseKeyOn(element.$$('main'),
-          13, null, 'enter');
+      MockInteractions.pressAndReleaseKeyOn(element.shadowRoot
+          .querySelector('main'),
+      13, null, 'enter');
       flushAsynchronousOperations();
 
       assert.isTrue(handleKeydownSpy.called);
       assert.isFalse(handleConfirmStub.called);
 
       element.confirmOnEnter = true;
-      MockInteractions.pressAndReleaseKeyOn(element.$$('main'),
-          13, null, 'enter');
+      MockInteractions.pressAndReleaseKeyOn(element.shadowRoot
+          .querySelector('main'),
+      13, null, 'enter');
       flushAsynchronousOperations();
 
       assert.isTrue(handleConfirmStub.called);
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js
index 17fafce..04df531 100644
--- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js
+++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands.js
@@ -53,7 +53,7 @@
     }
 
     focusOnCopy() {
-      this.$$('gr-shell-command').focusOnCopy();
+      this.shadowRoot.querySelector('gr-shell-command').focusOnCopy();
     }
 
     _getLoggedIn() {
diff --git a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html
index a298680..4e37f9e 100644
--- a/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-download-commands/gr-download-commands_test.html
@@ -79,24 +79,30 @@
       });
 
       test('focusOnCopy', () => {
-        const focusStub = sandbox.stub(element.$$('gr-shell-command'),
-            'focusOnCopy');
+        const focusStub = sandbox.stub(element.shadowRoot
+            .querySelector('gr-shell-command'),
+        'focusOnCopy');
         element.focusOnCopy();
         assert.isTrue(focusStub.called);
       });
 
       test('element visibility', () => {
-        assert.isFalse(isHidden(element.$$('paper-tabs')));
-        assert.isFalse(isHidden(element.$$('.commands')));
+        assert.isFalse(isHidden(element.shadowRoot
+            .querySelector('paper-tabs')));
+        assert.isFalse(isHidden(element.shadowRoot
+            .querySelector('.commands')));
 
         element.schemes = [];
-        assert.isTrue(isHidden(element.$$('paper-tabs')));
-        assert.isTrue(isHidden(element.$$('.commands')));
+        assert.isTrue(isHidden(element.shadowRoot
+            .querySelector('paper-tabs')));
+        assert.isTrue(isHidden(element.shadowRoot
+            .querySelector('.commands')));
       });
 
       test('tab selection', done => {
         assert.equal(element.$.downloadTabs.selected, '0');
-        MockInteractions.tap(element.$$('[data-scheme="ssh"]'));
+        MockInteractions.tap(element.shadowRoot
+            .querySelector('[data-scheme="ssh"]'));
         flushAsynchronousOperations();
         assert.equal(element.selectedScheme, 'ssh');
         assert.equal(element.$.downloadTabs.selected, '2');
@@ -137,7 +143,8 @@
 
         flushAsynchronousOperations();
 
-        const repoTab = element.$$('paper-tab[data-scheme="repo"]');
+        const repoTab = element.shadowRoot
+            .querySelector('paper-tab[data-scheme="repo"]');
 
         MockInteractions.tap(repoTab);
 
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.html b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.html
index 0a14127..40e43fd 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown-list/gr-dropdown-list_test.html
@@ -94,7 +94,8 @@
           mobileText: 'Mobile Text 3',
         },
       ];
-      assert.equal(element.$$('paper-listbox').selected, element.value);
+      assert.equal(element.shadowRoot
+          .querySelector('paper-listbox').selected, element.value);
       assert.equal(element.text, 'Button Text 2');
       flush(() => {
         const items = Polymer.dom(element.root).querySelectorAll('paper-item');
diff --git a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
index 5c6d06f..2d7f090 100644
--- a/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-dropdown/gr-dropdown_test.html
@@ -129,7 +129,8 @@
       element.addEventListener('tap-item-foo', fooTapped);
       element.addEventListener('tap-item', tapped);
       flushAsynchronousOperations();
-      MockInteractions.tap(element.$$('.itemAction'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('.itemAction'));
       assert.isTrue(fooTapped.called);
       assert.isTrue(tapped.called);
       assert.deepEqual(tapped.lastCall.args[0].detail, item0);
@@ -144,7 +145,8 @@
       element.addEventListener('tap-item-foo', stub);
       element.addEventListener('tap-item', tapped);
       flushAsynchronousOperations();
-      MockInteractions.tap(element.$$('.itemAction'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('.itemAction'));
       assert.isFalse(stub.called);
       assert.isFalse(tapped.called);
     });
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js
index 5145f50..4510d3f 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content.js
@@ -80,7 +80,7 @@
     }
 
     focusTextarea() {
-      this.$$('iron-autogrow-textarea').textarea.focus();
+      this.shadowRoot.querySelector('iron-autogrow-textarea').textarea.focus();
     }
 
     _newContentChanged(newContent, oldContent) {
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.html b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.html
index 671cb06..87be1e9 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-editable-content/gr-editable-content_test.html
@@ -57,14 +57,16 @@
         assert.equal(e.detail.content, 'foo');
         done();
       });
-      MockInteractions.tap(element.$$('gr-button[primary]'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('gr-button[primary]'));
     });
 
     test('cancel event', done => {
       element.addEventListener('editable-content-cancel', () => {
         done();
       });
-      MockInteractions.tap(element.$$('gr-button:not([primary])'));
+      MockInteractions.tap(element.shadowRoot
+          .querySelector('gr-button:not([primary])'));
     });
 
     test('enabling editing keeps old content', () => {
@@ -96,12 +98,14 @@
       });
 
       test('save button is disabled initially', () => {
-        assert.isTrue(element.$$('gr-button[primary]').disabled);
+        assert.isTrue(element.shadowRoot
+            .querySelector('gr-button[primary]').disabled);
       });
 
       test('save button is enabled when content changes', () => {
         element._newContent = 'new content';
-        assert.isFalse(element.$$('gr-button[primary]').disabled);
+        assert.isFalse(element.shadowRoot
+            .querySelector('gr-button[primary]').disabled);
       });
     });
 
diff --git a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.html b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.html
index 304b6c4..540c10d 100644
--- a/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-editable-label/gr-editable-label_test.html
@@ -67,7 +67,8 @@
       element = fixture('basic');
       elementNoPlaceholder = fixture('no-placeholder');
 
-      label = element.$$('label');
+      label = element.shadowRoot
+          .querySelector('label');
       sandbox = sinon.sandbox.create();
       flush(() => {
         // In Polymer 2 inputElement isn't nativeInput anymore
@@ -226,7 +227,8 @@
 
       setup(() => {
         element = fixture('read-only');
-        label = element.$$('label');
+        label = element.shadowRoot
+            .querySelector('label');
       });
 
       test('disallows edit when read-only', () => {
diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.html b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.html
index fa39cb0..91e1a49 100644
--- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-change-actions-js-api_test.html
@@ -128,14 +128,17 @@
         const handler = sinon.spy();
         changeActions.addTapListener(key, handler);
         flush(() => {
-          MockInteractions.tap(element.$$('[data-action-key="' + key + '"]'));
+          MockInteractions.tap(element.shadowRoot
+              .querySelector('[data-action-key="' + key + '"]'));
           assert(handler.calledOnce);
           changeActions.removeTapListener(key, handler);
-          MockInteractions.tap(element.$$('[data-action-key="' + key + '"]'));
+          MockInteractions.tap(element.shadowRoot
+              .querySelector('[data-action-key="' + key + '"]'));
           assert(handler.calledOnce);
           changeActions.remove(key);
           flush(() => {
-            assert.isNull(element.$$('[data-action-key="' + key + '"]'));
+            assert.isNull(element.shadowRoot
+                .querySelector('[data-action-key="' + key + '"]'));
             done();
           });
         });
@@ -144,7 +147,8 @@
       test('action button properties', done => {
         const key = changeActions.add(changeActions.ActionType.REVISION, 'Bork!');
         flush(() => {
-          const button = element.$$('[data-action-key="' + key + '"]');
+          const button = element.shadowRoot
+              .querySelector('[data-action-key="' + key + '"]');
           assert.isOk(button);
           assert.equal(button.getAttribute('data-label'), 'Bork!');
           assert.isNotOk(button.disabled);
@@ -166,13 +170,15 @@
       test('hide action buttons', done => {
         const key = changeActions.add(changeActions.ActionType.REVISION, 'Bork!');
         flush(() => {
-          const button = element.$$('[data-action-key="' + key + '"]');
+          const button = element.shadowRoot
+              .querySelector('[data-action-key="' + key + '"]');
           assert.isOk(button);
           assert.isFalse(button.hasAttribute('hidden'));
           changeActions.setActionHidden(
               changeActions.ActionType.REVISION, key, true);
           flush(() => {
-            const button = element.$$('[data-action-key="' + key + '"]');
+            const button = element.shadowRoot
+                .querySelector('[data-action-key="' + key + '"]');
             assert.isNotOk(button);
             done();
           });
@@ -183,11 +189,13 @@
         const key = changeActions.add(changeActions.ActionType.REVISION, 'Bork!');
         flush(() => {
           assert.isTrue(element.$.moreActions.hidden);
-          assert.isOk(element.$$('[data-action-key="' + key + '"]'));
+          assert.isOk(element.shadowRoot
+              .querySelector('[data-action-key="' + key + '"]'));
           changeActions.setActionOverflow(
               changeActions.ActionType.REVISION, key, true);
           flush(() => {
-            assert.isNotOk(element.$$('[data-action-key="' + key + '"]'));
+            assert.isNotOk(element.shadowRoot
+                .querySelector('[data-action-key="' + key + '"]'));
             assert.isFalse(element.$.moreActions.hidden);
             assert.strictEqual(element.$.moreActions.items[0].name, 'Bork!');
             done();
diff --git a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.html b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.html
index c234b13..013a6ee 100644
--- a/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-label-info/gr-label-info_test.html
@@ -82,7 +82,8 @@
 
       test('_computeCanDeleteVote', () => {
         element.mutable = false;
-        const button = element.$$('gr-button');
+        const button = element.shadowRoot
+            .querySelector('gr-button');
         assert.isTrue(isHidden(button));
         element.change.removable_reviewers = [element.account];
         element.mutable = true;
@@ -97,7 +98,8 @@
         element.change.removable_reviewers = [element.account];
         element.change.labels.test.recommended = {_account_id: 1};
         element.mutable = true;
-        const button = element.$$('gr-button');
+        const button = element.shadowRoot
+            .querySelector('gr-button');
         MockInteractions.tap(button);
         assert.isTrue(button.disabled);
         return deleteResponse.then(() => {
@@ -223,11 +225,14 @@
 
     test('placeholder', () => {
       element.labelInfo = {};
-      assert.isFalse(isHidden(element.$$('.placeholder')));
+      assert.isFalse(isHidden(element.shadowRoot
+          .querySelector('.placeholder')));
       element.labelInfo = {all: []};
-      assert.isFalse(isHidden(element.$$('.placeholder')));
+      assert.isFalse(isHidden(element.shadowRoot
+          .querySelector('.placeholder')));
       element.labelInfo = {all: [{value: 1}]};
-      assert.isTrue(isHidden(element.$$('.placeholder')));
+      assert.isTrue(isHidden(element.shadowRoot
+          .querySelector('.placeholder')));
     });
   });
 </script>
diff --git a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html
index 8a225f3..9e373b7 100644
--- a/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-linked-text/gr-linked-text_test.html
@@ -357,7 +357,8 @@
       const links = Polymer.dom(element.root).querySelectorAll('a');
 
       assert.equal(links.length, 2);
-      assert.equal(element.$$('span').textContent, '- B: 123, 45');
+      assert.equal(element.shadowRoot
+          .querySelector('span').textContent, '- B: 123, 45');
 
       assert.equal(links[0].href, 'ftp://foo/123');
       assert.equal(links[0].textContent, '123');
diff --git a/polygerrit-ui/app/elements/shared/gr-select/gr-select.js b/polygerrit-ui/app/elements/shared/gr-select/gr-select.js
index ea838a0..3e59aee 100644
--- a/polygerrit-ui/app/elements/shared/gr-select/gr-select.js
+++ b/polygerrit-ui/app/elements/shared/gr-select/gr-select.js
@@ -39,7 +39,10 @@
     }
 
     get nativeSelect() {
-      return this.$$('select');
+      // gr-select is not a shadow component
+      // TODO(taoalpha): maybe we should convert
+      // it into a shadow dom component instead
+      return this.querySelector('select');
     }
 
     _updateValue() {
diff --git a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.js b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.js
index 4b31086..63dbcbd 100644
--- a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.js
+++ b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command.js
@@ -31,7 +31,7 @@
     }
 
     focusOnCopy() {
-      this.$$('gr-copy-clipboard').focusOnCopy();
+      this.shadowRoot.querySelector('gr-copy-clipboard').focusOnCopy();
     }
   }
 
diff --git a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html
index 5fbbdf8..b596a4a 100644
--- a/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-shell-command/gr-shell-command_test.html
@@ -54,8 +54,9 @@
     });
 
     test('focusOnCopy', () => {
-      const focusStub = sandbox.stub(element.$$('gr-copy-clipboard'),
-          'focusOnCopy');
+      const focusStub = sandbox.stub(element.shadowRoot
+          .querySelector('gr-copy-clipboard'),
+      'focusOnCopy');
       element.focusOnCopy();
       assert.isTrue(focusStub.called);
     });
diff --git a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.html b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.html
index 07dc57f..4c9b954 100644
--- a/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.html
+++ b/polygerrit-ui/app/elements/shared/gr-tooltip/gr-tooltip_test.html
@@ -51,14 +51,18 @@
     });
 
     test('the correct arrow is displayed', () => {
-      assert.equal(getComputedStyle(element.$$('.arrowPositionBelow')).display,
-          'none');
-      assert.notEqual(getComputedStyle(element.$$('.arrowPositionAbove'))
+      assert.equal(getComputedStyle(element.shadowRoot
+          .querySelector('.arrowPositionBelow')).display,
+      'none');
+      assert.notEqual(getComputedStyle(element.shadowRoot
+          .querySelector('.arrowPositionAbove'))
           .display, 'none');
       element.positionBelow = true;
-      assert.notEqual(getComputedStyle(element.$$('.arrowPositionBelow'))
+      assert.notEqual(getComputedStyle(element.shadowRoot
+          .querySelector('.arrowPositionBelow'))
           .display, 'none');
-      assert.equal(getComputedStyle(element.$$('.arrowPositionAbove'))
+      assert.equal(getComputedStyle(element.shadowRoot
+          .querySelector('.arrowPositionAbove'))
           .display, 'none');
     });
   });