diff --git a/app/assets/javascripts/vue_shared/components/chronic_duration_input.vue b/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/chronic_duration_input.vue
similarity index 100%
rename from app/assets/javascripts/vue_shared/components/chronic_duration_input.vue
rename to app/assets/javascripts/admin/application_settings/runner_token_expiration/components/chronic_duration_input.vue
diff --git a/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_intervals.vue b/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_intervals.vue
index 371a26d266405c658e877242ea2f5db2cb53e709..695806a5fa604ffb04b771db53b492b52fff10f4 100644
--- a/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_intervals.vue
+++ b/app/assets/javascripts/admin/application_settings/runner_token_expiration/components/expiration_intervals.vue
@@ -1,7 +1,7 @@
 <script>
 import { GlFormGroup } from '@gitlab/ui';
 import { s__ } from '~/locale';
-import ChronicDurationInput from '~/vue_shared/components/chronic_duration_input.vue';
+import ChronicDurationInput from '~/admin/application_settings/runner_token_expiration/components/chronic_duration_input.vue';
 import ExpirationIntervalDescription from './expiration_interval_description.vue';
 
 export default {
diff --git a/ee/app/assets/javascripts/related_items_tree/components/related_items_tree_app.vue b/ee/app/assets/javascripts/related_items_tree/components/related_items_tree_app.vue
index 0b835de070c33dbf52115f5311101aebafceefd8..179309f6cde131e24f1afa255a601fe65303177c 100644
--- a/ee/app/assets/javascripts/related_items_tree/components/related_items_tree_app.vue
+++ b/ee/app/assets/javascripts/related_items_tree/components/related_items_tree_app.vue
@@ -6,7 +6,6 @@ import { TYPE_EPIC, TYPE_ISSUE } from '~/issues/constants';
 import { helpPagePath } from '~/helpers/help_page_helper';
 import { __, s__, sprintf } from '~/locale';
 import AddItemForm from '~/related_issues/components/add_issuable_form.vue';
-import SlotSwitch from '~/vue_shared/components/slot_switch.vue';
 import CrudComponent from '~/vue_shared/components/crud_component.vue';
 import {
   ITEM_TABS,
@@ -22,6 +21,7 @@ import RelatedItemsTreeHeaderActions from './related_items_tree_header_actions.v
 import RelatedItemsTreeCount from './related_items_tree_count.vue';
 import RelatedItemsTreeActions from './related_items_tree_actions.vue';
 import RelatedItemsRoadmapApp from './related_items_roadmap_app.vue';
+import SlotSwitch from './slot_switch.vue';
 import TreeItemRemoveModal from './tree_item_remove_modal.vue';
 
 const FORM_SLOTS = {
diff --git a/app/assets/javascripts/vue_shared/components/slot_switch.vue b/ee/app/assets/javascripts/related_items_tree/components/slot_switch.vue
similarity index 100%
rename from app/assets/javascripts/vue_shared/components/slot_switch.vue
rename to ee/app/assets/javascripts/related_items_tree/components/slot_switch.vue
diff --git a/ee/spec/frontend/related_items_tree/components/related_items_tree_app_spec.js b/ee/spec/frontend/related_items_tree/components/related_items_tree_app_spec.js
index ddfd7ee291c38eb45e4e983519d573c1312e278d..b6e3961db6c837fcf0ae8b7564fa4c865ebf3149 100644
--- a/ee/spec/frontend/related_items_tree/components/related_items_tree_app_spec.js
+++ b/ee/spec/frontend/related_items_tree/components/related_items_tree_app_spec.js
@@ -9,7 +9,7 @@ import mockProjects from 'test_fixtures_static/projects.json';
 import CreateIssueForm from 'ee/related_items_tree/components/create_issue_form.vue';
 import CreateEpicForm from 'ee/related_items_tree/components/create_epic_form.vue';
 import AddItemForm from '~/related_issues/components/add_issuable_form.vue';
-import SlotSwitch from '~/vue_shared/components/slot_switch.vue';
+import SlotSwitch from 'ee/related_items_tree/components/slot_switch.vue';
 import RelatedItemsTreeApp from 'ee/related_items_tree/components/related_items_tree_app.vue';
 import RelatedItemsTreeHeaderActions from 'ee/related_items_tree/components/related_items_tree_header_actions.vue';
 import RelatedItemsTreeActions from 'ee/related_items_tree/components/related_items_tree_actions.vue';
diff --git a/spec/frontend/vue_shared/components/slot_switch_spec.js b/ee/spec/frontend/related_items_tree/components/slot_switch_spec.js
similarity index 79%
rename from spec/frontend/vue_shared/components/slot_switch_spec.js
rename to ee/spec/frontend/related_items_tree/components/slot_switch_spec.js
index 3a2147c6c894011587a6b51fc84a8837df944cfd..1f728b9175989d536799402ee9f92b25422ba8bc 100644
--- a/spec/frontend/vue_shared/components/slot_switch_spec.js
+++ b/ee/spec/frontend/related_items_tree/components/slot_switch_spec.js
@@ -1,12 +1,12 @@
 import { shallowMount } from '@vue/test-utils';
 import { assertProps } from 'helpers/assert_props';
 
-import SlotSwitch from '~/vue_shared/components/slot_switch.vue';
+import SlotSwitch from 'ee/related_items_tree/components/slot_switch.vue';
 
 describe('SlotSwitch', () => {
   const slots = {
-    first: '<a>AGP</a>',
-    second: '<p>PCI</p>',
+    first: '<a data-testid="slot-item">AGP</a>',
+    second: '<p data-testid="slot-item">PCI</p>',
   };
 
   let wrapper;
@@ -18,7 +18,8 @@ describe('SlotSwitch', () => {
     });
   };
 
-  const getChildrenHtml = () => wrapper.findAll('* *').wrappers.map((c) => c.html());
+  const getChildrenHtml = () =>
+    wrapper.findAll('[data-testid="slot-item"]').wrappers.map((c) => c.html());
 
   it('throws an error if activeSlotNames is missing', () => {
     expect(() => assertProps(SlotSwitch, {})).toThrow(
diff --git a/scripts/frontend/quarantined_vue3_specs.txt b/scripts/frontend/quarantined_vue3_specs.txt
index f8a9f414ad305d76e99da7d072db89f458ba0597..5f3c101282d7f74d65d01b5d80746976b2b153b7 100644
--- a/scripts/frontend/quarantined_vue3_specs.txt
+++ b/scripts/frontend/quarantined_vue3_specs.txt
@@ -439,7 +439,6 @@ spec/frontend/vue_merge_request_widget/components/widget/widget_spec.js
 spec/frontend/vue_popovers_spec.js
 spec/frontend/vue_shared/components/alert_details_table_spec.js
 spec/frontend/vue_shared/components/badges/beta_badge_spec.js
-spec/frontend/vue_shared/components/chronic_duration_input_spec.js
 spec/frontend/vue_shared/components/color_picker/color_picker_spec.js
 spec/frontend/vue_shared/components/color_select_dropdown/dropdown_contents_spec.js
 spec/frontend/vue_shared/components/confirm_modal_spec.js
@@ -465,7 +464,6 @@ spec/frontend/vue_shared/components/registry/registry_search_spec.js
 spec/frontend/vue_shared/components/runner_instructions/instructions/runner_aws_instructions_spec.js
 spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
 spec/frontend/vue_shared/components/segmented_control_button_group_spec.js
-spec/frontend/vue_shared/components/slot_switch_spec.js
 spec/frontend/vue_shared/components/smart_virtual_list_spec.js
 spec/frontend/vue_shared/components/source_viewer/components/chunk_spec.js
 spec/frontend/vue_shared/components/tooltip_on_truncate_spec.js
diff --git a/spec/frontend/vue_shared/components/chronic_duration_input_spec.js b/spec/frontend/admin/application_settings/runner_token_expiration/components/chronic_duration_input_spec.js
similarity index 90%
rename from spec/frontend/vue_shared/components/chronic_duration_input_spec.js
rename to spec/frontend/admin/application_settings/runner_token_expiration/components/chronic_duration_input_spec.js
index 374babe3a97e2220c17ca67b38799bab680625f9..80d86b0fcfcd8ca3afc3fea25a4cf04013f9de52 100644
--- a/spec/frontend/vue_shared/components/chronic_duration_input_spec.js
+++ b/spec/frontend/admin/application_settings/runner_token_expiration/components/chronic_duration_input_spec.js
@@ -1,12 +1,14 @@
 import { mount } from '@vue/test-utils';
 import { nextTick } from 'vue';
-import ChronicDurationInput from '~/vue_shared/components/chronic_duration_input.vue';
+import { GlFormInput } from '@gitlab/ui';
+import ChronicDurationInput from '~/admin/application_settings/runner_token_expiration/components/chronic_duration_input.vue';
 
 const MOCK_VALUE = 2 * 3600 + 20 * 60;
 
-describe('vue_shared/components/chronic_duration_input', () => {
+describe('admin/application_settings/runner_token_expiration/components/chronic_duration_input', () => {
   let wrapper;
   let textElement;
+  let textFormInput;
   let hiddenElement;
 
   afterEach(() => {
@@ -15,8 +17,10 @@ describe('vue_shared/components/chronic_duration_input', () => {
   });
 
   const findComponents = () => {
-    textElement = wrapper.find('input[type=text]').element;
+    textElement = wrapper.findComponent(GlFormInput).element;
     hiddenElement = wrapper.find('input[type=hidden]').element;
+
+    textFormInput = wrapper.findComponent(GlFormInput);
   };
 
   const createComponent = (props = {}) => {
@@ -44,8 +48,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
     const createAndDispatch = async (initialValue, humanReadableInput) => {
       createComponent({ value: initialValue });
       await nextTick();
-      textElement.value = humanReadableInput;
-      textElement.dispatchEvent(new Event('input'));
+      textFormInput.vm.$emit('input', humanReadableInput);
     };
 
     describe('when starting with no value and receiving human-readable input', () => {
@@ -111,8 +114,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
       });
 
       it('emits valid with user input', async () => {
-        textElement.value = '1m10s';
-        textElement.dispatchEvent(new Event('input'));
+        textFormInput.vm.$emit('input', '1m10s');
         await nextTick();
 
         expect(wrapper.emitted('valid')).toEqual([
@@ -126,8 +128,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
         expect(hiddenElement.validity.customError).toBe(false);
         expect(hiddenElement.validationMessage).toBe('');
 
-        textElement.value = '';
-        textElement.dispatchEvent(new Event('input'));
+        textFormInput.vm.$emit('input', '');
         await nextTick();
 
         expect(wrapper.emitted('valid')).toEqual([
@@ -144,8 +145,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
       });
 
       it('emits invalid with user input', async () => {
-        textElement.value = 'gobbledygook';
-        textElement.dispatchEvent(new Event('input'));
+        textFormInput.vm.$emit('input', 'gobbledygook');
         await nextTick();
 
         expect(wrapper.emitted('valid')).toEqual([
@@ -203,8 +203,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
         });
 
         it('emits valid when input is integer', async () => {
-          textElement.value = '2hr20min';
-          textElement.dispatchEvent(new Event('input'));
+          textFormInput.vm.$emit('input', '2hr20min');
           await nextTick();
 
           expect(wrapper.emitted('change')).toEqual([[MOCK_VALUE]]);
@@ -221,8 +220,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
         });
 
         it('emits valid when input is decimal', async () => {
-          textElement.value = '1.5s';
-          textElement.dispatchEvent(new Event('input'));
+          textFormInput.vm.$emit('input', '1.5s');
           await nextTick();
 
           expect(wrapper.emitted('change')).toEqual([[1.5]]);
@@ -245,8 +243,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
         });
 
         it('emits valid when input is integer', async () => {
-          textElement.value = '2hr20min';
-          textElement.dispatchEvent(new Event('input'));
+          textFormInput.vm.$emit('input', '2hr20min');
           await nextTick();
 
           expect(wrapper.emitted('change')).toEqual([[MOCK_VALUE]]);
@@ -263,8 +260,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
         });
 
         it('emits invalid when input is decimal', async () => {
-          textElement.value = '1.5s';
-          textElement.dispatchEvent(new Event('input'));
+          textFormInput.vm.$emit('input', '1.5s');
           await nextTick();
 
           expect(wrapper.emitted('change')).toBeUndefined();
@@ -310,8 +306,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
       });
 
       it('passes updated prop via v-model', async () => {
-        textElement.value = '2hr20min';
-        textElement.dispatchEvent(new Event('input'));
+        textFormInput.vm.$emit('input', '2hr20min');
         await nextTick();
 
         expect(textElement.value).toBe('2hr20min');
@@ -321,8 +316,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
 
     describe('change', () => {
       it('passes user input to parent via v-model', async () => {
-        textElement.value = '2hr20min';
-        textElement.dispatchEvent(new Event('input'));
+        textFormInput.vm.$emit('input', '2hr20min');
         await nextTick();
 
         expect(wrapper.findComponent(ChronicDurationInput).props('value')).toBe(MOCK_VALUE);
@@ -369,8 +363,7 @@ describe('vue_shared/components/chronic_duration_input', () => {
     });
 
     it('creates form data with user-specified value', async () => {
-      textElement.value = '1m10s';
-      textElement.dispatchEvent(new Event('input'));
+      textFormInput.vm.$emit('input', '1m10s');
       await nextTick();
 
       const formData = new FormData(wrapper.find('[data-testid=myForm]').element);