diff --git a/app/assets/javascripts/vue_shared/gl_feature_flags_plugin.js b/app/assets/javascripts/vue_shared/gl_feature_flags_plugin.js
index c12ffaac40aea5810c1e623580df1576ce006f0f..79946ebaecd19ac831d5e6946572591eebc58941 100644
--- a/app/assets/javascripts/vue_shared/gl_feature_flags_plugin.js
+++ b/app/assets/javascripts/vue_shared/gl_feature_flags_plugin.js
@@ -1,12 +1,14 @@
 export default (Vue) => {
   Vue.mixin({
-    provide: {
-      glFeatures:
-        {
-          ...window.gon?.features,
-          // TODO: extract into glLicensedFeatures https://gitlab.com/gitlab-org/gitlab/-/issues/322460
-          ...window.gon?.licensed_features,
-        } || {},
+    provide() {
+      return {
+        glFeatures:
+          {
+            ...window.gon?.features,
+            // TODO: extract into glLicensedFeatures https://gitlab.com/gitlab-org/gitlab/-/issues/322460
+            ...window.gon?.licensed_features,
+          } || {},
+      };
     },
   });
 };
diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss
index ac74096e97c7f9d6482fbbdfe926475304a5ab2e..2bce432fee27ed86ec008b8d0ed7aa259b375e2e 100644
--- a/app/assets/stylesheets/startup/startup-dark.scss
+++ b/app/assets/stylesheets/startup/startup-dark.scss
@@ -132,10 +132,6 @@ kbd kbd {
 }
 @media (prefers-reduced-motion: reduce) {
 }
-.form-control:-moz-focusring {
-  color: transparent;
-  text-shadow: 0 0 0 #ececef;
-}
 .form-control::placeholder {
   color: #a4a3a8;
   opacity: 1;
diff --git a/app/assets/stylesheets/startup/startup-general.scss b/app/assets/stylesheets/startup/startup-general.scss
index fc3da60d3b8f395d40f58b091a92743ff0b92662..4d5b1aade01515022228c15de20fc50f4285f7d8 100644
--- a/app/assets/stylesheets/startup/startup-general.scss
+++ b/app/assets/stylesheets/startup/startup-general.scss
@@ -132,10 +132,6 @@ kbd kbd {
 }
 @media (prefers-reduced-motion: reduce) {
 }
-.form-control:-moz-focusring {
-  color: transparent;
-  text-shadow: 0 0 0 #333238;
-}
 .form-control::placeholder {
   color: #626168;
   opacity: 1;
diff --git a/app/assets/stylesheets/startup/startup-signin.scss b/app/assets/stylesheets/startup/startup-signin.scss
index 3aace601c45bb07edf1b7a35678a5b878a7cce64..da541d7acf1f33be651253cb570dd4abc1f5c130 100644
--- a/app/assets/stylesheets/startup/startup-signin.scss
+++ b/app/assets/stylesheets/startup/startup-signin.scss
@@ -205,10 +205,6 @@ hr {
 }
 @media (prefers-reduced-motion: reduce) {
 }
-.form-control:-moz-focusring {
-  color: transparent;
-  text-shadow: 0 0 0 #333238;
-}
 .form-control::placeholder {
   color: #626168;
   opacity: 1;
@@ -262,7 +258,7 @@ input.btn-block[type="button"] {
   display: block;
   min-height: 1.5rem;
   padding-left: 1.5rem;
-  color-adjust: exact;
+  print-color-adjust: exact;
 }
 .custom-control-input {
   position: absolute;
@@ -303,7 +299,7 @@ input.btn-block[type="button"] {
   pointer-events: none;
   content: "";
   background-color: #fff;
-  border: #737278 solid 1px;
+  border: 1px solid #737278;
 }
 .custom-control-label::after {
   position: absolute;
@@ -313,7 +309,7 @@ input.btn-block[type="button"] {
   width: 1rem;
   height: 1rem;
   content: "";
-  background: no-repeat 50% / 50% 50%;
+  background: 50% / 50% 50% no-repeat;
 }
 .custom-checkbox .custom-control-label::before {
   border-radius: 0.25rem;
diff --git a/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table.vue b/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table.vue
index 7e6fe06ac87b1b294027015692446077992dace8..57cd539c10fa766d907c79e0b8fbc2031ca2e04b 100644
--- a/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table.vue
+++ b/ee/app/assets/javascripts/analytics/analytics_dashboards/components/visualizations/data_table.vue
@@ -29,7 +29,6 @@ export default {
       return Object.keys(this.data[0]).map((key) => ({
         key,
         tdClass: 'gl-text-truncate gl-max-w-0',
-        thClass: 'gl-bg-transparent!',
       }));
     },
   },
diff --git a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
index dbc51d71e2f4c361eae94e089db7e2fa33bac8ec..0842582568e821e883aaa34f21cc33b10e9e1fcf 100644
--- a/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
+++ b/ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_report/vulnerability_list.vue
@@ -252,7 +252,6 @@ export default {
       no-sort-reset
       stacked="sm"
       show-empty
-      responsive
       hover
       primary-key="id"
       :tbody-tr-class="{ 'gl-cursor-pointer': canAdminVulnerability }"
diff --git a/ee/app/assets/stylesheets/components/vulnerability_list.scss b/ee/app/assets/stylesheets/components/vulnerability_list.scss
index 10bf1d6a7b4dfb2d9cdbd846a1da700482cd27a2..d69cce3d9ddeced1e53453dd89f5681288dab883 100644
--- a/ee/app/assets/stylesheets/components/vulnerability_list.scss
+++ b/ee/app/assets/stylesheets/components/vulnerability_list.scss
@@ -82,7 +82,8 @@ $selection-summary-with-error-height: 118px;
   // Due to position: sticky not being supported on Chrome (https://caniuse.com/#feat=css-sticky),
   // the property is assigned to the th element as a workaround
   thead th {
-    @include gl-sticky;
+    // The !important works around https://github.com/bootstrap-vue/bootstrap-vue/pull/6371.
+    position: sticky !important;
     @include gl-border-top-0;
     // The checkboxes use z-index: 1, so we need to place the headers higher so that the checkboxes
     // don't show on top of the headers when scrolling down.
diff --git a/ee/app/assets/stylesheets/startup/startup-dark.scss b/ee/app/assets/stylesheets/startup/startup-dark.scss
index ac74096e97c7f9d6482fbbdfe926475304a5ab2e..2bce432fee27ed86ec008b8d0ed7aa259b375e2e 100644
--- a/ee/app/assets/stylesheets/startup/startup-dark.scss
+++ b/ee/app/assets/stylesheets/startup/startup-dark.scss
@@ -132,10 +132,6 @@ kbd kbd {
 }
 @media (prefers-reduced-motion: reduce) {
 }
-.form-control:-moz-focusring {
-  color: transparent;
-  text-shadow: 0 0 0 #ececef;
-}
 .form-control::placeholder {
   color: #a4a3a8;
   opacity: 1;
diff --git a/ee/app/assets/stylesheets/startup/startup-general.scss b/ee/app/assets/stylesheets/startup/startup-general.scss
index fc3da60d3b8f395d40f58b091a92743ff0b92662..4d5b1aade01515022228c15de20fc50f4285f7d8 100644
--- a/ee/app/assets/stylesheets/startup/startup-general.scss
+++ b/ee/app/assets/stylesheets/startup/startup-general.scss
@@ -132,10 +132,6 @@ kbd kbd {
 }
 @media (prefers-reduced-motion: reduce) {
 }
-.form-control:-moz-focusring {
-  color: transparent;
-  text-shadow: 0 0 0 #333238;
-}
 .form-control::placeholder {
   color: #626168;
   opacity: 1;
diff --git a/ee/app/assets/stylesheets/startup/startup-signin.scss b/ee/app/assets/stylesheets/startup/startup-signin.scss
index 3aace601c45bb07edf1b7a35678a5b878a7cce64..da541d7acf1f33be651253cb570dd4abc1f5c130 100644
--- a/ee/app/assets/stylesheets/startup/startup-signin.scss
+++ b/ee/app/assets/stylesheets/startup/startup-signin.scss
@@ -205,10 +205,6 @@ hr {
 }
 @media (prefers-reduced-motion: reduce) {
 }
-.form-control:-moz-focusring {
-  color: transparent;
-  text-shadow: 0 0 0 #333238;
-}
 .form-control::placeholder {
   color: #626168;
   opacity: 1;
@@ -262,7 +258,7 @@ input.btn-block[type="button"] {
   display: block;
   min-height: 1.5rem;
   padding-left: 1.5rem;
-  color-adjust: exact;
+  print-color-adjust: exact;
 }
 .custom-control-input {
   position: absolute;
@@ -303,7 +299,7 @@ input.btn-block[type="button"] {
   pointer-events: none;
   content: "";
   background-color: #fff;
-  border: #737278 solid 1px;
+  border: 1px solid #737278;
 }
 .custom-control-label::after {
   position: absolute;
@@ -313,7 +309,7 @@ input.btn-block[type="button"] {
   width: 1rem;
   height: 1rem;
   content: "";
-  background: no-repeat 50% / 50% 50%;
+  background: 50% / 50% 50% no-repeat;
 }
 .custom-checkbox .custom-control-label::before {
   border-radius: 0.25rem;
diff --git a/ee/spec/frontend/analytics/analytics_dashboards/components/visualizations/data_table_spec.js b/ee/spec/frontend/analytics/analytics_dashboards/components/visualizations/data_table_spec.js
index e7598b38548df21ef137bd4a64b951688551b94b..ba20a31ec3fe76661764be037952e9856da44df7 100644
--- a/ee/spec/frontend/analytics/analytics_dashboards/components/visualizations/data_table_spec.js
+++ b/ee/spec/frontend/analytics/analytics_dashboards/components/visualizations/data_table_spec.js
@@ -43,7 +43,6 @@ describe('DataTable Visualization', () => {
 
       ['Field One', 'Field Two'].forEach((headerText, idx) => {
         expect(headers.at(idx).text()).toBe(headerText);
-        expect(headers.at(idx).classes()).toContain('gl-bg-transparent!');
       });
     });
 
diff --git a/ee/spec/frontend/analytics/code_review_analytics/components/__snapshots__/merge_request_table_spec.js.snap b/ee/spec/frontend/analytics/code_review_analytics/components/__snapshots__/merge_request_table_spec.js.snap
index 1fc2529a415949e9aea462751515bd486d036ba1..ebea0c5ceadc8bd4f32371adb2bda8e40b7ec16b 100644
--- a/ee/spec/frontend/analytics/code_review_analytics/components/__snapshots__/merge_request_table_spec.js.snap
+++ b/ee/spec/frontend/analytics/code_review_analytics/components/__snapshots__/merge_request_table_spec.js.snap
@@ -2,10 +2,9 @@
 
 exports[`MergeRequestTable component template matches the snapshot 1`] = `
 <table
-  aria-busy="false"
+  aria-busy=""
   aria-colcount="7"
-  aria-describedby="__BVID__36__caption_"
-  class="table b-table gl-table my-3 b-table-stacked-sm"
+  class="table b-table my-3 gl-table b-table-stacked-sm"
   id="__BVID__36"
   role="table"
 >
diff --git a/ee/spec/frontend/boards/components/__snapshots__/board_content_sidebar_spec.js.snap b/ee/spec/frontend/boards/components/__snapshots__/board_content_sidebar_spec.js.snap
index 2d123da6c151e3fc70d5d6d150c0ae1c4ebe4c2f..5a2a4ab72fe8b208e06740a0a25e6bbbb95db9f0 100644
--- a/ee/spec/frontend/boards/components/__snapshots__/board_content_sidebar_spec.js.snap
+++ b/ee/spec/frontend/boards/components/__snapshots__/board_content_sidebar_spec.js.snap
@@ -193,7 +193,7 @@ exports[`ee/BoardContentSidebar incident sidebar matches the snapshot 1`] = `
           <!---->
           <button
             aria-expanded="false"
-            aria-haspopup="true"
+            aria-haspopup="menu"
             class="btn dropdown-toggle btn-default btn-md btn-block gl-button gl-dropdown-toggle"
             id="__BVID__45__BV_toggle_"
             type="button"
diff --git a/ee/spec/frontend/security_orchestration/components/policies/filters/policy_source_filter_spec.js b/ee/spec/frontend/security_orchestration/components/policies/filters/policy_source_filter_spec.js
index 47daca5b3f6665d437857279e5071658be6c4641..678edda4aa8402842d369123818b0554dbe0618d 100644
--- a/ee/spec/frontend/security_orchestration/components/policies/filters/policy_source_filter_spec.js
+++ b/ee/spec/frontend/security_orchestration/components/policies/filters/policy_source_filter_spec.js
@@ -14,7 +14,7 @@ describe('PolicySourceFilter component', () => {
     });
   };
 
-  const findToggle = () => wrapper.find('button[aria-haspopup="true"]');
+  const findToggle = () => wrapper.find('button[aria-haspopup="menu"]');
 
   it.each`
     value                                    | expectedToggleText
diff --git a/ee/spec/frontend/security_orchestration/components/policies/filters/policy_type_filter_spec.js b/ee/spec/frontend/security_orchestration/components/policies/filters/policy_type_filter_spec.js
index 3f3f0b544833f097d81b04d704ec04cbd7c0960f..f1cabf5bd650f98e2212563e2893df1b825acd28 100644
--- a/ee/spec/frontend/security_orchestration/components/policies/filters/policy_type_filter_spec.js
+++ b/ee/spec/frontend/security_orchestration/components/policies/filters/policy_type_filter_spec.js
@@ -14,7 +14,7 @@ describe('PolicyTypeFilter component', () => {
     });
   };
 
-  const findToggle = () => wrapper.find('button[aria-haspopup="true"]');
+  const findToggle = () => wrapper.find('button[aria-haspopup="menu"]');
 
   it.each`
     value                                                          | expectedToggleText
diff --git a/ee/spec/frontend/sidebar/components/iteration/__snapshots__/iteration_dropdown_spec.js.snap b/ee/spec/frontend/sidebar/components/iteration/__snapshots__/iteration_dropdown_spec.js.snap
index a86874dc5d3c400bf95302e5094137543cccaa23..da1ad6aacdf6b64e5e2a700410c15545a5358715 100644
--- a/ee/spec/frontend/sidebar/components/iteration/__snapshots__/iteration_dropdown_spec.js.snap
+++ b/ee/spec/frontend/sidebar/components/iteration/__snapshots__/iteration_dropdown_spec.js.snap
@@ -11,6 +11,7 @@ exports[`IterationDropdown default shows gl-dropdown 1`] = `
   size="md"
   splitbuttontype="button"
   splitclass=",[object Object]"
+  toggleattrs="[object Object]"
   toggleclass=",[object Object]"
   toggletag="button"
   toggletext="Toggle dropdown"
diff --git a/ee/spec/frontend/subscriptions/new/components/__snapshots__/modal_spec.js.snap b/ee/spec/frontend/subscriptions/new/components/__snapshots__/modal_spec.js.snap
index 36fb747dc405d036a60375af43a540170841386e..c24dcdb3af1e990c09147b32ec22e3beb1da45d4 100644
--- a/ee/spec/frontend/subscriptions/new/components/__snapshots__/modal_spec.js.snap
+++ b/ee/spec/frontend/subscriptions/new/components/__snapshots__/modal_spec.js.snap
@@ -4,16 +4,16 @@ exports[`Modal component matches the snapshot 1`] = `
 <b-modal-stub
   canceltitle="Cancel"
   cancelvariant="secondary"
+  footertag="footer"
   headerclosecontent="&times;"
   headercloselabel="Close"
+  headertag="header"
   id="subscription-modal"
-  ignoreenforcefocusselector=""
   lazy="true"
   modalclass="gl-modal,"
   oktitle="OK"
   okvariant="primary"
   size="sm"
-  title=""
   titletag="h4"
 >
   
diff --git a/ee/spec/frontend/vulnerabilities/new_vulnerability/section_details_spec.js b/ee/spec/frontend/vulnerabilities/new_vulnerability/section_details_spec.js
index b54f7fa70399a92170d64d0d70410139293b54b4..fcffbcdbfbd4e54908f6ff963cdeae87cd161296 100644
--- a/ee/spec/frontend/vulnerabilities/new_vulnerability/section_details_spec.js
+++ b/ee/spec/frontend/vulnerabilities/new_vulnerability/section_details_spec.js
@@ -3,6 +3,7 @@ import { GlFormGroup, GlDropdown, GlDropdownItem, GlFormRadio } from '@gitlab/ui
 import { mountExtended } from 'helpers/vue_test_utils_helper';
 import SectionDetails from 'ee/vulnerabilities/components/new_vulnerability/section_details.vue';
 import SeverityBadge from 'ee/vue_shared/security_reports/components/severity_badge.vue';
+import { ERROR_SEVERITY, ERROR_STATUS } from 'ee/vulnerabilities/components/new_vulnerability/i18n';
 
 describe('New vulnerability - Section Details', () => {
   let wrapper;
@@ -92,11 +93,11 @@ describe('New vulnerability - Section Details', () => {
     await nextTick();
 
     // severity input
-    expect(wrapper.findAllByRole('alert').at(0).text()).toBe('Select a severity level');
     expect(findFormGroup(1).attributes('aria-invalid')).toBe('true');
+    expect(findFormGroup(1).text()).toContain(ERROR_SEVERITY);
 
     // status input
-    expect(wrapper.findAllByRole('alert').at(1).text()).toBe('Select a status');
     expect(findFormGroup(2).attributes('aria-invalid')).toBe('true');
+    expect(findFormGroup(2).text()).toContain(ERROR_STATUS);
   });
 });
diff --git a/ee/spec/frontend/vulnerabilities/new_vulnerability/section_identifiers_spec.js b/ee/spec/frontend/vulnerabilities/new_vulnerability/section_identifiers_spec.js
index 9e16b16b0f2bfca73bbcfefa5a773dfa51e2e9c5..4889dececd59441b5c11f6822708371f1a81f235 100644
--- a/ee/spec/frontend/vulnerabilities/new_vulnerability/section_identifiers_spec.js
+++ b/ee/spec/frontend/vulnerabilities/new_vulnerability/section_identifiers_spec.js
@@ -2,6 +2,10 @@ import { nextTick } from 'vue';
 import { GlFormGroup } from '@gitlab/ui';
 import { mountExtended } from 'helpers/vue_test_utils_helper';
 import SectionIdentifiers from 'ee/vulnerabilities/components/new_vulnerability/section_identifiers.vue';
+import {
+  ERROR_IDENTIFIER_CODE,
+  ERROR_IDENTIFIER_URL,
+} from 'ee/vulnerabilities/components/new_vulnerability/i18n';
 
 describe('New vulnerability - Section Identifiers', () => {
   let wrapper;
@@ -46,10 +50,10 @@ describe('New vulnerability - Section Identifiers', () => {
     await nextTick();
 
     expect(findFormGroup(0).attributes('aria-invalid')).toBe('true');
-    expect(wrapper.findAllByRole('alert').at(0).text()).toBe('Enter the CVE or CWE code');
+    expect(findFormGroup(0).text()).toContain(ERROR_IDENTIFIER_CODE);
 
     expect(findFormGroup(1).attributes('aria-invalid')).toBe('true');
-    expect(wrapper.findAllByRole('alert').at(1).text()).toBe('Enter the CVE or CWE identifier URL');
+    expect(findFormGroup(1).text()).toContain(ERROR_IDENTIFIER_URL);
   });
 
   it('emits change event when input changes', () => {
diff --git a/ee/spec/frontend/vulnerabilities/new_vulnerability/section_name_spec.js b/ee/spec/frontend/vulnerabilities/new_vulnerability/section_name_spec.js
index e971b690173572a0e442026213880964b774791f..bd0076d73a3ca22c52f90fe41cb8fd80d6e9ddc6 100644
--- a/ee/spec/frontend/vulnerabilities/new_vulnerability/section_name_spec.js
+++ b/ee/spec/frontend/vulnerabilities/new_vulnerability/section_name_spec.js
@@ -3,6 +3,7 @@ import { GlFormGroup, GlFormInput, GlFormTextarea } from '@gitlab/ui';
 import { mountExtended } from 'helpers/vue_test_utils_helper';
 import MarkdownField from '~/vue_shared/components/markdown/field.vue';
 import SectionName from 'ee/vulnerabilities/components/new_vulnerability/section_name.vue';
+import { ERROR_NAME } from 'ee/vulnerabilities/components/new_vulnerability/i18n';
 
 describe('New vulnerability - Section Name', () => {
   const markdownDocsPath = '/path/to/markdown/docs';
@@ -76,7 +77,7 @@ describe('New vulnerability - Section Name', () => {
 
     await nextTick();
 
-    expect(wrapper.findByRole('alert').text()).toBe('Enter a name');
     expect(findFormGroup(0).attributes('aria-invalid')).toBe('true');
+    expect(findFormGroup(0).text()).toContain(ERROR_NAME);
   });
 });
diff --git a/package.json b/package.json
index c4d738429d39854459d3c6222ee41923dc69e543..3221161c4808a8448bff2872c5945803d46b15e8 100644
--- a/package.json
+++ b/package.json
@@ -56,7 +56,7 @@
     "@gitlab/favicon-overlay": "2.0.0",
     "@gitlab/fonts": "^1.2.0",
     "@gitlab/svgs": "3.24.0",
-    "@gitlab/ui": "56.2.1",
+    "@gitlab/ui": "56.3.0",
     "@gitlab/visual-review-tools": "1.7.3",
     "@gitlab/web-ide": "0.0.1-dev-20230223005157",
     "@mattiasbuelens/web-streams-adapter": "^0.1.0",
@@ -104,7 +104,7 @@
     "axios": "^0.24.0",
     "babel-loader": "^8.2.5",
     "babel-plugin-lodash": "^3.3.4",
-    "bootstrap": "4.5.3",
+    "bootstrap": "4.6.2",
     "browserslist": "^4.21.3",
     "cache-loader": "^4.1.0",
     "canvas-confetti": "^1.4.0",
diff --git a/spec/features/groups/members/sort_members_spec.rb b/spec/features/groups/members/sort_members_spec.rb
index 5634122ec16bb6ef5dec407f3dd7eb94d931d2d4..fa5a14f18b4fcdd08313c84ea136f1d7bc25a969 100644
--- a/spec/features/groups/members/sort_members_spec.rb
+++ b/spec/features/groups/members/sort_members_spec.rb
@@ -18,7 +18,7 @@
 
   def expect_sort_by(text, sort_direction)
     within('[data-testid="members-sort-dropdown"]') do
-      expect(page).to have_css('button[aria-haspopup="true"]', text: text)
+      expect(page).to have_css('button[aria-haspopup="menu"]', text: text)
       expect(page).to have_button("Sorting Direction: #{sort_direction == :asc ? 'Ascending' : 'Descending'}")
     end
   end
diff --git a/spec/features/projects/members/sorting_spec.rb b/spec/features/projects/members/sorting_spec.rb
index 6df1e974f42449e17f57925b96f810c0fe187357..78fad9b0b5556b10750da7bdbab15c583670bec0 100644
--- a/spec/features/projects/members/sorting_spec.rb
+++ b/spec/features/projects/members/sorting_spec.rb
@@ -148,7 +148,7 @@ def second_member
 
   def expect_sort_by(text, sort_direction)
     within('[data-testid="members-sort-dropdown"]') do
-      expect(page).to have_css('button[aria-haspopup="true"]', text: text)
+      expect(page).to have_css('button[aria-haspopup="menu"]', text: text)
       expect(page).to have_button("Sorting Direction: #{sort_direction == :asc ? 'Ascending' : 'Descending'}")
     end
   end
diff --git a/spec/frontend/ci_secure_files/components/metadata/__snapshots__/modal_spec.js.snap b/spec/frontend/ci_secure_files/components/metadata/__snapshots__/modal_spec.js.snap
index b2084e3a7deffe9272c2c128626581b6807885a2..1be89ae832ddc658b5d2dfc39d644d6790c86299 100644
--- a/spec/frontend/ci_secure_files/components/metadata/__snapshots__/modal_spec.js.snap
+++ b/spec/frontend/ci_secure_files/components/metadata/__snapshots__/modal_spec.js.snap
@@ -15,7 +15,7 @@ exports[`Secure File Metadata Modal when a .cer file is supplied matches cer the
   >
      
     <table
-      aria-busy="false"
+      aria-busy=""
       aria-colcount="2"
       class="table b-table gl-table"
       role="table"
@@ -196,7 +196,7 @@ exports[`Secure File Metadata Modal when a .mobileprovision file is supplied mat
   >
      
     <table
-      aria-busy="false"
+      aria-busy=""
       aria-colcount="2"
       class="table b-table gl-table"
       role="table"
diff --git a/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap b/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap
index 656e72baf7786b5ac3a37e63d6e92aefbf5dc795..21ffda8578a6d8bc0376fd00cb99d9bd71f8fbdc 100644
--- a/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap
+++ b/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap
@@ -3,7 +3,7 @@
 exports[`NewCluster renders the cluster component correctly 1`] = `
 "<div class=\\"gl-pt-4\\">
   <h4>Enter your Kubernetes cluster certificate details</h4>
-  <p>Enter details about your cluster. <b-link-stub href=\\"/help/user/project/clusters/add_existing_cluster\\" event=\\"click\\" routertag=\\"a\\" class=\\"gl-link\\">How do I use a certificate to connect to my cluster?</b-link-stub>
+  <p>Enter details about your cluster. <b-link-stub href=\\"/help/user/project/clusters/add_existing_cluster\\" class=\\"gl-link\\">How do I use a certificate to connect to my cluster?</b-link-stub>
   </p>
 </div>"
 `;
diff --git a/spec/frontend/content_editor/components/__snapshots__/toolbar_button_spec.js.snap b/spec/frontend/content_editor/components/__snapshots__/toolbar_button_spec.js.snap
index a63cca006dad6472babb3bd5722a93c935a2aa7f..b8e6bcbc3c4f71e09b844316c1be3dbe08c7e918 100644
--- a/spec/frontend/content_editor/components/__snapshots__/toolbar_button_spec.js.snap
+++ b/spec/frontend/content_editor/components/__snapshots__/toolbar_button_spec.js.snap
@@ -1,7 +1,7 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
 exports[`content_editor/components/toolbar_button displays tertiary, medium button with a provided label and icon 1`] = `
-"<b-button-stub size=\\"md\\" variant=\\"default\\" type=\\"button\\" tag=\\"button\\" aria-label=\\"Bold\\" title=\\"Bold\\" class=\\"gl-button btn-default-tertiary btn-icon\\">
+"<b-button-stub size=\\"md\\" tag=\\"button\\" type=\\"button\\" variant=\\"default\\" aria-label=\\"Bold\\" title=\\"Bold\\" class=\\"gl-button btn-default-tertiary btn-icon\\">
   <!---->
   <gl-icon-stub name=\\"bold\\" size=\\"16\\" class=\\"gl-button-icon\\"></gl-icon-stub>
   <!---->
diff --git a/spec/frontend/invite_members/components/group_select_spec.js b/spec/frontend/invite_members/components/group_select_spec.js
index 94bcd2b60a108c4439496946575732b50d15018b..75b91c89bd5b204530299bc6ad97a915cc1aae92 100644
--- a/spec/frontend/invite_members/components/group_select_spec.js
+++ b/spec/frontend/invite_members/components/group_select_spec.js
@@ -28,7 +28,7 @@ describe('GroupSelect', () => {
 
   const findSearchBoxByType = () => wrapper.findComponent(GlSearchBoxByType);
   const findDropdown = () => wrapper.findComponent(GlDropdown);
-  const findDropdownToggle = () => findDropdown().find('button[aria-haspopup="true"]');
+  const findDropdownToggle = () => findDropdown().find('button[aria-haspopup="menu"]');
   const findAvatarByLabel = (text) =>
     wrapper
       .findAllComponents(GlAvatarLabeled)
diff --git a/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap b/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap
index 40e627262db23a468405a3c94f855acc27aa8c84..6766456d09c0984ebf9a7dd04c48d6739fb86fb8 100644
--- a/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap
+++ b/spec/frontend/jira_import/components/__snapshots__/jira_import_form_spec.js.snap
@@ -2,7 +2,7 @@
 
 exports[`JiraImportForm table body shows correct information in each cell 1`] = `
 <table
-  aria-busy="false"
+  aria-busy=""
   aria-colcount="3"
   class="table b-table gl-table b-table-fixed"
   role="table"
@@ -92,7 +92,7 @@ exports[`JiraImportForm table body shows correct information in each cell 1`] =
           <!---->
           <button
             aria-expanded="false"
-            aria-haspopup="true"
+            aria-haspopup="menu"
             class="btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle"
             type="button"
           >
@@ -217,7 +217,7 @@ exports[`JiraImportForm table body shows correct information in each cell 1`] =
           <!---->
           <button
             aria-expanded="false"
-            aria-haspopup="true"
+            aria-haspopup="menu"
             class="btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle"
             type="button"
           >
diff --git a/spec/frontend/members/components/filter_sort/sort_dropdown_spec.js b/spec/frontend/members/components/filter_sort/sort_dropdown_spec.js
index ef3c8bde3cf96416ffeeb0818227e3d6f17c01d4..526f839ece87b6572ecae117efa9d50d4f5aa759 100644
--- a/spec/frontend/members/components/filter_sort/sort_dropdown_spec.js
+++ b/spec/frontend/members/components/filter_sort/sort_dropdown_spec.js
@@ -46,7 +46,7 @@ describe('SortDropdown', () => {
   const findSortingComponent = () => wrapper.findComponent(GlSorting);
   const findSortDirectionToggle = () =>
     findSortingComponent().find('button[title^="Sort direction"]');
-  const findDropdownToggle = () => wrapper.find('button[aria-haspopup="true"]');
+  const findDropdownToggle = () => wrapper.find('button[aria-haspopup="menu"]');
   const findDropdownItemByText = (text) =>
     wrapper
       .findAllComponents(GlSortingItem)
diff --git a/spec/frontend/members/components/table/role_dropdown_spec.js b/spec/frontend/members/components/table/role_dropdown_spec.js
index 0b07311db294839ac8c77bbd3b4c5dfc629e0c97..60790640316f97b43cbd6457421fe8a54469fccc 100644
--- a/spec/frontend/members/components/table/role_dropdown_spec.js
+++ b/spec/frontend/members/components/table/role_dropdown_spec.js
@@ -67,7 +67,7 @@ describe('RoleDropdown', () => {
       .findAllComponents(GlDropdownItem)
       .wrappers.find((dropdownItemWrapper) => dropdownItemWrapper.props('isChecked'));
 
-  const findDropdownToggle = () => wrapper.find('button[aria-haspopup="true"]');
+  const findDropdownToggle = () => wrapper.find('button[aria-haspopup="menu"]');
   const findDropdown = () => wrapper.findComponent(GlDropdown);
 
   let originalGon;
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap
index 801cde8582e54a64d615c105711b36526050d0ce..d0841c6110f01cc3e643475e46d5046804675fbf 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/__snapshots__/packages_list_app_spec.js.snap
@@ -49,9 +49,7 @@ exports[`packages_list_app renders 1`] = `
             Learn how to 
             <b-link-stub
               class="gl-link"
-              event="click"
               href="helpUrl"
-              routertag="a"
               target="_blank"
             >
               publish and share your packages
diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap
index b2375da7b118744f4f2b6409e87adfa1492e0276..5d390730ef11d0e5c6753691bf95e6ef41c70dd2 100644
--- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap
+++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/pypi_installation_spec.js.snap
@@ -20,7 +20,7 @@ exports[`PypiInstallation renders all the messages 1`] = `
         <!---->
         <button
           aria-expanded="false"
-          aria-haspopup="true"
+          aria-haspopup="menu"
           class="btn dropdown-toggle btn-default btn-md gl-button gl-dropdown-toggle"
           id="__BVID__27__BV_toggle_"
           type="button"
@@ -59,7 +59,6 @@ exports[`PypiInstallation renders all the messages 1`] = `
   </div>
    
   <fieldset
-    aria-describedby="installation-pip-command-group__BV_description_"
     class="form-group gl-form-group"
     id="installation-pip-command-group"
   >
@@ -75,12 +74,7 @@ exports[`PypiInstallation renders all the messages 1`] = `
        
       <!---->
     </legend>
-    <div
-      aria-labelledby="installation-pip-command-group__BV_label_"
-      class="bv-no-focus-ring"
-      role="group"
-      tabindex="-1"
-    >
+    <div>
       <div
         data-testid="pip-command"
         id="installation-pip-command"
diff --git a/yarn.lock b/yarn.lock
index b02d803a9a3a91fd108ebccde90ecce0bdf30d21..5f133bdb49eeb5d79a2c0398a493ba80f30fdb6d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1226,13 +1226,13 @@
   resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-3.24.0.tgz#bc8265919aa04b06cd08be91637471bad195936d"
   integrity sha512-R4s5qJUFUIbPflknpw1aI/PchiNq65vY7LVsJZnQkY+vi+AgmsETdut/AdferbGWmeWMU0q2wuVu9phE8lDUgA==
 
-"@gitlab/ui@56.2.1":
-  version "56.2.1"
-  resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-56.2.1.tgz#ca503f5b70a912c98da6bb30f9e22b6fff710d72"
-  integrity sha512-WeTNZT+Bo3jZ2gv7efuTyu4fm5Ks6KbpBLaJmyFtDMe38+o0RpgRgMjc+Zh0nLP3RuejhBUPkYsK9WxhdVmiog==
+"@gitlab/ui@56.3.0":
+  version "56.3.0"
+  resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-56.3.0.tgz#6503564f852db6b414ac6e5f224754be7bcc2edf"
+  integrity sha512-HXechAWiHN9IgDHHrxFjDNhfVDTpivliL780sRGrJbzlPxqbvsk/jPW+PdSdDOhkXoZe9seEfaDRdF5eb+QoQQ==
   dependencies:
     "@popperjs/core" "^2.11.2"
-    bootstrap-vue "2.20.1"
+    bootstrap-vue "2.23.1"
     dompurify "^2.4.5"
     echarts "^5.3.2"
     iframe-resizer "^4.3.2"
@@ -3352,21 +3352,21 @@ boolbase@^1.0.0:
   resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
   integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
 
-bootstrap-vue@2.20.1:
-  version "2.20.1"
-  resolved "https://registry.yarnpkg.com/bootstrap-vue/-/bootstrap-vue-2.20.1.tgz#1b6cd4368632c1a6dd4a5ed161242baa131c3cd5"
-  integrity sha512-s+w83q0T2mo/RbFwTM8gExbLJMEOYpdTUqmyFaHv2Ir+TFprMvTWpeAzeNuawJ130W1gePZ3LW3cNp1t/tZbOw==
+bootstrap-vue@2.23.1:
+  version "2.23.1"
+  resolved "https://registry.yarnpkg.com/bootstrap-vue/-/bootstrap-vue-2.23.1.tgz#8f866f7cda27eb0e7e13a0bea8d55d8fc7a82199"
+  integrity sha512-SEWkG4LzmMuWjQdSYmAQk1G/oOKm37dtNfjB5kxq0YafnL2W6qUAmeDTcIZVbPiQd2OQlIkWOMPBRGySk/zGsg==
   dependencies:
     "@nuxt/opencollective" "^0.3.2"
-    bootstrap ">=4.5.3 <5.0.0"
+    bootstrap "^4.6.1"
     popper.js "^1.16.1"
     portal-vue "^2.1.7"
     vue-functional-data-merge "^3.1.0"
 
-bootstrap@4.5.3, "bootstrap@>=4.5.3 <5.0.0":
-  version "4.5.3"
-  resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6"
-  integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ==
+bootstrap@4.6.2, bootstrap@^4.6.1:
+  version "4.6.2"
+  resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.2.tgz#8e0cd61611728a5bf65a3a2b8d6ff6c77d5d7479"
+  integrity sha512-51Bbp/Uxr9aTuy6ca/8FbFloBUJZLHwnhTcnjIeRn2suQWsWzcuJhGjKDB5eppVte/8oCdOL3VuwxvZDUggwGQ==
 
 brace-expansion@^1.1.7:
   version "1.1.11"