diff --git a/app/assets/javascripts/vue_shared/components/actions_button.vue b/app/assets/javascripts/vue_shared/components/actions_button.vue
index 175aef59ae553ac45cc116dff1ff12d773ee1c17..c3f3226c46e38e8961cb92f79d5d532cccb2c121 100644
--- a/app/assets/javascripts/vue_shared/components/actions_button.vue
+++ b/app/assets/javascripts/vue_shared/components/actions_button.vue
@@ -1,29 +1,25 @@
 <script>
-import { GlDropdown, GlDropdownItem, GlDropdownDivider, GlButton, GlTooltip } from '@gitlab/ui';
+import {
+  GlDisclosureDropdown,
+  GlDisclosureDropdownGroup,
+  GlDisclosureDropdownItem,
+} from '@gitlab/ui';
 
 export default {
   components: {
-    GlDropdown,
-    GlDropdownItem,
-    GlDropdownDivider,
-    GlButton,
-    GlTooltip,
+    GlDisclosureDropdown,
+    GlDisclosureDropdownGroup,
+    GlDisclosureDropdownItem,
   },
   props: {
-    id: {
+    toggleText: {
       type: String,
-      required: false,
-      default: '',
+      required: true,
     },
     actions: {
       type: Array,
       required: true,
     },
-    selectedKey: {
-      type: String,
-      required: false,
-      default: '',
-    },
     category: {
       type: String,
       required: false,
@@ -34,78 +30,40 @@ export default {
       required: false,
       default: 'default',
     },
-    showActionTooltip: {
-      type: Boolean,
-      required: false,
-      default: true,
-    },
-  },
-  computed: {
-    hasMultipleActions() {
-      return this.actions.length > 1;
-    },
-    selectedAction() {
-      return this.actions.find((x) => x.key === this.selectedKey) || this.actions[0];
-    },
   },
   methods: {
     handleItemClick(action) {
-      this.$emit('select', action.key);
-    },
-    handleClick(action, evt) {
-      this.$emit('actionClicked', { action });
-      return action.handle?.(evt);
+      return action.handle?.();
     },
   },
 };
 </script>
 
 <template>
-  <span>
-    <gl-dropdown
-      v-if="hasMultipleActions"
-      :id="id"
-      :text="selectedAction.text"
-      :split-href="selectedAction.href"
-      :variant="variant"
-      :category="category"
-      split
-      data-qa-selector="action_dropdown"
-      @click="handleClick(selectedAction, $event)"
-    >
-      <template #button-content>
-        <span class="gl-dropdown-button-text" v-bind="selectedAction.attrs">
-          {{ selectedAction.text }}
-        </span>
-      </template>
-      <template v-for="(action, index) in actions">
-        <gl-dropdown-item
-          :key="action.key"
-          is-check-item
-          :is-checked="action.key === selectedAction.key"
-          :secondary-text="action.secondaryText"
-          :data-qa-selector="`${action.key}_menu_item`"
-          :data-testid="`action_${action.key}`"
-          @click="handleItemClick(action)"
-        >
-          <span class="gl-font-weight-bold">{{ action.text }}</span>
-        </gl-dropdown-item>
-        <gl-dropdown-divider v-if="index != actions.length - 1" :key="action.key + '_divider'" />
-      </template>
-    </gl-dropdown>
-    <gl-button
-      v-else-if="selectedAction"
-      :id="id"
-      v-bind="selectedAction.attrs"
-      :variant="variant"
-      :category="category"
-      :href="selectedAction.href"
-      @click="handleClick(selectedAction, $event)"
-    >
-      {{ selectedAction.text }}
-    </gl-button>
-    <gl-tooltip v-if="selectedAction.tooltip && showActionTooltip" :target="id">
-      {{ selectedAction.tooltip }}
-    </gl-tooltip>
-  </span>
+  <gl-disclosure-dropdown
+    :variant="variant"
+    :category="category"
+    :toggle-text="toggleText"
+    data-qa-selector="action_dropdown"
+  >
+    <gl-disclosure-dropdown-group>
+      <gl-disclosure-dropdown-item
+        v-for="action in actions"
+        :key="action.key"
+        v-bind="action.attrs"
+        :item="action"
+        :data-qa-selector="`${action.key}_menu_item`"
+        @action="handleItemClick(action)"
+      >
+        <template #list-item>
+          <div class="gl-display-flex gl-flex-direction-column">
+            <span class="gl-font-weight-bold gl-mb-2">{{ action.text }}</span>
+            <span class="gl-text-gray-700">
+              {{ action.secondaryText }}
+            </span>
+          </div>
+        </template>
+      </gl-disclosure-dropdown-item>
+    </gl-disclosure-dropdown-group>
+  </gl-disclosure-dropdown>
 </template>
diff --git a/app/assets/javascripts/vue_shared/components/web_ide_link.vue b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
index 3c08142e2b926dff0e360759886c53aecdb9af87..96944877f618248522e0e490c6b5c0f7c3ee3ae6 100644
--- a/app/assets/javascripts/vue_shared/components/web_ide_link.vue
+++ b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
@@ -3,9 +3,7 @@ import { GlModal, GlSprintf, GlLink } from '@gitlab/ui';
 import { s__, __ } from '~/locale';
 import { visitUrl } from '~/lib/utils/url_utility';
 import ActionsButton from '~/vue_shared/components/actions_button.vue';
-import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
 import ConfirmForkModal from '~/vue_shared/components/confirm_fork_modal.vue';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
 import { KEY_EDIT, KEY_WEB_IDE, KEY_GITPOD, KEY_PIPELINE_EDITOR } from './constants';
 
 export const i18n = {
@@ -21,22 +19,18 @@ export const i18n = {
   webIdeTooltip: s__(
     'WebIDE|Quickly and easily edit multiple files in your project. Press . to open',
   ),
+  toggleText: __('Edit'),
 };
 
-export const PREFERRED_EDITOR_KEY = 'gl-web-ide-button-selected';
-export const PREFERRED_EDITOR_RESET_KEY = 'gl-web-ide-button-selected-reset';
-
 export default {
   components: {
     ActionsButton,
-    LocalStorageSync,
     GlModal,
     GlSprintf,
     GlLink,
     ConfirmForkModal,
   },
   i18n,
-  mixins: [glFeatureFlagsMixin()],
   props: {
     isFork: {
       type: Boolean,
@@ -141,7 +135,6 @@ export default {
   },
   data() {
     return {
-      selection: this.showPipelineEditorButton ? KEY_PIPELINE_EDITOR : KEY_WEB_IDE,
       showEnableGitpodModal: false,
       showForkModal: false,
     };
@@ -155,6 +148,9 @@ export default {
         this.gitpodAction,
       ].filter((action) => action);
     },
+    hasActions() {
+      return this.actions.length > 0;
+    },
     editAction() {
       if (!this.showEditButton) {
         return null;
@@ -176,9 +172,8 @@ export default {
 
       return {
         key: KEY_EDIT,
-        text: __('Edit'),
+        text: __('Edit single file'),
         secondaryText: __('Edit this file only.'),
-        tooltip: '',
         attrs: {
           'data-qa-selector': 'edit_button',
           'data-track-action': 'click_consolidated_edit',
@@ -205,7 +200,6 @@ export default {
 
       const handleOptions = this.needsToFork
         ? {
-            href: '#modal-confirm-fork-webide',
             handle: () => {
               if (this.disableForkModal) {
                 this.$emit('edit', 'ide');
@@ -216,9 +210,7 @@ export default {
             },
           }
         : {
-            href: this.webIdeUrl,
-            handle: (evt) => {
-              evt.preventDefault();
+            handle: () => {
               visitUrl(this.webIdeUrl, true);
             },
           };
@@ -227,7 +219,6 @@ export default {
         key: KEY_WEB_IDE,
         text: this.webIdeActionText,
         secondaryText: this.$options.i18n.webIdeText,
-        tooltip: this.$options.i18n.webIdeTooltip,
         attrs: {
           'data-qa-selector': 'web_ide_button',
           'data-track-action': 'click_consolidated_edit_ide',
@@ -258,7 +249,6 @@ export default {
         key: KEY_PIPELINE_EDITOR,
         text: __('Edit in pipeline editor'),
         secondaryText,
-        tooltip: secondaryText,
         attrs: {
           'data-qa-selector': 'pipeline_editor_button',
         },
@@ -283,7 +273,6 @@ export default {
         key: KEY_GITPOD,
         text: this.gitpodActionText,
         secondaryText,
-        tooltip: secondaryText,
         attrs: {
           'data-qa-selector': 'gitpod_button',
         },
@@ -310,52 +299,24 @@ export default {
       };
     },
   },
-  mounted() {
-    this.resetPreferredEditor();
-  },
   methods: {
-    select(key) {
-      this.selection = key;
-    },
     showModal(dataKey) {
       this[dataKey] = true;
     },
-    resetPreferredEditor() {
-      if (!this.glFeatures.vscodeWebIde || this.showEditButton) {
-        return;
-      }
-
-      if (localStorage.getItem(PREFERRED_EDITOR_RESET_KEY) === 'true') {
-        return;
-      }
-
-      localStorage.setItem(PREFERRED_EDITOR_KEY, KEY_WEB_IDE);
-      localStorage.setItem(PREFERRED_EDITOR_RESET_KEY, true);
-
-      this.select(KEY_WEB_IDE);
-    },
   },
   webIdeButtonId: 'web-ide-link',
-  PREFERRED_EDITOR_KEY,
 };
 </script>
 
 <template>
   <div class="gl-sm-ml-3">
     <actions-button
+      v-if="hasActions"
       :id="$options.webIdeButtonId"
       :actions="actions"
-      :selected-key="selection"
+      :toggle-text="$options.i18n.toggleText"
       :variant="isBlob ? 'confirm' : 'default'"
       :category="isBlob ? 'primary' : 'secondary'"
-      show-action-tooltip
-      @select="select"
-    />
-    <local-storage-sync
-      :storage-key="$options.PREFERRED_EDITOR_KEY"
-      :value="selection"
-      as-string
-      @input="select"
     />
     <gl-modal
       v-if="computedShowGitpodButton && !gitpodEnabled"
diff --git a/doc/development/contributing/index.md b/doc/development/contributing/index.md
index bc8ed6e2cd4b0fe32c581aa879b9cc3d04702f03..17e45f8c96da6dd10850ba9c1ef09bf95614135f 100644
--- a/doc/development/contributing/index.md
+++ b/doc/development/contributing/index.md
@@ -60,8 +60,9 @@ To write and test your code, you will use the GitLab Development Kit.
      consider doing so with an empty rails app and port it to GDK after.
 
    - To run a pre-configured GDK instance in the cloud, use [GDK with Gitpod](../../integration/gitpod.md).
-     From a project's repository, select the caret (angle-down) next to **Web IDE**,
-     and select **Gitpod** from the list.
+     From a project repository:
+       1. On the top bar, select **Main menu > Projects** and find your project.
+       1. In the upper right, select **Edit > Gitpod**.
 1. If you want to contribute to the [website](https://about.gitlab.com/) or the [handbook](https://about.gitlab.com/handbook/),
    go to the footer of any page and select **Edit in Web IDE** to open the [Web IDE](../../user/project/web_ide/index.md).
 
diff --git a/doc/development/documentation/contribute.md b/doc/development/documentation/contribute.md
index 8b08743c6e9474ee48bc10389dd83ce8d94c0916..e86cf4318b84c49997ae8abfaaccd88506fb0963 100644
--- a/doc/development/documentation/contribute.md
+++ b/doc/development/documentation/contribute.md
@@ -50,9 +50,7 @@ When you are ready to update the documentation:
 1. In your fork, find the documentation page in the `\doc` directory.
 1. If you know Git, make your changes and open a merge request.
    If not, follow these steps:
-   1. In the upper-right corner, select **Edit** if it is visible.
-      If it is not, select the down arrow (**{chevron-lg-down}**) next to
-      **Open in Web IDE** or **Gitpod**, and select **Edit**.
+   1. In the upper right, select **Edit > Edit single file**.
    1. In the **Commit message** text box, enter a commit message.
       Use 3-5 words, start with a capital letter, and do not end with a period.
    1. Select **Commit changes**.
diff --git a/doc/integration/gitpod.md b/doc/integration/gitpod.md
index 0ba227c2a8571aeb7adb546976aee420782fb875..c47aca2c7d869ad52b92d8ad515a7b60123924ca 100644
--- a/doc/integration/gitpod.md
+++ b/doc/integration/gitpod.md
@@ -59,16 +59,12 @@ GitLab users can then [enable the Gitpod integration for themselves](#enable-git
 
 You can launch Gitpod directly from GitLab in one of these ways:
 
-- *From your project's page:*
-  1. Go to your project, then go to the page you want to edit.
-  1. Select the caret (**{chevron-lg-down}**) next to **Web IDE**, and select **Gitpod**
-     from the list:
+- **From a project repository:**
+  1. On the top bar, select **Main menu > Projects** and find your project.
+  1. In the upper right, select **Edit > Gitpod**.
 
-     ![Gitpod Button on Project Page](img/gitpod_button_project_page_v13_4.png)
-
-  1. Select **Open in Gitpod**.
-- *From a merge request:*
+- **From a merge request:**
   1. Go to your merge request.
-  1. In the upper-right corner, select **Code**, then select **Open in Gitpod**.
+  1. In the upper-right corner, select **Code > Open in Gitpod**.
 
 Gitpod builds your development environment for your branch.
diff --git a/doc/integration/img/gitpod_button_project_page_v13_4.png b/doc/integration/img/gitpod_button_project_page_v13_4.png
deleted file mode 100644
index 55a70d891699d0377e8f0a0f4d2d86a16723cbaa..0000000000000000000000000000000000000000
Binary files a/doc/integration/img/gitpod_button_project_page_v13_4.png and /dev/null differ
diff --git a/doc/tutorials/dependency_scanning.md b/doc/tutorials/dependency_scanning.md
index c5f65a8affc847285cb3f3e845515a4202edb823..53f329d5bfd320d67af197a2057e483f8c840717 100644
--- a/doc/tutorials/dependency_scanning.md
+++ b/doc/tutorials/dependency_scanning.md
@@ -138,8 +138,8 @@ need to upgrade the `fastify` package.
 
 To fix the vulnerability:
 
-1. Go to **Repository > Files**.
-1. From the **WebIDE** dropdown list select **GitPod**, then right-click on **GitPod** to open
+1. On the top bar, select **Main menu > Projects** and find your project.
+1. In the upper right, select **Edit > GitPod** and open
    GitPod in a new tab.
 1. If you are prompted to, select **Continue with GitLab**, then select **Authorize**.
 1. On the **New Workspace** page, select **Continue**.
diff --git a/doc/user/project/repository/web_editor.md b/doc/user/project/repository/web_editor.md
index dc988846676a5116cd3d9845072ec405a799c998..c81f4e931666b6a897a0a2b449561a30d3b3e43d 100644
--- a/doc/user/project/repository/web_editor.md
+++ b/doc/user/project/repository/web_editor.md
@@ -58,13 +58,7 @@ To edit a text file in the Web Editor:
 
 1. On the top bar, select **Main menu > Projects** and find your project.
 1. Go to your file.
-1. In the upper-right corner of the file, select **Edit**.
-
-   If **Edit** is not visible:
-
-   1. Next to **Open in Web IDE** or **Open in Gitpod**, select the down arrow (**{chevron-lg-down}**).
-   1. From the dropdown list, select **Edit** as your default setting.
-   1. Select **Edit**.
+1. In the upper right, select **Edit > Edit single file**.
 
 ### Keyboard shortcuts
 
diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md
index cb04957a2b6da7caaef43e70231588c4b425a520..1e54566ab3f604240ae7ab484f77856958d15979 100644
--- a/doc/user/project/web_ide/index.md
+++ b/doc/user/project/web_ide/index.md
@@ -36,13 +36,7 @@ You can also open the Web IDE from:
 
 To open the Web IDE from a file or the repository file list:
 
-- In the upper-right corner of the page, select **Open in Web IDE**.
-
-If **Open in Web IDE** is not visible:
-
-1. Next to **Edit** or **Gitpod**, select the down arrow (**{chevron-lg-down}**).
-1. From the dropdown list, select **Open in Web IDE**.
-1. Select **Open in Web IDE**.
+- In the upper right, select **Edit > Open in Web IDE**.
 
 ### From a merge request
 
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d38db8931dd11d8ca7bddae39fe7a2b7da0a2bab..d72b2a6e2a8d54de7fbdfe7e688453716f31ebed 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -16664,6 +16664,9 @@ msgstr ""
 msgid "Edit sidebar"
 msgstr ""
 
+msgid "Edit single file"
+msgstr ""
+
 msgid "Edit table"
 msgstr ""
 
diff --git a/qa/qa/page/file/show.rb b/qa/qa/page/file/show.rb
index 011b1ea5d81a8f5e46eba48cdc876f2a9f806aa2..173baa211606527d288b7283e43f3978fb7785b2 100644
--- a/qa/qa/page/file/show.rb
+++ b/qa/qa/page/file/show.rb
@@ -12,21 +12,15 @@ class Show < Page::Base
           element :lock_button
         end
 
-        view 'app/assets/javascripts/vue_shared/components/web_ide_link.vue' do
-          element :edit_button
-        end
-
         view 'app/assets/javascripts/vue_shared/components/actions_button.vue' do
           element :action_dropdown
           element :edit_menu_item, ':data-qa-selector="`${action.key}_menu_item`"' # rubocop:disable QA/ElementWithPattern
+          element :webide_menu_item, ':data-qa-selector="`${action.key}_menu_item`"' # rubocop:disable QA/ElementWithPattern
         end
 
         def click_edit
-          within_element(:action_dropdown) do
-            click_button(class: 'dropdown-toggle-split')
-            click_element(:edit_menu_item)
-            click_element(:edit_button)
-          end
+          click_element(:action_dropdown)
+          click_element(:edit_menu_item)
         end
 
         def click_delete
diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb
index daaee280b8499b9c720fdf9f27e92721c498effc..95a6c840684adad00f6485eebf46954b4146653d 100644
--- a/qa/qa/page/project/show.rb
+++ b/qa/qa/page/project/show.rb
@@ -62,10 +62,6 @@ class Show < Page::Base
           element :new_file_menu_item
         end
 
-        view 'app/assets/javascripts/vue_shared/components/web_ide_link.vue' do
-          element :web_ide_button
-        end
-
         view 'app/views/projects/blob/viewers/_loading.html.haml' do
           element :spinner_placeholder
         end
@@ -154,7 +150,8 @@ def new_merge_request
         end
 
         def open_web_ide!
-          click_element(:web_ide_button)
+          click_element(:action_dropdown)
+          click_element(:webide_menu_item)
           page.driver.browser.switch_to.window(page.driver.browser.window_handles.last)
         end
 
@@ -164,7 +161,8 @@ def open_web_ide_via_shortcut
         end
 
         def has_edit_fork_button?
-          has_element?(:web_ide_button, text: 'Edit fork in Web IDE')
+          click_element(:action_dropdown)
+          has_element?(:webide_menu_item, text: 'Edit fork in Web IDE')
         end
 
         def project_name
diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb
index 3c68f31074435691292950585abdb73159302dd1..e8a9edcc0cc48187e5d9a1279038f10608d98498 100644
--- a/spec/features/projects/blobs/edit_spec.rb
+++ b/spec/features/projects/blobs/edit_spec.rb
@@ -23,15 +23,11 @@
     end
 
     def edit_and_commit(commit_changes: true, is_diff: false)
-      set_default_button('edit')
-      refresh
-      wait_for_requests
-
       if is_diff
         first('.js-diff-more-actions').click
         click_link('Edit in single-file editor')
       else
-        click_link('Edit')
+        edit_in_single_file_editor
       end
 
       fill_editor(content: 'class NextFeature\\nend\\n')
diff --git a/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb b/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb
index 3e4ee13269f49122091cdc36bf8505cc0ff16db1..bef4e5f89b173a075d9db4fe5e4f5f8460f09d73 100644
--- a/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb
+++ b/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb
@@ -19,6 +19,8 @@
       project.repository.create_file(user, project.ci_config_path_or_default, 'test', message: 'testing', branch_name: 'master')
       visit project_blob_path(project, File.join('master', '.my-config.yml'))
 
+      click_button 'Edit'
+
       expect(page).to have_content('Edit in pipeline editor')
     end
 
@@ -26,6 +28,8 @@
       project.repository.create_file(user, '.my-sub-config.yml', 'test', message: 'testing', branch_name: 'master')
       visit project_blob_path(project, File.join('master', '.my-sub-config.yml'))
 
+      click_button 'Edit'
+
       expect(page).not_to have_content('Edit in pipeline editor')
     end
   end
@@ -36,6 +40,9 @@
     end
     it 'does not shows the Pipeline Editor button' do
       visit project_blob_path(project, File.join('master', '.my-config.yml'))
+
+      click_button 'Edit'
+
       expect(page).not_to have_content('Edit in pipeline editor')
     end
   end
diff --git a/spec/features/projects/files/user_browses_lfs_files_spec.rb b/spec/features/projects/files/user_browses_lfs_files_spec.rb
index 04094ae2d6fa97889949476d6070b69878a0410a..d8c1c8e4f2a33d0b881f29eb1a213428a520a5d2 100644
--- a/spec/features/projects/files/user_browses_lfs_files_spec.rb
+++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb
@@ -71,7 +71,9 @@
         expect(page).not_to have_content('Annotate')
         expect(page).not_to have_content('Blame')
 
-        expect(page).not_to have_selector(:link_or_button, text: /^Edit$/)
+        click_button 'Edit'
+
+        expect(page).not_to have_selector(:link_or_button, text: /^Edit single file$/)
         expect(page).to have_selector(:link_or_button, 'Open in Web IDE')
       end
     end
diff --git a/spec/features/projects/files/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb
index 7d888aabf53f92afda9439213a51eb5713d51a0c..de82f3062a2ee9d6ad56f143ea832f654f4ccceb 100644
--- a/spec/features/projects/files/user_creates_files_spec.rb
+++ b/spec/features/projects/files/user_creates_files_spec.rb
@@ -105,8 +105,6 @@ def submit_new_file(options)
       end
 
       it 'creates and commit a new file with new lines at the end of file' do
-        set_default_button('edit')
-
         editor_set_value('Sample\n\n\n')
         fill_in(:file_name, with: 'not_a_file.md')
         fill_in(:commit_message, with: 'New commit message', visible: true)
@@ -116,7 +114,7 @@ def submit_new_file(options)
 
         expect(page).to have_current_path(new_file_path, ignore_query: true)
 
-        click_link('Edit')
+        edit_in_single_file_editor
 
         expect(find('.monaco-editor')).to have_content('Sample\n\n\n')
       end
diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb
index acaeffe5ef49d8e28c38c17b20bb4e1116703594..10fa4a2135938d5d925add0bec6531897be25469 100644
--- a/spec/features/projects/files/user_edits_files_spec.rb
+++ b/spec/features/projects/files/user_edits_files_spec.rb
@@ -19,10 +19,6 @@
     sign_in(user)
   end
 
-  after do
-    unset_default_button
-  end
-
   shared_examples 'unavailable for an archived project' do
     it 'does not show the edit link for an archived project', :js do
       project.update!(archived: true)
@@ -48,9 +44,8 @@
     end
 
     it 'inserts a content of a file' do
-      set_default_button('edit')
       click_link('.gitignore')
-      click_link_or_button('Edit')
+      edit_in_single_file_editor
       find('.file-editor', match: :first)
 
       editor_set_value('*.rbca')
@@ -69,9 +64,8 @@
     end
 
     it 'commits an edited file' do
-      set_default_button('edit')
       click_link('.gitignore')
-      click_link_or_button('Edit')
+      edit_in_single_file_editor
       find('.file-editor', match: :first)
 
       editor_set_value('*.rbca')
@@ -86,9 +80,8 @@
     end
 
     it 'commits an edited file to a new branch' do
-      set_default_button('edit')
       click_link('.gitignore')
-      click_link_or_button('Edit')
+      edit_in_single_file_editor
 
       find('.file-editor', match: :first)
 
@@ -105,10 +98,8 @@
     end
 
     it 'shows loader on commit changes' do
-      set_default_button('edit')
       click_link('.gitignore')
-      click_link_or_button('Edit')
-
+      edit_in_single_file_editor
       # why: We don't want the form to actually submit, so that we can assert the button's changed state
       page.execute_script("document.querySelector('.js-edit-blob-form').addEventListener('submit', e => e.preventDefault())")
 
@@ -120,9 +111,8 @@
     end
 
     it 'shows the diff of an edited file' do
-      set_default_button('edit')
       click_link('.gitignore')
-      click_link_or_button('Edit')
+      edit_in_single_file_editor
       find('.file-editor', match: :first)
 
       editor_set_value('*.rbca')
@@ -158,9 +148,8 @@ def expect_fork_status
     end
 
     it 'inserts a content of a file in a forked project', :sidekiq_might_not_need_inline do
-      set_default_button('edit')
       click_link('.gitignore')
-      click_link_or_button('Edit')
+      edit_in_single_file_editor
 
       expect_fork_prompt
 
@@ -176,9 +165,8 @@ def expect_fork_status
     end
 
     it 'opens the Web IDE in a forked project', :sidekiq_might_not_need_inline do
-      set_default_button('webide')
       click_link('.gitignore')
-      click_link_or_button('Web IDE')
+      edit_in_web_ide
 
       expect_fork_prompt
 
@@ -191,9 +179,8 @@ def expect_fork_status
     end
 
     it 'commits an edited file in a forked project', :sidekiq_might_not_need_inline do
-      set_default_button('edit')
       click_link('.gitignore')
-      click_link_or_button('Edit')
+      edit_in_single_file_editor
 
       expect_fork_prompt
       click_link_or_button('Fork')
@@ -222,9 +209,8 @@ def expect_fork_status
       end
 
       it 'links to the forked project for editing', :sidekiq_might_not_need_inline do
-        set_default_button('edit')
         click_link('.gitignore')
-        click_link_or_button('Edit')
+        edit_in_single_file_editor
 
         expect(page).not_to have_link('Fork')
 
diff --git a/spec/features/projects/show/user_sees_collaboration_links_spec.rb b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
index a86bc0ae97a21b9f20e0c4163b3ec19ae4a4ec4f..29fb20841fdbe23983287a2afa856073f6a31f86 100644
--- a/spec/features/projects/show/user_sees_collaboration_links_spec.rb
+++ b/spec/features/projects/show/user_sees_collaboration_links_spec.rb
@@ -51,7 +51,8 @@ def find_new_menu_toggle
       end
 
       # The Web IDE
-      expect(page).to have_link('Web IDE')
+      click_button 'Edit'
+      expect(page).to have_button('Web IDE')
     end
 
     it 'hides the links when the project is archived' do
@@ -73,7 +74,7 @@ def find_new_menu_toggle
 
       expect(page).not_to have_selector('[data-testid="add-to-tree"]')
 
-      expect(page).not_to have_link('Web IDE')
+      expect(page).not_to have_button('Edit')
     end
   end
 
@@ -95,7 +96,7 @@ def find_new_menu_toggle
       end
 
       it "updates Web IDE link" do
-        expect(page.has_link?('Web IDE')).to be(expect_ide_link)
+        expect(page.has_button?('Edit')).to be(expect_ide_link)
       end
     end
   end
diff --git a/spec/frontend/vue_shared/components/actions_button_spec.js b/spec/frontend/vue_shared/components/actions_button_spec.js
index 8c2f2b52f8e506039b9bdd0754b30eefd9020109..e7663e2adb2c2c58b10cf1f3edc91cc80bdbbec4 100644
--- a/spec/frontend/vue_shared/components/actions_button_spec.js
+++ b/spec/frontend/vue_shared/components/actions_button_spec.js
@@ -1,12 +1,15 @@
-import { GlDropdown, GlDropdownDivider, GlButton, GlTooltip } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import {
+  GlDisclosureDropdown,
+  GlDisclosureDropdownGroup,
+  GlDisclosureDropdownItem,
+} from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
 import ActionsButton from '~/vue_shared/components/actions_button.vue';
 
 const TEST_ACTION = {
   key: 'action1',
   text: 'Sample',
   secondaryText: 'Lorem ipsum.',
-  tooltip: '',
   href: '/sample',
   attrs: {
     'data-test': '123',
@@ -14,191 +17,75 @@ const TEST_ACTION = {
     href: '/sample',
     variant: 'default',
   },
+  handle: jest.fn(),
 };
 const TEST_ACTION_2 = {
   key: 'action2',
   text: 'Sample 2',
   secondaryText: 'Dolar sit amit.',
-  tooltip: 'Dolar sit amit.',
   href: '#',
   attrs: { 'data-test': '456' },
+  handle: jest.fn(),
 };
-const TEST_TOOLTIP = 'Lorem ipsum dolar sit';
 
-describe('Actions button component', () => {
+describe('vue_shared/components/actions_button', () => {
   let wrapper;
 
   function createComponent(props) {
-    wrapper = shallowMount(ActionsButton, {
-      propsData: { ...props },
+    wrapper = shallowMountExtended(ActionsButton, {
+      propsData: { actions: [TEST_ACTION, TEST_ACTION_2], toggleText: 'Edit', ...props },
+      stubs: {
+        GlDisclosureDropdownItem,
+      },
     });
   }
+  const findDropdown = () => wrapper.findComponent(GlDisclosureDropdown);
 
-  const findButton = () => wrapper.findComponent(GlButton);
-  const findTooltip = () => wrapper.findComponent(GlTooltip);
-  const findDropdown = () => wrapper.findComponent(GlDropdown);
-  const parseDropdownItems = () =>
-    findDropdown()
-      .findAll('gl-dropdown-item-stub,gl-dropdown-divider-stub')
-      .wrappers.map((x) => {
-        if (x.is(GlDropdownDivider)) {
-          return { type: 'divider' };
-        }
-
-        const { isCheckItem, isChecked, secondaryText } = x.props();
-
-        return {
-          type: 'item',
-          isCheckItem,
-          isChecked,
-          secondaryText,
-          text: x.text(),
-        };
-      });
-  const clickOn = (child, evt = new Event('click')) => child.vm.$emit('click', evt);
-  const clickLink = (...args) => clickOn(findButton(), ...args);
-  const clickDropdown = (...args) => clickOn(findDropdown(), ...args);
-
-  describe('with 1 action', () => {
-    beforeEach(() => {
-      createComponent({ actions: [TEST_ACTION] });
-    });
-
-    it('should not render dropdown', () => {
-      expect(findDropdown().exists()).toBe(false);
-    });
-
-    it('should render single button', () => {
-      expect(findButton().attributes()).toMatchObject({
-        href: TEST_ACTION.href,
-        ...TEST_ACTION.attrs,
-      });
-      expect(findButton().text()).toBe(TEST_ACTION.text);
-    });
-
-    it('should not have tooltip', () => {
-      expect(findTooltip().exists()).toBe(false);
-    });
+  it('dropdown toggle displays provided toggleLabel', () => {
+    createComponent();
 
-    it('should have attrs', () => {
-      expect(findButton().attributes()).toMatchObject(TEST_ACTION.attrs);
-    });
-
-    it('can click', () => {
-      expect(clickLink).not.toThrow();
-    });
+    expect(findDropdown().props().toggleText).toBe('Edit');
   });
 
-  describe('with 1 action with tooltip', () => {
-    it('should have tooltip', () => {
-      createComponent({ actions: [{ ...TEST_ACTION, tooltip: TEST_TOOLTIP }] });
+  it('allows customizing variant and category', () => {
+    const variant = 'confirm';
+    const category = 'secondary';
 
-      expect(findTooltip().text()).toBe(TEST_TOOLTIP);
-    });
+    createComponent({ variant, category });
+
+    expect(findDropdown().props()).toMatchObject({ category, variant });
   });
 
-  describe('when showActionTooltip is false', () => {
-    it('should not have tooltip', () => {
-      createComponent({
-        actions: [{ ...TEST_ACTION, tooltip: TEST_TOOLTIP }],
-        showActionTooltip: false,
-      });
+  it('displays a single dropdown group', () => {
+    createComponent();
 
-      expect(findTooltip().exists()).toBe(false);
-    });
+    expect(wrapper.findAllComponents(GlDisclosureDropdownGroup)).toHaveLength(1);
   });
 
-  describe('with 1 action with handle', () => {
-    it('can click and trigger handle', () => {
-      const handleClick = jest.fn();
-      createComponent({ actions: [{ ...TEST_ACTION, handle: handleClick }] });
+  it('create dropdown items for every action', () => {
+    createComponent();
 
-      const event = new Event('click');
-      clickLink(event);
+    [TEST_ACTION, TEST_ACTION_2].forEach((action, index) => {
+      const dropdownItem = wrapper.findAllComponents(GlDisclosureDropdownItem).at(index);
 
-      expect(handleClick).toHaveBeenCalledWith(event);
+      expect(dropdownItem.props().item).toBe(action);
+      expect(dropdownItem.attributes()).toMatchObject(action.attrs);
+      expect(dropdownItem.text()).toContain(action.text);
+      expect(dropdownItem.text()).toContain(action.secondaryText);
     });
   });
 
-  describe('with multiple actions', () => {
-    let handleAction;
+  describe('when clicking a dropdown item', () => {
+    it("invokes the action's handle method", () => {
+      createComponent();
 
-    beforeEach(() => {
-      handleAction = jest.fn();
+      [TEST_ACTION, TEST_ACTION_2].forEach((action, index) => {
+        const dropdownItem = wrapper.findAllComponents(GlDisclosureDropdownItem).at(index);
 
-      createComponent({ actions: [{ ...TEST_ACTION, handle: handleAction }, TEST_ACTION_2] });
-    });
+        dropdownItem.vm.$emit('action');
 
-    it('should default to selecting first action', () => {
-      expect(findDropdown().attributes()).toMatchObject({
-        text: TEST_ACTION.text,
-        'split-href': TEST_ACTION.href,
+        expect(action.handle).toHaveBeenCalled();
       });
     });
-
-    it('should handle first action click', () => {
-      const event = new Event('click');
-
-      clickDropdown(event);
-
-      expect(handleAction).toHaveBeenCalledWith(event);
-    });
-
-    it('should render dropdown items', () => {
-      expect(parseDropdownItems()).toEqual([
-        {
-          type: 'item',
-          isCheckItem: true,
-          isChecked: true,
-          secondaryText: TEST_ACTION.secondaryText,
-          text: TEST_ACTION.text,
-        },
-        { type: 'divider' },
-        {
-          type: 'item',
-          isCheckItem: true,
-          isChecked: false,
-          secondaryText: TEST_ACTION_2.secondaryText,
-          text: TEST_ACTION_2.text,
-        },
-      ]);
-    });
-
-    it('should select action 2 when clicked', () => {
-      expect(wrapper.emitted('select')).toBeUndefined();
-
-      const action2 = wrapper.find(`[data-testid="action_${TEST_ACTION_2.key}"]`);
-      action2.vm.$emit('click');
-
-      expect(wrapper.emitted('select')).toEqual([[TEST_ACTION_2.key]]);
-    });
-
-    it('should not have tooltip value', () => {
-      expect(findTooltip().exists()).toBe(false);
-    });
-  });
-
-  describe('with multiple actions and selectedKey', () => {
-    beforeEach(() => {
-      createComponent({ actions: [TEST_ACTION, TEST_ACTION_2], selectedKey: TEST_ACTION_2.key });
-    });
-
-    it('should show action 2 as selected', () => {
-      expect(parseDropdownItems()).toEqual([
-        expect.objectContaining({
-          type: 'item',
-          isChecked: false,
-        }),
-        { type: 'divider' },
-        expect.objectContaining({
-          type: 'item',
-          isChecked: true,
-        }),
-      ]);
-    });
-
-    it('should have tooltip value', () => {
-      expect(findTooltip().text()).toBe(TEST_ACTION_2.tooltip);
-    });
   });
 });
diff --git a/spec/frontend/vue_shared/components/web_ide_link_spec.js b/spec/frontend/vue_shared/components/web_ide_link_spec.js
index d888abc19efcc1903e1fd7c85da0693606e67005..26557c63a77ecd2b28cd62ac3b408772ef93d478 100644
--- a/spec/frontend/vue_shared/components/web_ide_link_spec.js
+++ b/spec/frontend/vue_shared/components/web_ide_link_spec.js
@@ -1,19 +1,12 @@
-import { GlButton, GlModal } from '@gitlab/ui';
+import { GlModal } from '@gitlab/ui';
 import { nextTick } from 'vue';
 
 import ActionsButton from '~/vue_shared/components/actions_button.vue';
-import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
-import WebIdeLink, {
-  i18n,
-  PREFERRED_EDITOR_RESET_KEY,
-  PREFERRED_EDITOR_KEY,
-} from '~/vue_shared/components/web_ide_link.vue';
+import WebIdeLink, { i18n } from '~/vue_shared/components/web_ide_link.vue';
 import ConfirmForkModal from '~/vue_shared/components/confirm_fork_modal.vue';
-import { KEY_WEB_IDE } from '~/vue_shared/components/constants';
 
 import { stubComponent } from 'helpers/stub_component';
 import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
-import { useLocalStorageSpy } from 'helpers/local_storage_helper';
 
 import { visitUrl } from '~/lib/utils/url_utility';
 
@@ -30,9 +23,8 @@ const forkPath = '/some/fork/path';
 const ACTION_EDIT = {
   href: TEST_EDIT_URL,
   key: 'edit',
-  text: 'Edit',
+  text: 'Edit single file',
   secondaryText: 'Edit this file only.',
-  tooltip: '',
   attrs: {
     'data-qa-selector': 'edit_button',
     'data-track-action': 'click_consolidated_edit',
@@ -45,10 +37,8 @@ const ACTION_EDIT_CONFIRM_FORK = {
   handle: expect.any(Function),
 };
 const ACTION_WEB_IDE = {
-  href: TEST_WEB_IDE_URL,
   key: 'webide',
   secondaryText: i18n.webIdeText,
-  tooltip: i18n.webIdeTooltip,
   text: 'Web IDE',
   attrs: {
     'data-qa-selector': 'web_ide_button',
@@ -59,7 +49,6 @@ const ACTION_WEB_IDE = {
 };
 const ACTION_WEB_IDE_CONFIRM_FORK = {
   ...ACTION_WEB_IDE,
-  href: '#modal-confirm-fork-webide',
   handle: expect.any(Function),
 };
 const ACTION_WEB_IDE_EDIT_FORK = { ...ACTION_WEB_IDE, text: 'Edit fork in Web IDE' };
@@ -67,7 +56,6 @@ const ACTION_GITPOD = {
   href: TEST_GITPOD_URL,
   key: 'gitpod',
   secondaryText: 'Launch a ready-to-code development environment for your project.',
-  tooltip: 'Launch a ready-to-code development environment for your project.',
   text: 'Gitpod',
   attrs: {
     'data-qa-selector': 'gitpod_button',
@@ -82,16 +70,13 @@ const ACTION_PIPELINE_EDITOR = {
   href: TEST_PIPELINE_EDITOR_URL,
   key: 'pipeline_editor',
   secondaryText: 'Edit, lint, and visualize your pipeline.',
-  tooltip: 'Edit, lint, and visualize your pipeline.',
   text: 'Edit in pipeline editor',
   attrs: {
     'data-qa-selector': 'pipeline_editor_button',
   },
 };
 
-describe('Web IDE link component', () => {
-  useLocalStorageSpy();
-
+describe('vue_shared/components/web_ide_link', () => {
   let wrapper;
 
   function createComponent(props, { mountFn = shallowMountExtended, glFeatures = {} } = {}) {
@@ -120,12 +105,7 @@ describe('Web IDE link component', () => {
     });
   }
 
-  beforeEach(() => {
-    localStorage.setItem(PREFERRED_EDITOR_RESET_KEY, 'true');
-  });
-
   const findActionsButton = () => wrapper.findComponent(ActionsButton);
-  const findLocalStorageSync = () => wrapper.findComponent(LocalStorageSync);
   const findModal = () => wrapper.findComponent(GlModal);
   const findForkConfirmModal = () => wrapper.findComponent(ConfirmForkModal);
 
@@ -238,64 +218,16 @@ describe('Web IDE link component', () => {
       });
     });
 
-    it('selected Pipeline Editor by default', () => {
+    it('displays Pipeline Editor as the first action', () => {
       expect(findActionsButton().props()).toMatchObject({
         actions: [ACTION_PIPELINE_EDITOR, ACTION_WEB_IDE, ACTION_GITPOD],
-        selectedKey: ACTION_PIPELINE_EDITOR.key,
       });
     });
 
     it('when web ide button is clicked it opens in a new tab', async () => {
-      findActionsButton().props('actions')[1].handle({
-        preventDefault: jest.fn(),
-      });
-      await nextTick();
-      expect(visitUrl).toHaveBeenCalledWith(ACTION_WEB_IDE.href, true);
-    });
-  });
-
-  describe('with multiple actions', () => {
-    beforeEach(() => {
-      createComponent({
-        showEditButton: false,
-        showWebIdeButton: true,
-        showGitpodButton: true,
-        showPipelineEditorButton: false,
-        userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
-        userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
-        gitpodEnabled: true,
-      });
-    });
-
-    it('selected Web IDE by default', () => {
-      expect(findActionsButton().props()).toMatchObject({
-        actions: [ACTION_WEB_IDE, ACTION_GITPOD],
-        selectedKey: ACTION_WEB_IDE.key,
-      });
-    });
-
-    it('should set selection with local storage value', async () => {
-      expect(findActionsButton().props('selectedKey')).toBe(ACTION_WEB_IDE.key);
-
-      findLocalStorageSync().vm.$emit('input', ACTION_GITPOD.key);
-
+      findActionsButton().props('actions')[1].handle();
       await nextTick();
-
-      expect(findActionsButton().props('selectedKey')).toBe(ACTION_GITPOD.key);
-    });
-
-    it('should update local storage when selection changes', async () => {
-      expect(findLocalStorageSync().props()).toMatchObject({
-        asString: true,
-        value: ACTION_WEB_IDE.key,
-      });
-
-      findActionsButton().vm.$emit('select', ACTION_GITPOD.key);
-
-      await nextTick();
-
-      expect(findActionsButton().props('selectedKey')).toBe(ACTION_GITPOD.key);
-      expect(findLocalStorageSync().props('value')).toBe(ACTION_GITPOD.key);
+      expect(visitUrl).toHaveBeenCalledWith(TEST_WEB_IDE_URL, true);
     });
   });
 
@@ -348,7 +280,10 @@ describe('Web IDE link component', () => {
     it.each(testActions)('opens the modal when the button is clicked', async ({ props }) => {
       createComponent({ ...props, needsToFork: true }, { mountFn: mountExtended });
 
-      await findActionsButton().findComponent(GlButton).trigger('click');
+      wrapper.findComponent(ActionsButton).props().actions[0].handle();
+
+      await nextTick();
+      await wrapper.findByRole('button', { name: /Web IDE|Edit/im }).trigger('click');
 
       expect(findForkConfirmModal().props()).toEqual({
         visible: true,
@@ -404,10 +339,8 @@ describe('Web IDE link component', () => {
         { mountFn: mountExtended },
       );
 
-      findLocalStorageSync().vm.$emit('input', ACTION_GITPOD.key);
-
       await nextTick();
-      await wrapper.findByRole('button', { name: gitpodText }).trigger('click');
+      await wrapper.findByRole('button', { name: new RegExp(gitpodText, 'm') }).trigger('click');
 
       expect(findModal().props('visible')).toBe(true);
     });
@@ -425,58 +358,4 @@ describe('Web IDE link component', () => {
       expect(findModal().exists()).toBe(false);
     });
   });
-
-  describe('when vscode_web_ide feature flag is enabled', () => {
-    describe('when is not showing edit button', () => {
-      describe(`when ${PREFERRED_EDITOR_RESET_KEY} is unset`, () => {
-        beforeEach(() => {
-          localStorage.setItem.mockReset();
-          localStorage.getItem.mockReturnValueOnce(null);
-          createComponent({ showEditButton: false }, { glFeatures: { vscodeWebIde: true } });
-        });
-
-        it(`sets ${PREFERRED_EDITOR_KEY} local storage key to ${KEY_WEB_IDE}`, () => {
-          expect(localStorage.getItem).toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY);
-          expect(localStorage.setItem).toHaveBeenCalledWith(PREFERRED_EDITOR_KEY, KEY_WEB_IDE);
-        });
-
-        it(`sets ${PREFERRED_EDITOR_RESET_KEY} local storage key to true`, () => {
-          expect(localStorage.setItem).toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY, true);
-        });
-
-        it(`selects ${KEY_WEB_IDE} as the preferred editor`, () => {
-          expect(findActionsButton().props().selectedKey).toBe(KEY_WEB_IDE);
-        });
-      });
-
-      describe(`when ${PREFERRED_EDITOR_RESET_KEY} is set to true`, () => {
-        beforeEach(() => {
-          localStorage.setItem.mockReset();
-          localStorage.getItem.mockReturnValueOnce('true');
-          createComponent({ showEditButton: false }, { glFeatures: { vscodeWebIde: true } });
-        });
-
-        it(`does not update the persisted preferred editor`, () => {
-          expect(localStorage.getItem).toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY);
-          expect(localStorage.setItem).not.toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY);
-        });
-      });
-    });
-
-    describe('when is showing the edit button', () => {
-      it(`does not try to reset the ${PREFERRED_EDITOR_KEY}`, () => {
-        createComponent({ showEditButton: true }, { glFeatures: { vscodeWebIde: true } });
-
-        expect(localStorage.getItem).not.toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY);
-      });
-    });
-  });
-
-  describe('when vscode_web_ide feature flag is disabled', () => {
-    it(`does not try to reset the ${PREFERRED_EDITOR_KEY}`, () => {
-      createComponent({}, { glFeatures: { vscodeWebIde: false } });
-
-      expect(localStorage.getItem).not.toHaveBeenCalledWith(PREFERRED_EDITOR_RESET_KEY);
-    });
-  });
 });
diff --git a/spec/support/helpers/features/blob_spec_helpers.rb b/spec/support/helpers/features/blob_spec_helpers.rb
index 8254e1d76bdf2b00b532e485700786d389f74c70..91969107a17e327e42b732b49ab03f2a6e589db6 100644
--- a/spec/support/helpers/features/blob_spec_helpers.rb
+++ b/spec/support/helpers/features/blob_spec_helpers.rb
@@ -5,12 +5,14 @@ module Features
   module BlobSpecHelpers
     include ActionView::Helpers::JavaScriptHelper
 
-    def set_default_button(type)
-      evaluate_script("localStorage.setItem('gl-web-ide-button-selected', '#{type}')")
+    def edit_in_single_file_editor
+      click_button 'Edit'
+      click_link_or_button 'Edit single file'
     end
 
-    def unset_default_button
-      set_default_button('')
+    def edit_in_web_ide
+      click_button 'Edit'
+      click_link_or_button 'Web IDE'
     end
   end
 end
diff --git a/spec/support/helpers/features/web_ide_spec_helpers.rb b/spec/support/helpers/features/web_ide_spec_helpers.rb
index c51116b55b20277384dc08113167c19055d02b05..32b27864e0be97b51f552651b2317d96a755ab93 100644
--- a/spec/support/helpers/features/web_ide_spec_helpers.rb
+++ b/spec/support/helpers/features/web_ide_spec_helpers.rb
@@ -12,6 +12,7 @@
 module Features
   module WebIdeSpecHelpers
     include Features::SourceEditorSpecHelpers
+    include Features::BlobSpecHelpers
 
     # Open the IDE from anywhere by first visiting the given project's page
     def ide_visit(project)
@@ -21,8 +22,10 @@ def ide_visit(project)
     end
 
     # Open the IDE from the current page by clicking the Web IDE link
-    def ide_visit_from_link(link_sel = 'Web IDE')
-      new_tab = window_opened_by { click_link(link_sel) }
+    def ide_visit_from_link
+      new_tab = window_opened_by do
+        edit_in_web_ide
+      end
 
       switch_to_window new_tab
     end