diff --git a/core/modules/tour/config/schema/tour.schema.yml b/core/modules/tour/config/schema/tour.schema.yml
deleted file mode 100644
index 05fcb5b058..0000000000
--- a/core/modules/tour/config/schema/tour.schema.yml
+++ /dev/null
@@ -1,58 +0,0 @@
-# Schema for the configuration files of the Tour module.
-
-tour.tour.*:
-  type: config_entity
-  label: 'Tour settings'
-  mapping:
-    id:
-      type: machine_name
-      label: 'ID'
-    label:
-      type: label
-      label: 'Label'
-    module:
-      type: string
-      label: 'Providing module'
-    routes:
-      type: sequence
-      label: 'Route settings'
-      sequence:
-        type: route
-        label: 'Route'
-    tips:
-      type: sequence
-      label: 'Tips'
-      sequence:
-        type: tour.tip.[plugin]
-        label: 'Tour tip'
-
-tour.tip:
-  type: mapping
-  label: 'Tour tip'
-  mapping:
-    id:
-      type: string
-      label: 'ID'
-    plugin:
-      type: string
-      label: 'Plugin'
-    label:
-      type: label
-      label: 'Label'
-    weight:
-      type: integer
-      label: 'Weight'
-    position:
-      type: string
-      label: 'Position'
-    selector:
-      type: string
-      label: 'Selector'
-
-tour.tip.text:
-  type: tour.tip
-  label: 'Textual tour tip'
-  mapping:
-    body:
-      type: text
-      label: 'Body'
diff --git a/core/modules/tour/css/tour.module.css b/core/modules/tour/css/tour.module.css
deleted file mode 100644
index 50eb62aaba..0000000000
--- a/core/modules/tour/css/tour.module.css
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- * @file
- * Styling for tour module.
- */
-
-/* Tab appearance. */
-.toolbar .toolbar-bar .tour-toolbar-tab.toolbar-tab {
-  float: right; /* LTR */
-}
-[dir="rtl"] .toolbar .toolbar-bar .tour-toolbar-tab.toolbar-tab {
-  float: left;
-}
-
-/* Style the tour progress indicator. */
-.tour-progress {
-  position: absolute;
-  right: 20px; /* LTR */
-  bottom: 20px;
-}
-[dir="rtl"] .tour-progress {
-  right: auto;
-  left: 20px;
-}
-
-/**
- * The following are largely Shepherd's default styles, with a few modifications
- * to facilitate a graceful transition from Joyride, the library used prior to
- * Shepherd.
- */
-.shepherd-footer {
-  display: flex;
-  justify-content: flex-start;
-  padding: 0 20px 20px;
-}
-
-.shepherd-footer .shepherd-button:last-child {
-  margin-right: 0;
-}
-
-.shepherd-cancel-icon {
-  position: absolute;
-  top: 20px;
-  right: 20px;
-  margin: 0;
-  padding: 0;
-  cursor: pointer;
-  border: none;
-  background: transparent;
-  line-height: 1em;
-}
-
-.shepherd-title {
-  margin: 0;
-  padding: 0;
-}
-
-.shepherd-header {
-  position: relative;
-  margin-bottom: 10px;
-  padding: 20px 50px 0 20px;
-}
-
-.shepherd-text {
-  padding: 0 20px;
-}
-
-.shepherd-text p {
-  margin: 0 0 1.4em;
-}
-
-.shepherd-element {
-  z-index: 110;
-  width: 300px;
-  background: #fff;
-}
-
-@media only screen and (max-width: 767px) {
-  .shepherd-element {
-    left: 2.5%;
-    width: 85%;
-  }
-}
-
-.shepherd-enabled.shepherd-element {
-  opacity: 1;
-}
-
-.shepherd-element[data-popper-reference-hidden]:not(.shepherd-centered) {
-  opacity: 0;
-}
-
-.shepherd-element,
-.shepherd-element *,
-.shepherd-element ::after,
-.shepherd-element ::before {
-  box-sizing: border-box;
-}
-
-.shepherd-arrow,
-.shepherd-arrow::before {
-  position: absolute;
-  width: 16px;
-  height: 16px;
-}
-
-.shepherd-arrow::before {
-  content: "";
-  transform: rotate(45deg);
-  background: #fff;
-}
-
-.shepherd-element[data-popper-placement^=top] > .shepherd-arrow {
-  bottom: -8px;
-}
-
-.shepherd-element[data-popper-placement^=bottom] > .shepherd-arrow {
-  top: -8px;
-}
-
-.shepherd-element[data-popper-placement^=left] > .shepherd-arrow {
-  right: -8px;
-}
-
-.shepherd-element[data-popper-placement^=right] > .shepherd-arrow {
-  left: -8px;
-}
-
-.shepherd-target-click-disabled.shepherd-enabled.shepherd-target,
-.shepherd-target-click-disabled.shepherd-enabled.shepherd-target * {
-  pointer-events: none;
-}
-
-.shepherd-modal-overlay-container {
-  position: fixed;
-  z-index: 105;
-  top: 0;
-  left: 0;
-  overflow: hidden;
-  width: 100vw;
-  height: 0;
-  pointer-events: none;
-  opacity: 0;
-  fill-rule: evenodd;
-}
-
-.shepherd-modal-overlay-container.shepherd-modal-is-visible {
-  height: 100vh;
-  opacity: 0.5;
-}
-
-.shepherd-modal-overlay-container.shepherd-modal-is-visible path {
-  pointer-events: all;
-}
diff --git a/core/modules/tour/js/tour.js b/core/modules/tour/js/tour.js
deleted file mode 100644
index 43858e4e2a..0000000000
--- a/core/modules/tour/js/tour.js
+++ /dev/null
@@ -1,414 +0,0 @@
-/**
- * @file
- * Attaches behaviors for the Tour module's toolbar tab.
- */
-
-(($, Backbone, Drupal, settings, document, Shepherd) => {
-  const queryString = decodeURI(window.location.search);
-
-  /**
-   * Attaches the tour's toolbar tab behavior.
-   *
-   * It uses the query string for:
-   * - tour: When ?tour=1 is present, the tour will start automatically after
-   *   the page has loaded.
-   * - tips: Pass ?tips=class in the url to filter the available tips to the
-   *   subset which match the given class.
-   *
-   * @example
-   * http://example.com/foo?tour=1&tips=bar
-   *
-   * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attach tour functionality on `tour` events.
-   */
-  Drupal.behaviors.tour = {
-    attach(context) {
-      once('tour', 'body').forEach(() => {
-        const model = new Drupal.tour.models.StateModel();
-        // eslint-disable-next-line no-new
-        new Drupal.tour.views.ToggleTourView({
-          el: $(context).find('#toolbar-tab-tour'),
-          model,
-        });
-
-        model
-          // Allow other scripts to respond to tour events.
-          .on('change:isActive', (tourModel, isActive) => {
-            $(document).trigger(
-              isActive ? 'drupalTourStarted' : 'drupalTourStopped',
-            );
-          });
-        // Initialization: check whether a tour is available on the current
-        // page.
-        if (settings._tour_internal) {
-          model.set('tour', settings._tour_internal);
-        }
-        // Start the tour immediately if toggled via query string.
-        if (/tour=?/i.test(queryString)) {
-          model.set('isActive', true);
-        }
-      });
-    },
-  };
-
-  /**
-   * @namespace
-   */
-  Drupal.tour = Drupal.tour || {
-    /**
-     * @namespace Drupal.tour.models
-     */
-    models: {},
-
-    /**
-     * @namespace Drupal.tour.views
-     */
-    views: {},
-  };
-
-  /**
-   * Backbone Model for tours.
-   *
-   * @constructor
-   *
-   * @augments Backbone.Model
-   */
-  Drupal.tour.models.StateModel = Backbone.Model.extend(
-    /** @lends Drupal.tour.models.StateModel# */ {
-      /**
-       * @type {object}
-       */
-      defaults: /** @lends Drupal.tour.models.StateModel# */ {
-        /**
-         * Indicates whether the Drupal root window has a tour.
-         *
-         * @type {Array}
-         */
-        tour: [],
-
-        /**
-         * Indicates whether the tour is currently running.
-         *
-         * @type {boolean}
-         */
-        isActive: false,
-
-        /**
-         * Indicates which tour is the active one (necessary to cleanly stop).
-         *
-         * @type {Array}
-         */
-        activeTour: [],
-      },
-    },
-  );
-
-  Drupal.tour.views.ToggleTourView = Backbone.View.extend(
-    /** @lends Drupal.tour.views.ToggleTourView# */ {
-      /**
-       * @type {object}
-       */
-      events: { click: 'onClick' },
-
-      /**
-       * Handles edit mode toggle interactions.
-       *
-       * @constructs
-       *
-       * @augments Backbone.View
-       */
-      initialize() {
-        this.listenTo(this.model, 'change:tour change:isActive', this.render);
-        this.listenTo(this.model, 'change:isActive', this.toggleTour);
-      },
-
-      /**
-       * {@inheritdoc}
-       *
-       * @return {Drupal.tour.views.ToggleTourView}
-       *   The `ToggleTourView` view.
-       */
-      render() {
-        // Render the visibility.
-        this.$el.toggleClass('hidden', this._getTour().length === 0);
-        // Render the state.
-        const isActive = this.model.get('isActive');
-        this.$el
-          .find('button')
-          .toggleClass('is-active', isActive)
-          .attr('aria-pressed', isActive);
-        return this;
-      },
-
-      /**
-       * Model change handler; starts or stops the tour.
-       */
-      toggleTour() {
-        if (this.model.get('isActive')) {
-          this._removeIrrelevantTourItems(this._getTour());
-          const tourItems = this.model.get('tour');
-          const that = this;
-
-          if (tourItems.length) {
-            // If Joyride is positioned relative to the top or bottom of an
-            // element, and its secondary position is right or left, then the
-            // arrow is also positioned right or left. Shepherd defaults to
-            // center positioning the arrow.
-            //
-            // In most cases, this arrow positioning difference has
-            // little impact. However, tours built with Joyride may have tips
-            // using a higher level selector than the element the tip is
-            // expected to point to, and relied on Joyride's arrow positioning
-            // to align the arrow with the expected reference element. Joyride's
-            // arrow positioning behavior is replicated here to prevent those
-            // use cases from causing UI regressions.
-            //
-            // This modifier is provided here instead of TourViewBuilder (where
-            // most position modifications are) because it includes adding a
-            // JavaScript callback function.
-            settings.tourShepherdConfig.defaultStepOptions.popperOptions.modifiers.push(
-              {
-                name: 'moveArrowJoyridePosition',
-                enabled: true,
-                phase: 'write',
-                fn({ state }) {
-                  const { arrow } = state.elements;
-                  const { placement } = state;
-                  if (
-                    arrow &&
-                    /^top|bottom/.test(placement) &&
-                    /-start|-end$/.test(placement)
-                  ) {
-                    const horizontalPosition = placement.split('-')[1];
-                    const offset =
-                      horizontalPosition === 'start'
-                        ? 28
-                        : state.elements.popper.clientWidth - 56;
-                    arrow.style.transform = `translate3d(${offset}px, 0px, 0px)`;
-                  }
-                },
-              },
-            );
-            const shepherdTour = new Shepherd.Tour(settings.tourShepherdConfig);
-            shepherdTour.on('cancel', () => {
-              that.model.set('isActive', false);
-            });
-            shepherdTour.on('complete', () => {
-              that.model.set('isActive', false);
-            });
-
-            tourItems.forEach((tourStepConfig, index) => {
-              // Create the configuration for a given tour step by using values
-              // defined in TourViewBuilder.
-              // @see \Drupal\tour\TourViewBuilder::viewMultiple()
-              const tourItemOptions = {
-                title: tourStepConfig.title
-                  ? Drupal.checkPlain(tourStepConfig.title)
-                  : null,
-                text: () => Drupal.theme('tourItemContent', tourStepConfig),
-                attachTo: tourStepConfig.attachTo,
-                buttons: [Drupal.tour.nextButton(shepherdTour, tourStepConfig)],
-                classes: tourStepConfig.classes,
-                index,
-              };
-
-              tourItemOptions.when = {
-                show() {
-                  const nextButton =
-                    shepherdTour.currentStep.el.querySelector('footer button');
-
-                  // Drupal disables Shepherd's built in focus after item
-                  // creation functionality due to focus being set on the tour
-                  // item container after every scroll and resize event. In its
-                  // place, the 'next' button is focused here.
-                  nextButton.focus();
-
-                  // When Stable 9 is part of the active theme, the
-                  // Drupal.tour.convertToJoyrideMarkup() function is available.
-                  // This function converts Shepherd markup to Joyride markup,
-                  // facilitating the use of the Shepherd library that is
-                  // backwards compatible with customizations intended for
-                  // Joyride.
-                  // The Drupal.tour.convertToJoyrideMarkup() function is
-                  // internal, and will eventually be removed from Drupal core.
-                  if (Drupal.tour.hasOwnProperty('convertToJoyrideMarkup')) {
-                    Drupal.tour.convertToJoyrideMarkup(shepherdTour);
-                  }
-                },
-              };
-
-              shepherdTour.addStep(tourItemOptions);
-            });
-            shepherdTour.start();
-            this.model.set({ isActive: true, activeTour: shepherdTour });
-          }
-        } else {
-          this.model.get('activeTour').cancel();
-          this.model.set({ isActive: false, activeTour: [] });
-        }
-      },
-
-      /**
-       * Toolbar tab click event handler; toggles isActive.
-       *
-       * @param {jQuery.Event} event
-       *   The click event.
-       */
-      onClick(event) {
-        this.model.set('isActive', !this.model.get('isActive'));
-        event.preventDefault();
-        event.stopPropagation();
-      },
-
-      /**
-       * Gets the tour.
-       *
-       * @return {array}
-       *   An array of Shepherd tour item objects.
-       */
-      _getTour() {
-        return this.model.get('tour');
-      },
-
-      /**
-       * Removes tour items for elements that don't have matching page elements.
-       *
-       * Or that are explicitly filtered out via the 'tips' query string.
-       *
-       * @example
-       * <caption>This will filter out tips that do not have a matching
-       * page element or don't have the "bar" class.</caption>
-       * http://example.com/foo?tips=bar
-       *
-       * @param {Object[]} tourItems
-       *   An array containing tour Step config objects.
-       *   The object properties relevant to this function:
-       *   - classes {string}: A string of classes to be added to the tour step
-       *     when rendered.
-       *   - selector {string}: The selector a tour step is associated with.
-       */
-      _removeIrrelevantTourItems(tourItems) {
-        const tips = /tips=([^&]+)/.exec(queryString);
-        const filteredTour = tourItems.filter((tourItem) => {
-          // If the query parameter 'tips' is set, remove all tips that don't
-          // have the matching class. The `tourItem` variable is a step config
-          // object, and the 'classes' property is a ShepherdJS Step() config
-          // option that provides a string.
-          if (
-            tips &&
-            tourItem.hasOwnProperty('classes') &&
-            tourItem.classes.indexOf(tips[1]) === -1
-          ) {
-            return false;
-          }
-
-          // If a selector is configured but there isn't a matching element,
-          // return false.
-          return !(
-            tourItem.selector && !document.querySelector(tourItem.selector)
-          );
-        });
-
-        // If there are tours filtered, we'll have to update model.
-        if (tourItems.length !== filteredTour.length) {
-          filteredTour.forEach((filteredTourItem, filteredTourItemId) => {
-            filteredTour[filteredTourItemId].counter = Drupal.t(
-              '!tour_item of !total',
-              {
-                '!tour_item': filteredTourItemId + 1,
-                '!total': filteredTour.length,
-              },
-            );
-
-            if (filteredTourItemId === filteredTour.length - 1) {
-              filteredTour[filteredTourItemId].cancelText =
-                Drupal.t('End tour');
-            }
-          });
-          this.model.set('tour', filteredTour);
-        }
-      },
-    },
-  );
-
-  /**
-   * Provides an object that will become the tour item's 'next' button.
-   *
-   * Similar to a theme function, themes can override this function to customize
-   * the resulting button. Unlike a theme function, it returns an object instead
-   * of a string, which is why it is not part of Drupal.theme.
-   *
-   * @param {Tour} shepherdTour
-   *  A class representing a Shepherd site tour.
-   * @param {Object} tourStepConfig
-   *   An object generated in TourViewBuilder used for creating the options
-   *   passed to `Tour.addStep(options)`.
-   *   Contains the following properties:
-   *   - id {string}: The tour.tip ID specified by its config
-   *   - selector {string|null}: The selector of the element the tour step is
-   *     attaching to.
-   *   - module {string}: The module providing the tip plugin used by this step.
-   *   - counter {string}: A string indicating which tour step this is out of
-   *     how many total steps.
-   *   - attachTo {Object} This is directly mapped to the `attachTo` Step()
-   *     option. It has two properties:
-   *     - element {string}: The selector of the element the step attaches to.
-   *     - on {string}: a PopperJS compatible string to specify step position.
-   *   - classes {string}: Will be added to the class attribute of the step.
-   *   - body {string}: Markup that is mapped to the `text` Step() option. Will
-   *     become the step content.
-   *   - title {string}: is mapped to the `title` Step() option.
-   *
-   * @return {{classes: string, action: string, text: string}}
-   *    An object structured in the manner Shepherd requires to create the
-   *    'next' button.
-   *
-   * @see https://shepherdjs.dev/docs/Tour.html
-   * @see \Drupal\tour\TourViewBuilder::viewMultiple()
-   * @see https://shepherdjs.dev/docs/Step.html
-   */
-  Drupal.tour.nextButton = (shepherdTour, tourStepConfig) => {
-    return {
-      classes: 'button button--primary',
-      text: tourStepConfig.cancelText
-        ? tourStepConfig.cancelText
-        : Drupal.t('Next'),
-      action: tourStepConfig.cancelText
-        ? shepherdTour.cancel
-        : shepherdTour.next,
-    };
-  };
-
-  /**
-   * Theme function for tour item content.
-   *
-   * @param {Object} tourStepConfig
-   *   An object generated in TourViewBuilder used for creating the options
-   *   passed to `Tour.addStep(options)`.
-   *   Contains the following properties:
-   *   - id {string}: The tour.tip ID specified by its config
-   *   - selector {string|null}: The selector of the element the tour step is
-   *     attaching to.
-   *   - module {string}: The module providing the tip plugin used by this step.
-   *   - counter {string}: A string indicating which tour step this is out of
-   *     how many total steps.
-   *   - attachTo {Object} This is directly mapped to the `attachTo` Step()
-   *     option. It has two properties:
-   *     - element {string}: The selector of the element the step attaches to.
-   *     - on {string}: a PopperJS compatible string to specify step position.
-   *   - classes {string}: Will be added to the class attribute of the step.
-   *   - body {string}: Markup that is mapped to the `text` Step() option. Will
-   *     become the step content.
-   *   - title {string}: is mapped to the `title` Step() option.
-   *
-   * @return {string}
-   *   The tour item content markup.
-   *
-   * @see \Drupal\tour\TourViewBuilder::viewMultiple()
-   * @see https://shepherdjs.dev/docs/Step.html
-   */
-  Drupal.theme.tourItemContent = (tourStepConfig) =>
-    `${tourStepConfig.body}<div class="tour-progress">${tourStepConfig.counter}</div>`;
-})(jQuery, Backbone, Drupal, drupalSettings, document, window.Shepherd);
diff --git a/core/modules/tour/src/Annotation/Tip.php b/core/modules/tour/src/Annotation/Tip.php
deleted file mode 100644
index d1daeb75ee..0000000000
--- a/core/modules/tour/src/Annotation/Tip.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-namespace Drupal\tour\Annotation;
-
-use Drupal\Component\Annotation\Plugin;
-
-/**
- * Defines a tour item annotation object.
- *
- * Plugin Namespace: Plugin\tour\tip
- *
- * For a working example, see \Drupal\tour\Plugin\tour\tip\TipPluginText
- *
- * @see \Drupal\tour\TipPluginBase
- * @see \Drupal\tour\TipPluginInterface
- * @see \Drupal\tour\TipPluginManager
- * @see plugin_api
- *
- * @Annotation
- */
-class Tip extends Plugin {
-
-  /**
-   * The plugin ID.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * The title of the plugin.
-   *
-   * @var \Drupal\Core\Annotation\Translation
-   *
-   * @ingroup plugin_translatable
-   */
-  public $title;
-
-}
diff --git a/core/modules/tour/src/Entity/Tour.php b/core/modules/tour/src/Entity/Tour.php
deleted file mode 100644
index 8e168fe0a8..0000000000
--- a/core/modules/tour/src/Entity/Tour.php
+++ /dev/null
@@ -1,189 +0,0 @@
-<?php
-
-namespace Drupal\tour\Entity;
-
-use Drupal\Core\Config\Entity\ConfigEntityBase;
-use Drupal\tour\TipsPluginCollection;
-use Drupal\tour\TourInterface;
-
-/**
- * Defines the configured tour entity.
- *
- * @ConfigEntityType(
- *   id = "tour",
- *   label = @Translation("Tour"),
- *   label_collection = @Translation("Tours"),
- *   label_singular = @Translation("tour"),
- *   label_plural = @Translation("tours"),
- *   label_count = @PluralTranslation(
- *     singular = "@count tour",
- *     plural = "@count tours",
- *   ),
- *   handlers = {
- *     "view_builder" = "Drupal\tour\TourViewBuilder",
- *     "access" = "Drupal\tour\TourAccessControlHandler",
- *   },
- *   admin_permission = "administer site configuration",
- *   entity_keys = {
- *     "id" = "id",
- *     "label" = "label"
- *   },
- *   config_export = {
- *     "id",
- *     "label",
- *     "module",
- *     "routes",
- *     "tips",
- *   },
- *   lookup_keys = {
- *     "routes.*.route_name"
- *   }
- * )
- */
-class Tour extends ConfigEntityBase implements TourInterface {
-
-  /**
-   * The name (plugin ID) of the tour.
-   *
-   * @var string
-   */
-  protected $id;
-
-  /**
-   * The module which this tour is assigned to.
-   *
-   * @var string
-   */
-  protected $module;
-
-  /**
-   * The label of the tour.
-   *
-   * @var string
-   */
-  protected $label;
-
-  /**
-   * The routes on which this tour should be displayed.
-   *
-   * @var array
-   */
-  protected $routes = [];
-
-  /**
-   * The routes on which this tour should be displayed, keyed by route id.
-   *
-   * @var array
-   */
-  protected $keyedRoutes;
-
-  /**
-   * Holds the collection of tips that are attached to this tour.
-   *
-   * @var \Drupal\tour\TipsPluginCollection
-   */
-  protected $tipsCollection;
-
-  /**
-   * The array of plugin config, only used for export and to populate the $tipsCollection.
-   *
-   * @var array
-   */
-  protected $tips = [];
-
-  /**
-   * {@inheritdoc}
-   */
-  public function __construct(array $values, $entity_type) {
-    parent::__construct($values, $entity_type);
-
-    $this->tipsCollection = new TipsPluginCollection(\Drupal::service('plugin.manager.tour.tip'), $this->tips);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRoutes() {
-    return $this->routes;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTip($id) {
-    return $this->tipsCollection->get($id);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTips() {
-    $tips = [];
-    foreach ($this->tips as $id => $tip) {
-      $tips[] = $this->getTip($id);
-    }
-    uasort($tips, function ($a, $b) {
-      return $a->getWeight() <=> $b->getWeight();
-    });
-
-    \Drupal::moduleHandler()->alter('tour_tips', $tips, $this);
-    return array_values($tips);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getModule() {
-    return $this->module;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasMatchingRoute($route_name, $route_params) {
-    if (!isset($this->keyedRoutes)) {
-      $this->keyedRoutes = [];
-      foreach ($this->getRoutes() as $route) {
-        $this->keyedRoutes[$route['route_name']] = $route['route_params'] ?? [];
-      }
-    }
-    if (!isset($this->keyedRoutes[$route_name])) {
-      // We don't know about this route.
-      return FALSE;
-    }
-    if (empty($this->keyedRoutes[$route_name])) {
-      // We don't need to worry about route params, the route name is enough.
-      return TRUE;
-    }
-    foreach ($this->keyedRoutes[$route_name] as $key => $value) {
-      // If a required param is missing or doesn't match, return FALSE.
-      if (empty($route_params[$key]) || $route_params[$key] !== $value) {
-        return FALSE;
-      }
-    }
-    return TRUE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function resetKeyedRoutes() {
-    unset($this->keyedRoutes);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function calculateDependencies() {
-    parent::calculateDependencies();
-
-    foreach ($this->tipsCollection as $instance) {
-      $definition = $instance->getPluginDefinition();
-      $this->addDependency('module', $definition['provider']);
-    }
-
-    $this->addDependency('module', $this->module);
-    return $this;
-  }
-
-}
diff --git a/core/modules/tour/src/Plugin/HelpSection/TourHelpSection.php b/core/modules/tour/src/Plugin/HelpSection/TourHelpSection.php
deleted file mode 100644
index 4716af4271..0000000000
--- a/core/modules/tour/src/Plugin/HelpSection/TourHelpSection.php
+++ /dev/null
@@ -1,133 +0,0 @@
-<?php
-
-namespace Drupal\tour\Plugin\HelpSection;
-
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Link;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Url;
-use Drupal\help\Plugin\HelpSection\HelpSectionPluginBase;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Provides the tours list section for the help page.
- *
- * @HelpSection(
- *   id = "tour",
- *   title = @Translation("Tours"),
- *   weight = 10,
- *   description = @Translation("Tours guide you through workflows or explain concepts on various user interface pages. The tours with links in this list are on user interface landing pages; the tours without links will show on individual pages (such as when editing a View using the Views UI module). Available tours:"),
- *   permission = "access tour"
- * )
- */
-class TourHelpSection extends HelpSectionPluginBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The entity type manager.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
-   */
-  protected $entityTypeManager;
-
-  /**
-   * Constructs a TourHelpSection object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
-   *   The entity type manager service.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->entityTypeManager = $entity_type_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('entity_type.manager')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCacheMaxAge() {
-    // The calculation of which URL (if any) gets put on which tour depends
-    // on a route access check. This can have a lot of inputs, including user
-    // permissions and other factors. Rather than doing a complicated
-    // accounting of the cache metadata for all of these possible factors, set
-    // the max age of the cache to zero to prevent using incorrect cached
-    // information.
-    return 0;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function listTopics() {
-    /** @var \Drupal\tour\TourInterface[] $tours */
-    $tours = $this->entityTypeManager->getStorage('tour')->loadMultiple();
-    // Sort in the manner defined by Tour.
-    uasort($tours, ['Drupal\tour\Entity\Tour', 'sort']);
-
-    // Make a link to each tour, using the first of its routes that can
-    // be linked to by this user, if any.
-    $topics = [];
-    foreach ($tours as $tour) {
-      $title = $tour->label();
-      $id = $tour->id();
-      $routes = $tour->getRoutes();
-      $made_link = FALSE;
-      foreach ($routes as $route) {
-        // Some tours are for routes with parameters. For instance, there is
-        // currently a tour in the Language module for the language edit page,
-        // which appears on all pages with URLs like:
-        // /admin/config/regional/language/edit/LANGCODE.
-        // There is no way to make a link to the page that displays the tour,
-        // because it is a set of pages. The easiest way to detect this is to
-        // use a try/catch exception -- try to make a link, and it will error
-        // out with a missing parameter exception if the route leads to a set
-        // of pages instead of a single page.
-        try {
-          $params = $route['route_params'] ?? [];
-          $url = Url::fromRoute($route['route_name'], $params);
-          // Skip this route if the current user cannot access it.
-          if (!$url->access()) {
-            continue;
-          }
-
-          // Generate the link HTML directly, using toString(), to catch
-          // missing parameter exceptions now instead of at render time.
-          $topics[$id] = Link::fromTextAndUrl($title, $url)->toString();
-          // If the line above didn't generate an exception, we have a good
-          // link that the user can access.
-          $made_link = TRUE;
-          break;
-        }
-        catch (\Exception $e) {
-          // Exceptions are normally due to routes that need parameters. If
-          // there is an exception, just try the next route and see if we can
-          // find one that will work for us.
-        }
-      }
-      if (!$made_link) {
-        // None of the routes worked to make a link, so at least display the
-        // tour title.
-        $topics[$id] = $title;
-      }
-    }
-
-    return $topics;
-  }
-
-}
diff --git a/core/modules/tour/src/Plugin/tour/tip/TipPluginText.php b/core/modules/tour/src/Plugin/tour/tip/TipPluginText.php
deleted file mode 100644
index 93963bfb55..0000000000
--- a/core/modules/tour/src/Plugin/tour/tip/TipPluginText.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-
-namespace Drupal\tour\Plugin\tour\tip;
-
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Utility\Token;
-use Drupal\tour\TipPluginBase;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Displays some text as a tip.
- *
- * @Tip(
- *   id = "text",
- *   title = @Translation("Text")
- * )
- */
-class TipPluginText extends TipPluginBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The body text which is used for render of this Text Tip.
-   *
-   * @var string
-   */
-  protected $body;
-
-  /**
-   * Token service.
-   *
-   * @var \Drupal\Core\Utility\Token
-   */
-  protected $token;
-
-  /**
-   * Constructs a \Drupal\tour\Plugin\tour\tip\TipPluginText object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Utility\Token $token
-   *   The token service.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, Token $token) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->token = $token;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('token'));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getBody(): array {
-    return [
-      '#type' => 'html_tag',
-      '#tag' => 'p',
-      '#value' => $this->token->replace($this->get('body')),
-      '#attributes' => [
-        'class' => ['tour-tip-body'],
-      ],
-    ];
-  }
-
-}
diff --git a/core/modules/tour/src/TipPluginBase.php b/core/modules/tour/src/TipPluginBase.php
deleted file mode 100644
index bb24470c87..0000000000
--- a/core/modules/tour/src/TipPluginBase.php
+++ /dev/null
@@ -1,112 +0,0 @@
-<?php
-
-namespace Drupal\tour;
-
-use Drupal\Core\Plugin\PluginBase;
-
-/**
- * Defines a base tour item implementation.
- *
- * @see \Drupal\tour\Annotation\Tip
- * @see \Drupal\tour\TipPluginInterface
- * @see \Drupal\tour\TipPluginManager
- * @see plugin_api
- */
-abstract class TipPluginBase extends PluginBase implements TipPluginInterface {
-
-  /**
-   * The label which is used for render of this tip.
-   *
-   * @var string
-   */
-  protected $label;
-
-  /**
-   * Allows tips to take more priority that others.
-   *
-   * @var string
-   */
-  protected $weight;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function id() {
-    return $this->get('id');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getLabel() {
-    return $this->get('label');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getWeight() {
-    return $this->get('weight');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function get($key) {
-    if (!empty($this->configuration[$key])) {
-      return $this->configuration[$key];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function set($key, $value) {
-    $this->configuration[$key] = $value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getLocation(): ?string {
-    $location = $this->get('position');
-
-    // The location values accepted by PopperJS, the library used for
-    // positioning the tip.
-    assert(in_array(trim($location ?? ''), [
-      'auto',
-      'auto-start',
-      'auto-end',
-      'top',
-      'top-start',
-      'top-end',
-      'bottom',
-      'bottom-start',
-      'bottom-end',
-      'right',
-      'right-start',
-      'right-end',
-      'left',
-      'left-start',
-      'left-end',
-      '',
-    ], TRUE), "$location is not a valid Tour Tip position value");
-
-    return $location;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getSelector(): ?string {
-    return $this->get('selector');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getBody(): array {
-    return [];
-  }
-
-}
diff --git a/core/modules/tour/src/TipPluginInterface.php b/core/modules/tour/src/TipPluginInterface.php
deleted file mode 100644
index 6fd4b59e2e..0000000000
--- a/core/modules/tour/src/TipPluginInterface.php
+++ /dev/null
@@ -1,101 +0,0 @@
-<?php
-
-namespace Drupal\tour;
-
-/**
- * Defines an interface for tour items.
- *
- * @see \Drupal\tour\Annotation\Tip
- * @see \Drupal\tour\TipPluginBase
- * @see \Drupal\tour\TipPluginManager
- * @see plugin_api
- */
-interface TipPluginInterface {
-
-  /**
-   * Returns id of the tip.
-   *
-   * @return string
-   *   The id of the tip.
-   */
-  public function id();
-
-  /**
-   * Returns label of the tip.
-   *
-   * @return string
-   *   The label of the tip.
-   */
-  public function getLabel();
-
-  /**
-   * Returns weight of the tip.
-   *
-   * @return string
-   *   The weight of the tip.
-   */
-  public function getWeight();
-
-  /**
-   * Used for returning values by key.
-   *
-   * @var string
-   *   Key of the value.
-   *
-   * @return string
-   *   Value of the key.
-   */
-  public function get($key);
-
-  /**
-   * Returns the selector the tour tip will attach to.
-   *
-   * This typically maps to the Shepherd Step options `attachTo.element`
-   * property.
-   *
-   * @return null|string
-   *   A selector string, or null for an unattached tip.
-   *
-   * @see https://shepherdjs.dev/docs/Step.html
-   */
-  public function getSelector(): ?string;
-
-  /**
-   * Returns the body content of the tooltip.
-   *
-   * This typically maps to the Shepherd Step options `text` property.
-   *
-   * @return array
-   *   A render array.
-   *
-   * @see https://shepherdjs.dev/docs/Step.html
-   */
-  public function getBody(): array;
-
-  /**
-   * Returns the configured placement of the tip relative to the element.
-   *
-   * If null, the tip will automatically determine the best position based on
-   * the element's position in the viewport.
-   *
-   * This typically maps to the Shepherd Step options `attachTo.on` property.
-   *
-   * @return string|null
-   *   The tip placement relative to the element.
-   *
-   * @see https://shepherdjs.dev/docs/Step.html
-   */
-  public function getLocation(): ?string;
-
-  /**
-   * Used for returning values by key.
-   *
-   * @var string
-   *   Key of the value.
-   *
-   * @var string
-   *   Value of the key.
-   */
-  public function set($key, $value);
-
-}
diff --git a/core/modules/tour/src/TipPluginManager.php b/core/modules/tour/src/TipPluginManager.php
deleted file mode 100644
index 4675fd803b..0000000000
--- a/core/modules/tour/src/TipPluginManager.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-namespace Drupal\tour;
-
-use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Plugin\DefaultPluginManager;
-
-/**
- * Provides a plugin manager for tour items.
- *
- * @see \Drupal\tour\Annotation\Tip
- * @see \Drupal\tour\TipPluginBase
- * @see \Drupal\tour\TipPluginInterface
- * @see plugin_api
- */
-class TipPluginManager extends DefaultPluginManager {
-
-  /**
-   * Constructs a new TipPluginManager.
-   *
-   * @param \Traversable $namespaces
-   *   An object that implements \Traversable which contains the root paths
-   *   keyed by the corresponding namespace to look for plugin implementations,
-   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
-   *   Cache backend instance to use.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler to invoke the alter hook with.
-   */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
-    parent::__construct('Plugin/tour/tip', $namespaces, $module_handler, 'Drupal\tour\TipPluginInterface', 'Drupal\tour\Annotation\Tip');
-
-    $this->alterInfo('tour_tips_info');
-    $this->setCacheBackend($cache_backend, 'tour_plugins');
-  }
-
-}
diff --git a/core/modules/tour/src/TipsPluginCollection.php b/core/modules/tour/src/TipsPluginCollection.php
deleted file mode 100644
index 5480f10dcd..0000000000
--- a/core/modules/tour/src/TipsPluginCollection.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-
-namespace Drupal\tour;
-
-use Drupal\Core\Plugin\DefaultLazyPluginCollection;
-
-/**
- * A collection of tips.
- */
-class TipsPluginCollection extends DefaultLazyPluginCollection {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $pluginKey = 'plugin';
-
-  /**
-   * {@inheritdoc}
-   *
-   * @return \Drupal\tour\TipPluginInterface
-   */
-  public function &get($instance_id) {
-    return parent::get($instance_id);
-  }
-
-}
diff --git a/core/modules/tour/src/TourAccessControlHandler.php b/core/modules/tour/src/TourAccessControlHandler.php
deleted file mode 100644
index a0d427a0b1..0000000000
--- a/core/modules/tour/src/TourAccessControlHandler.php
+++ /dev/null
@@ -1,28 +0,0 @@
-<?php
-
-namespace Drupal\tour;
-
-use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Entity\EntityAccessControlHandler;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Session\AccountInterface;
-
-/**
- * Defines the access control handler for the tour entity type.
- *
- * @see \Drupal\tour\Entity\Tour
- */
-class TourAccessControlHandler extends EntityAccessControlHandler {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
-    if ($operation === 'view') {
-      return AccessResult::allowedIfHasPermissions($account, ['access tour', 'administer site configuration'], 'OR');
-    }
-
-    return parent::checkAccess($entity, $operation, $account);
-  }
-
-}
diff --git a/core/modules/tour/src/TourInterface.php b/core/modules/tour/src/TourInterface.php
deleted file mode 100644
index 31590713fe..0000000000
--- a/core/modules/tour/src/TourInterface.php
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-
-namespace Drupal\tour;
-
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
-
-/**
- * Provides an interface defining a tour entity.
- */
-interface TourInterface extends ConfigEntityInterface {
-
-  /**
-   * The routes that this tour will appear on.
-   *
-   * @return array
-   *   Returns array of routes for the tour.
-   */
-  public function getRoutes();
-
-  /**
-   * Whether the tour matches a given set of route parameters.
-   *
-   * @param string $route_name
-   *   The route name the parameters are for.
-   * @param array $route_params
-   *   Associative array of raw route params.
-   *
-   * @return bool
-   *   TRUE if the tour matches the route parameters.
-   */
-  public function hasMatchingRoute($route_name, $route_params);
-
-  /**
-   * Returns tip plugin.
-   *
-   * @param string $id
-   *   The identifier of the tip.
-   *
-   * @return \Drupal\tour\TipPluginInterface
-   *   The tip plugin.
-   */
-  public function getTip($id);
-
-  /**
-   * Returns the tips for this tour.
-   *
-   * @return array
-   *   An array of tip plugins.
-   */
-  public function getTips();
-
-  /**
-   * Gets the module this tour belongs to.
-   *
-   * @return string
-   *   The module this tour belongs to.
-   */
-  public function getModule();
-
-  /**
-   * Resets the statically cached keyed routes.
-   */
-  public function resetKeyedRoutes();
-
-}
diff --git a/core/modules/tour/src/TourTipPluginInterface.php b/core/modules/tour/src/TourTipPluginInterface.php
deleted file mode 100644
index 27f5ac2d99..0000000000
--- a/core/modules/tour/src/TourTipPluginInterface.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-
-namespace Drupal\tour;
-
-@trigger_error('The ' . __NAMESPACE__ . '\TourTipPluginInterface is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Implement ' . __NAMESPACE__ . '\TipPluginInterface instead. See https://www.drupal.org/node/3340701.', E_USER_DEPRECATED);
-
-/**
- * Defines an interface for tour items.
- *
- * @see \Drupal\tour\Annotation\Tip
- * @see \Drupal\tour\TipPluginBase
- * @see \Drupal\tour\TipPluginManager
- * @see plugin_api
- *
- * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Implements
- *   TipPluginInterface instead.
- *
- * @see https://www.drupal.org/node/3340701
- */
-interface TourTipPluginInterface extends TipPluginInterface {}
diff --git a/core/modules/tour/src/TourViewBuilder.php b/core/modules/tour/src/TourViewBuilder.php
deleted file mode 100644
index f7226109ad..0000000000
--- a/core/modules/tour/src/TourViewBuilder.php
+++ /dev/null
@@ -1,137 +0,0 @@
-<?php
-
-namespace Drupal\tour;
-
-use Drupal\Core\Cache\Cache;
-use Drupal\Core\Entity\EntityViewBuilder;
-use Drupal\Component\Utility\Html;
-
-/**
- * Provides a Tour view builder.
- */
-class TourViewBuilder extends EntityViewBuilder {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewMultiple(array $entities = [], $view_mode = 'full', $langcode = NULL) {
-    /** @var \Drupal\tour\TourInterface[] $entities */
-    $tour = [];
-    $cache_tags = [];
-    $total_tips = 0;
-    foreach ($entities as $entity_id => $entity) {
-      $tour[$entity_id] = $entity->getTips();
-      $total_tips += count($tour[$entity_id]);
-      $cache_tags = Cache::mergeTags($cache_tags, $entity->getCacheTags());
-    }
-
-    $items = [];
-    foreach ($tour as $tour_id => $tips) {
-      $tourEntity = $entities[$tour_id];
-
-      foreach ($tips as $index => $tip) {
-        $classes = [
-          'tip-module-' . Html::getClass($tourEntity->getModule()),
-          'tip-type-' . Html::getClass($tip->getPluginId()),
-          'tip-' . Html::getClass($tip->id()),
-        ];
-
-        $selector = $tip->getSelector();
-        $location = $tip->getLocation();
-
-        $body_render_array = $tip->getBody();
-        $body = (string) \Drupal::service('renderer')->renderPlain($body_render_array);
-        $output = [
-          'body' => $body,
-          'title' => $tip->getLabel(),
-        ];
-
-        $selector = $tip->getSelector();
-
-        if ($output) {
-          $items[] = [
-            'id' => $tip->id(),
-            'selector' => $selector,
-            'module' => $tourEntity->getModule(),
-            'type' => $tip->getPluginId(),
-            'counter' => $this->t('@tour_item of @total', [
-              '@tour_item' => $index + 1,
-              '@total' => $total_tips,
-            ]),
-            'attachTo' => [
-              'element' => $selector,
-              'on' => $location ?? 'bottom-start',
-            ],
-            // Shepherd expects classes to be provided as a string.
-            'classes' => implode(' ', $classes),
-          ] + $output;
-        }
-      }
-    }
-
-    // If there is at least one tour item, build the tour.
-    if ($items) {
-      end($items);
-      $key = key($items);
-      $items[$key]['cancelText'] = t('End tour');
-    }
-
-    $build = [
-      '#cache' => [
-        'tags' => $cache_tags,
-      ],
-    ];
-
-    // If at least one tour was built, attach tips and the tour library.
-    if ($items) {
-      $build['#attached']['drupalSettings']['tourShepherdConfig'] = [
-        'defaultStepOptions' => [
-          'classes' => 'drupal-tour',
-          'cancelIcon' => [
-            'enabled' => TRUE,
-            'label' => $this->t('Close'),
-          ],
-          'modalOverlayOpeningPadding' => 3,
-          'scrollTo' => [
-            'behavior' => 'smooth',
-            'block' => 'center',
-          ],
-          'popperOptions' => [
-            'modifiers' => [
-              // Prevent overlap with the element being highlighted.
-              [
-                'name' => 'offset',
-                'options' => [
-                  'offset' => [-10, 20],
-                ],
-              ],
-              // Pad the arrows so they don't hit the edge of rounded corners.
-              [
-                'name' => 'arrow',
-                'options' => [
-                  'padding' => 12,
-                ],
-              ],
-              // Disable Shepherd's focusAfterRender modifier, which results in
-              // the tour item container being focused on any scroll or resize
-              // event.
-              [
-                'name' => 'focusAfterRender',
-                'enabled' => FALSE,
-              ],
-
-            ],
-          ],
-        ],
-        'useModalOverlay' => TRUE,
-      ];
-      // This property is used for storing the tour items. It may change without
-      // notice and should not be extended or modified in contrib.
-      // see: https://www.drupal.org/project/drupal/issues/3214593
-      $build['#attached']['drupalSettings']['_tour_internal'] = $items;
-      $build['#attached']['library'][] = 'tour/tour';
-    }
-    return $build;
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Functional/Rest/TourJsonAnonTest.php b/core/modules/tour/tests/src/Functional/Rest/TourJsonAnonTest.php
deleted file mode 100644
index 0a171f2485..0000000000
--- a/core/modules/tour/tests/src/Functional/Rest/TourJsonAnonTest.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional\Rest;
-
-use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
-
-/**
- * @group rest
- */
-class TourJsonAnonTest extends TourResourceTestBase {
-
-  use AnonResourceTestTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $format = 'json';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $mimeType = 'application/json';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-}
diff --git a/core/modules/tour/tests/src/Functional/Rest/TourJsonBasicAuthTest.php b/core/modules/tour/tests/src/Functional/Rest/TourJsonBasicAuthTest.php
deleted file mode 100644
index 89aeb274e9..0000000000
--- a/core/modules/tour/tests/src/Functional/Rest/TourJsonBasicAuthTest.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional\Rest;
-
-use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
-
-/**
- * @group rest
- */
-class TourJsonBasicAuthTest extends TourResourceTestBase {
-
-  use BasicAuthResourceTestTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = ['basic_auth'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $format = 'json';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $mimeType = 'application/json';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $auth = 'basic_auth';
-
-}
diff --git a/core/modules/tour/tests/src/Functional/Rest/TourJsonCookieTest.php b/core/modules/tour/tests/src/Functional/Rest/TourJsonCookieTest.php
deleted file mode 100644
index f124c5ce33..0000000000
--- a/core/modules/tour/tests/src/Functional/Rest/TourJsonCookieTest.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional\Rest;
-
-use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
-
-/**
- * @group rest
- */
-class TourJsonCookieTest extends TourResourceTestBase {
-
-  use CookieResourceTestTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $format = 'json';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $mimeType = 'application/json';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $auth = 'cookie';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-}
diff --git a/core/modules/tour/tests/src/Functional/Rest/TourResourceTestBase.php b/core/modules/tour/tests/src/Functional/Rest/TourResourceTestBase.php
deleted file mode 100644
index 813505a304..0000000000
--- a/core/modules/tour/tests/src/Functional/Rest/TourResourceTestBase.php
+++ /dev/null
@@ -1,116 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional\Rest;
-
-use Drupal\Tests\rest\Functional\EntityResource\ConfigEntityResourceTestBase;
-use Drupal\tour\Entity\Tour;
-
-abstract class TourResourceTestBase extends ConfigEntityResourceTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = ['tour'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $entityTypeId = 'tour';
-
-  /**
-   * @var \Drupal\tour\TourInterface
-   */
-  protected $entity;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUpAuthorization($method) {
-    $this->grantPermissionsToTestedRole(['access tour']);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function createEntity() {
-    $tour = Tour::create([
-      'id' => 'tour-llama',
-      'label' => 'Llama tour',
-      'langcode' => 'en',
-      'module' => 'tour',
-      'routes' => [
-        [
-          'route_name' => '<front>',
-        ],
-      ],
-      'tips' => [
-        'tour-llama-1' => [
-          'id' => 'tour-llama-1',
-          'plugin' => 'text',
-          'label' => 'Llama',
-          'body' => 'Who handle the awesomeness of llamas?',
-          'weight' => 100,
-          'selector' => '#tour-llama-1',
-        ],
-      ],
-    ]);
-    $tour->save();
-
-    return $tour;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getExpectedNormalizedEntity() {
-    return [
-      'dependencies' => [],
-      'id' => 'tour-llama',
-      'label' => 'Llama tour',
-      'langcode' => 'en',
-      'module' => 'tour',
-      'routes' => [
-        [
-          'route_name' => '<front>',
-        ],
-      ],
-      'status' => TRUE,
-      'tips' => [
-        'tour-llama-1' => [
-          'id' => 'tour-llama-1',
-          'plugin' => 'text',
-          'label' => 'Llama',
-          'body' => 'Who handle the awesomeness of llamas?',
-          'weight' => 100,
-          'selector' => '#tour-llama-1',
-        ],
-      ],
-      'uuid' => $this->entity->uuid(),
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getNormalizedPostEntity() {
-    // @todo Update in https://www.drupal.org/node/2300677.
-    return [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getExpectedCacheContexts() {
-    return [
-      'user.permissions',
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getExpectedUnauthorizedAccessMessage($method) {
-    return "The following permissions are required: 'access tour' OR 'administer site configuration'.";
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Functional/Rest/TourXmlAnonTest.php b/core/modules/tour/tests/src/Functional/Rest/TourXmlAnonTest.php
deleted file mode 100644
index 416c3b353b..0000000000
--- a/core/modules/tour/tests/src/Functional/Rest/TourXmlAnonTest.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional\Rest;
-
-use Drupal\Tests\rest\Functional\AnonResourceTestTrait;
-use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
-
-/**
- * @group rest
- */
-class TourXmlAnonTest extends TourResourceTestBase {
-
-  use AnonResourceTestTrait;
-  use XmlEntityNormalizationQuirksTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $format = 'xml';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $mimeType = 'text/xml; charset=UTF-8';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-}
diff --git a/core/modules/tour/tests/src/Functional/Rest/TourXmlBasicAuthTest.php b/core/modules/tour/tests/src/Functional/Rest/TourXmlBasicAuthTest.php
deleted file mode 100644
index 6828e1d035..0000000000
--- a/core/modules/tour/tests/src/Functional/Rest/TourXmlBasicAuthTest.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional\Rest;
-
-use Drupal\Tests\rest\Functional\BasicAuthResourceTestTrait;
-use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
-
-/**
- * @group rest
- */
-class TourXmlBasicAuthTest extends TourResourceTestBase {
-
-  use BasicAuthResourceTestTrait;
-  use XmlEntityNormalizationQuirksTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = ['basic_auth'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $format = 'xml';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $mimeType = 'text/xml; charset=UTF-8';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $auth = 'basic_auth';
-
-}
diff --git a/core/modules/tour/tests/src/Functional/Rest/TourXmlCookieTest.php b/core/modules/tour/tests/src/Functional/Rest/TourXmlCookieTest.php
deleted file mode 100644
index 4fee143b93..0000000000
--- a/core/modules/tour/tests/src/Functional/Rest/TourXmlCookieTest.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional\Rest;
-
-use Drupal\Tests\rest\Functional\CookieResourceTestTrait;
-use Drupal\Tests\rest\Functional\EntityResource\XmlEntityNormalizationQuirksTrait;
-
-/**
- * @group rest
- */
-class TourXmlCookieTest extends TourResourceTestBase {
-
-  use CookieResourceTestTrait;
-  use XmlEntityNormalizationQuirksTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $format = 'xml';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $mimeType = 'text/xml; charset=UTF-8';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $auth = 'cookie';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-}
diff --git a/core/modules/tour/tests/src/Functional/TourCacheTagsTest.php b/core/modules/tour/tests/src/Functional/TourCacheTagsTest.php
deleted file mode 100644
index d5a587f2c6..0000000000
--- a/core/modules/tour/tests/src/Functional/TourCacheTagsTest.php
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional;
-
-use Drupal\Core\Url;
-use Drupal\Tests\system\Functional\Cache\PageCacheTagsTestBase;
-use Drupal\tour\Entity\Tour;
-use Drupal\user\Entity\Role;
-use Drupal\user\RoleInterface;
-
-/**
- * Tests the Tour entity's cache tags.
- *
- * @group tour
- */
-class TourCacheTagsTest extends PageCacheTagsTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = ['tour', 'tour_test'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-
-    // Give anonymous users permission to view nodes, so that we can verify the
-    // cache tags of cached versions of node pages.
-    Role::load(RoleInterface::ANONYMOUS_ID)->grantPermission('access tour')
-      ->save();
-  }
-
-  /**
-   * Tests cache tags presence and invalidation of the Tour entity.
-   *
-   * Tests the following cache tags:
-   * - 'tour:<tour ID>'
-   */
-  public function testRenderedTour() {
-    $url = Url::fromRoute('tour_test.1');
-
-    // Prime the page cache.
-    $this->verifyPageCache($url, 'MISS');
-
-    // Verify a cache hit, but also the presence of the correct cache tags.
-    $expected_tags = [
-      'config:tour.tour.tour-test',
-      'config:user.role.anonymous',
-      'http_response',
-      'rendered',
-    ];
-    $this->verifyPageCache($url, 'HIT', $expected_tags);
-
-    // Verify that after modifying the tour, there is a cache miss.
-    Tour::load('tour-test')->save();
-    $this->verifyPageCache($url, 'MISS');
-
-    // Verify a cache hit.
-    $this->verifyPageCache($url, 'HIT', $expected_tags);
-
-    // Verify that after deleting the tour, there is a cache miss.
-    Tour::load('tour-test')->delete();
-    $this->verifyPageCache($url, 'MISS');
-
-    // Verify a cache hit.
-    $expected_tags = [
-      'config:user.role.anonymous',
-      'http_response',
-      'rendered',
-    ];
-    $this->verifyPageCache($url, 'HIT', $expected_tags);
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Functional/TourHelpPageTest.php b/core/modules/tour/tests/src/Functional/TourHelpPageTest.php
deleted file mode 100644
index 2dabc7d58d..0000000000
--- a/core/modules/tour/tests/src/Functional/TourHelpPageTest.php
+++ /dev/null
@@ -1,152 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional;
-
-use Drupal\Tests\BrowserTestBase;
-
-/**
- * Verifies help page display of tours.
- *
- * @group help
- */
-class TourHelpPageTest extends BrowserTestBase {
-
-  /**
-   * Modules to enable, including some providing tours.
-   *
-   * @var array
-   */
-  protected static $modules = ['help', 'tour', 'locale', 'language'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-  /**
-   * User that can access tours and help.
-   *
-   * @var \Drupal\user\UserInterface
-   */
-  protected $tourUser;
-
-  /**
-   * A user who can access help but not tours.
-   *
-   * @var \Drupal\user\UserInterface
-   */
-  protected $noTourUser;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-
-    // Create users. For the Tour user, include permissions for the language
-    // tours' parent pages, but not the translation tour's parent page. See
-    // self:getTourList().
-    $this->tourUser = $this->drupalCreateUser([
-      'access help pages',
-      'access tour',
-      'administer languages',
-    ]);
-    $this->noTourUser = $this->drupalCreateUser([
-      'access help pages',
-    ]);
-  }
-
-  /**
-   * Logs in users, tests help pages.
-   */
-  public function testHelp() {
-    $this->drupalLogin($this->tourUser);
-    $this->verifyHelp();
-
-    $this->drupalLogin($this->noTourUser);
-    $this->verifyHelp(FALSE);
-  }
-
-  /**
-   * Verifies the logged in user has access to the help properly.
-   *
-   * @param bool $tours_ok
-   *   (optional) TRUE (default) if the user should see tours, FALSE if not.
-   */
-  protected function verifyHelp($tours_ok = TRUE) {
-    $this->drupalGet('admin/help');
-
-    // All users should be able to see the module section.
-    $this->assertSession()->pageTextContains('Module overviews are provided by modules');
-    foreach ($this->getModuleList() as $name) {
-      $this->assertSession()->linkExists($name);
-    }
-
-    // Some users should be able to see the tour section.
-    if ($tours_ok) {
-      $this->assertSession()->pageTextContains('Tours guide you through workflows');
-    }
-    else {
-      $this->assertSession()->pageTextNotContains('Tours guide you through workflows');
-    }
-
-    $titles = $this->getTourList();
-
-    // Test the titles that should be links.
-    foreach ($titles[0] as $title) {
-      if ($tours_ok) {
-        $this->assertSession()->linkExists($title);
-      }
-      else {
-        $this->assertSession()->linkNotExists($title);
-        // Just test the first item in the list of links that should not
-        // be there, because the second matches the name of a module that is
-        // in the Module overviews section, so the link will be there and
-        // this test will fail. Testing one should be sufficient to verify
-        // the page is working correctly.
-        break;
-      }
-    }
-
-    // Test the titles that should not be links.
-    foreach ($titles[1] as $title) {
-      if ($tours_ok) {
-        $this->assertSession()->pageTextContains($title);
-        $this->assertSession()->linkNotExistsExact($title);
-      }
-      else {
-        $this->assertSession()->pageTextNotContains($title);
-        // Just test the first item in the list of text that should not
-        // be there, because the second matches part of the name of a module
-        // that is in the Module overviews section, so the text will be there
-        // and this test will fail. Testing one should be sufficient to verify
-        // the page is working correctly.
-        break;
-      }
-    }
-  }
-
-  /**
-   * Gets a list of modules to test for hook_help() pages.
-   *
-   * @return array
-   *   A list of module names to test.
-   */
-  protected function getModuleList() {
-    return ['Help', 'Tour'];
-  }
-
-  /**
-   * Gets a list of tours to test.
-   *
-   * @return array
-   *   A list of tour titles to test. The first array element is a list of tours
-   *   with links, and the second is a list of tours without links. Assumes
-   *   that the user being tested has 'administer languages' permission but
-   *   not 'translate interface'.
-   */
-  protected function getTourList() {
-    return [['Adding languages', 'Language'], ['Editing languages', 'Translation']];
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Functional/TourTest.php b/core/modules/tour/tests/src/Functional/TourTest.php
deleted file mode 100644
index a7d8d40fdb..0000000000
--- a/core/modules/tour/tests/src/Functional/TourTest.php
+++ /dev/null
@@ -1,306 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional;
-
-use Drupal\Core\Url;
-use Drupal\language\Entity\ConfigurableLanguage;
-use Drupal\tour\Entity\Tour;
-
-/**
- * Tests the functionality of tour tips.
- *
- * @group tour
- */
-class TourTest extends TourTestBasic {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  protected static $modules = [
-    'block',
-    'tour',
-    'locale',
-    'language',
-    'tour_test',
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-  /**
-   * The permissions required for a logged in user to test tour tips.
-   *
-   * @var array
-   *   A list of permissions.
-   */
-  protected $permissions = ['access tour', 'administer languages'];
-
-  /**
-   * Tour tip attributes to be tested. Keyed by the path.
-   *
-   * @var array
-   *   An array of tip attributes, keyed by path.
-   */
-  protected $tips = [
-    'tour-test-1' => [],
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-
-    $this->drupalPlaceBlock('local_actions_block', [
-      'theme' => 'claro',
-      'region' => 'content',
-    ]);
-  }
-
-  /**
-   * Tests tour functionality.
-   */
-  public function testTourFunctionality() {
-    // Navigate to tour-test-1 and verify the tour_test_1 tip is found with appropriate classes.
-    $this->drupalGet('tour-test-1');
-
-    // Test the TourTestBase class assertTourTips() method.
-    $tips = [];
-    $tips[] = ['data-id' => 'tour-test-1'];
-    $tips[] = ['data-class' => 'tour-test-5'];
-    $this->assertTourTips($tips);
-    $this->assertTourTips();
-
-    $tips = $this->getTourTips();
-
-    $href = Url::fromRoute('<front>', [], ['absolute' => TRUE])->toString();
-    $elements = [];
-    foreach ($tips as $tip) {
-      if ($tip['id'] == 'tour-test-1' && $tip['module'] == 'tour_test' && $tip['type'] == 'text' && str_contains($tip['body'], $href) && str_contains($tip['body'], 'Drupal')) {
-        $elements[] = $tip;
-      }
-    }
-    $this->assertCount(1, $elements, 'Found Token replacement.');
-
-    $elements = $this->findTip([
-      'id' => 'tour-test-1',
-      'title' => 'The first tip',
-    ]);
-    $this->assertCount(1, $elements, 'Found English variant of tip 1.');
-
-    $elements = $this->findTip([
-      'id' => 'tour-test-2',
-      'title' => 'The quick brown fox',
-    ]);
-    $this->assertNotCount(1, $elements, 'Did not find English variant of tip 2.');
-
-    $elements = $this->findTip([
-      'id' => 'tour-test-1',
-      'title' => 'La pioggia cade in spagna',
-    ]);
-    $this->assertNotCount(1, $elements, 'Did not find Italian variant of tip 1.');
-
-    // Ensure that plugins work.
-    $elements = [];
-    foreach ($tips as $tip) {
-      if (str_contains($tip['body'], 'http://local/image.png')) {
-        $elements[] = $tip;
-      }
-    }
-    $this->assertCount(1, $elements, 'Image plugin tip found.');
-
-    // Navigate to tour-test-2/subpath and verify the tour_test_2 tip is found.
-    $this->drupalGet('tour-test-2/subpath');
-
-    $elements = $this->findTip([
-      'id' => 'tour-test-2',
-      'title' => 'The quick brown fox',
-    ]);
-    $this->assertCount(1, $elements, 'Found English variant of tip 2.');
-
-    $elements = $this->findTip([
-      'id' => 'tour-test-1',
-      'title' => 'The first tip',
-    ]);
-    $this->assertNotCount(1, $elements, 'Did not find English variant of tip 1.');
-
-    // Enable Italian language and navigate to it/tour-test1 and verify italian
-    // version of tip is found.
-    ConfigurableLanguage::createFromLangcode('it')->save();
-    $this->drupalGet('it/tour-test-1');
-
-    $elements = $this->findTip([
-      'id' => 'tour-test-1',
-      'title' => 'La pioggia cade in spagna',
-    ]);
-    $this->assertCount(1, $elements, 'Found Italian variant of tip 1.');
-
-    $elements = $this->findTip([
-      'id' => 'tour-test-2',
-      'title' => 'The quick brown fox',
-    ]);
-    $this->assertNotCount(1, $elements, 'Did not find English variant of tip 1.');
-
-    // Programmatically create a tour for use through the remainder of the test.
-    $tour = Tour::create([
-      'id' => 'tour-entity-create-test-en',
-      'label' => 'Tour test english',
-      'langcode' => 'en',
-      'module' => 'system',
-      'routes' => [
-        ['route_name' => 'tour_test.1'],
-      ],
-      'tips' => [
-        'tour-test-1' => [
-          'id' => 'tour-code-test-1',
-          'plugin' => 'text',
-          'label' => 'The rain in spain is <strong>strong</strong>',
-          'body' => 'Falls mostly on the plain.',
-          'weight' => '100',
-          'selector' => '#tour-code-test-1',
-        ],
-        'tour-code-test-2' => [
-          'id' => 'tour-code-test-2',
-          'plugin' => 'image',
-          'label' => 'The awesome image',
-          'url' => 'http://local/image.png',
-          'weight' => 1,
-          'selector' => '#tour-code-test-2',
-        ],
-      ],
-    ]);
-    $tour->save();
-
-    // Ensure that a tour entity has the expected dependencies based on plugin
-    // providers and the module named in the configuration entity.
-    $dependencies = $tour->calculateDependencies()->getDependencies();
-    $this->assertEquals(['system', 'tour_test'], $dependencies['module']);
-
-    $this->drupalGet('tour-test-1');
-
-    // Load it back from the database and verify storage worked.
-    $entity_save_tip = Tour::load('tour-entity-create-test-en');
-    // Verify that hook_ENTITY_TYPE_load() integration worked.
-    $this->assertEquals('Load hooks work', $entity_save_tip->loaded);
-    // Verify that hook_ENTITY_TYPE_presave() integration worked.
-    $this->assertEquals('Tour test english alter', $entity_save_tip->label());
-
-    // Navigate to tour-test-1 and verify the new tip is found.
-    $this->drupalGet('tour-test-1');
-
-    $elements = $this->findTip([
-      'id' => 'tour-code-test-1',
-      'title' => 'The rain in spain is <strong>strong</strong>',
-    ]);
-    $this->assertCount(1, $elements, 'Found the required tip markup for tip 4');
-
-    // Verify that the weight sorting works by ensuring the lower weight item
-    // (tip 4) has the 'End tour' button.
-    $elements = $this->findTip([
-      'id' => 'tour-code-test-1',
-      'text' => 'End tour',
-    ]);
-    $this->assertCount(1, $elements, 'Found code tip was weighted last and had "End tour".');
-
-    // Test hook_tour_alter().
-    $this->assertSession()->responseContains('Altered by hook_tour_tips_alter');
-
-    // Navigate to tour-test-3 and verify the tour_test_1 tip is found with
-    // appropriate classes.
-    $this->drupalGet('tour-test-3/foo');
-
-    $elements = $this->findTip([
-      'id' => 'tour-test-1',
-      'module' => 'tour_test',
-      'type' => 'text',
-      'title' => 'The first tip',
-    ]);
-    $this->assertCount(1, $elements, 'Found English variant of tip 1.');
-
-    // Navigate to tour-test-3 and verify the tour_test_1 tip is not found with
-    // appropriate classes.
-    $this->drupalGet('tour-test-3/bar');
-
-    $elements = $this->findTip([
-      'id' => 'tour-test-1',
-      'module' => 'tour_test',
-      'type' => 'text',
-      'title' => 'The first tip',
-    ]);
-    $this->assertCount(0, $elements, 'Did not find English variant of tip 1.');
-  }
-
-  /**
-   * Tests enabling and disabling the tour tip functionality.
-   */
-  public function testStatus() {
-    // Set tour tip status as enabled.
-    $tour = Tour::load('tour-test');
-    $tour->setStatus(TRUE);
-    $tour->save();
-
-    $this->drupalGet('tour-test-1');
-    $this->assertSession()->statusCodeEquals(200);
-
-    // Tour tips should be visible on the page.
-    $this->assertTourTips();
-
-    $tour->setStatus(FALSE);
-    $tour->save();
-
-    // Navigate and verify the tour_test_1 tip is not found with
-    // appropriate classes.
-    $this->drupalGet('tour-test-1');
-    $this->assertSession()->statusCodeEquals(200);
-
-    // No tips expected as tour is disabled.
-    $this->assertTourTips(expectEmpty: TRUE);
-  }
-
-  /**
-   * Gets tour tips from the JavaScript drupalSettings variable.
-   *
-   * @return array
-   *   A list of tips and their data.
-   */
-  protected function getTourTips() {
-    $tips = [];
-    $drupalSettings = $this->getDrupalSettings();
-    if (isset($drupalSettings['_tour_internal'])) {
-      foreach ($drupalSettings['_tour_internal'] as $tip) {
-        $tips[] = $tip;
-      }
-    }
-
-    return $tips;
-  }
-
-  /**
-   * Find specific tips by their parameters in the list of tips.
-   *
-   * @param array $params
-   *   The list of search parameters and their values.
-   *
-   * @return array
-   *   A list of tips which match the parameters.
-   */
-  protected function findTip(array $params) {
-    $tips = $this->getTourTips();
-    $elements = [];
-    foreach ($tips as $tip) {
-      foreach ($params as $param => $value) {
-        if (isset($tip[$param]) && $tip[$param] != $value) {
-          continue 2;
-        }
-      }
-      $elements[] = $tip;
-    }
-
-    return $elements;
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Functional/TourTestBase.php b/core/modules/tour/tests/src/Functional/TourTestBase.php
deleted file mode 100644
index de9fb4595e..0000000000
--- a/core/modules/tour/tests/src/Functional/TourTestBase.php
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional;
-
-use Drupal\Component\Render\FormattableMarkup;
-use Drupal\Tests\BrowserTestBase;
-
-/**
- * Base class for testing Tour functionality.
- */
-abstract class TourTestBase extends BrowserTestBase {
-
-  /**
-   * Asserts the presence of page elements for tour tips.
-   *
-   * @code
-   * // Basic example.
-   * $this->assertTourTips();
-   *
-   * // Advanced example. The following would be used for multipage or
-   * // targeting a specific subset of tips.
-   * $tips = array();
-   * $tips[] = array('data-id' => 'foo');
-   * $tips[] = array('data-id' => 'bar');
-   * $tips[] = array('data-class' => 'baz');
-   * $this->assertTourTips($tips);
-   * @endcode
-   *
-   * @param array $tips
-   *   A list of tips which provide either a "data-id" or "data-class".
-   * @param bool $expectEmpty
-   *   Whether or not the field is expected to be Empty.
-   */
-  public function assertTourTips(array $tips = [], bool $expectEmpty = FALSE) {
-    // Get the rendered tips and their data-id and data-class attributes.
-    if (empty($tips)) {
-      // Tips are rendered as drupalSettings values.
-      $drupalSettings = $this->getDrupalSettings();
-      if (isset($drupalSettings['_tour_internal'])) {
-        foreach ($drupalSettings['_tour_internal'] as $tip) {
-          $tips[] = [
-            'selector' => $tip['selector'] ?? NULL,
-          ];
-        }
-      }
-    }
-
-    $tip_count = count($tips);
-    if ($tip_count === 0 && $expectEmpty) {
-      // No tips found as expected.
-      return;
-    }
-    if ($tip_count > 0 && $expectEmpty) {
-      $this->fail(sprintf('No tips were expected but %d were found', $tip_count));
-    }
-    $this->assertGreaterThan(0, $tip_count);
-
-    // Check for corresponding page elements.
-    $total = 0;
-    $modals = 0;
-    foreach ($tips as $tip) {
-      if (!empty($tip['data-id'])) {
-        $elements = $this->getSession()->getPage()->findAll('css', '#' . $tip['data-id']);
-        $this->assertCount(1, $elements, new FormattableMarkup('Found corresponding page element for tour tip with id #%data-id', ['%data-id' => $tip['data-id']]));
-      }
-      elseif (!empty($tip['data-class'])) {
-        $elements = $this->getSession()->getPage()->findAll('css', '.' . $tip['data-class']);
-        $this->assertNotEmpty($elements, sprintf("Page element for tour tip with class .%s should be present", $tip['data-class']));
-      }
-      else {
-        // It's a modal.
-        $modals++;
-      }
-      $total++;
-    }
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Functional/TourTestBasic.php b/core/modules/tour/tests/src/Functional/TourTestBasic.php
deleted file mode 100644
index 7a878ee1d6..0000000000
--- a/core/modules/tour/tests/src/Functional/TourTestBasic.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Functional;
-
-/**
- * Simple tour tips test base.
- */
-abstract class TourTestBasic extends TourTestBase {
-
-  /**
-   * Tour tip attributes to be tested. Keyed by the path.
-   *
-   * @var array
-   *   An array of tip attributes, keyed by path.
-   *
-   * @code
-   * protected $tips = array(
-   *   '/foo/bar' => array(
-   *     array('data-id' => 'foo'),
-   *     array('data-class' => 'bar'),
-   *   ),
-   * );
-   * @endcode
-   */
-  protected $tips = [];
-
-  /**
-   * An admin user with administrative permissions for tour.
-   *
-   * @var \Drupal\user\UserInterface
-   */
-  protected $adminUser;
-
-  /**
-   * The permissions required for a logged in user to test tour tips.
-   *
-   * @var array
-   *   A list of permissions.
-   */
-  protected $permissions = ['access tour'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-
-    // Make sure we are using distinct default and administrative themes for
-    // the duration of these tests.
-    $this->container->get('theme_installer')->install(['olivero', 'claro']);
-    $this->config('system.theme')
-      ->set('default', 'olivero')
-      ->set('admin', 'claro')
-      ->save();
-
-    $this->permissions[] = 'view the administration theme';
-
-    // Create an admin user to view tour tips.
-    $this->adminUser = $this->drupalCreateUser($this->permissions);
-    $this->drupalLogin($this->adminUser);
-  }
-
-  /**
-   * A simple tip test.
-   */
-  public function testTips() {
-    foreach ($this->tips as $path => $attributes) {
-      $this->drupalGet($path);
-      $this->assertTourTips($attributes);
-    }
-  }
-
-}
diff --git a/core/modules/tour/tests/src/FunctionalJavascript/TourJavascriptTest.php b/core/modules/tour/tests/src/FunctionalJavascript/TourJavascriptTest.php
deleted file mode 100644
index 51494d25e3..0000000000
--- a/core/modules/tour/tests/src/FunctionalJavascript/TourJavascriptTest.php
+++ /dev/null
@@ -1,131 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
-
-/**
- * General Tour tests that require JavaScript.
- *
- * @group tour
- */
-class TourJavascriptTest extends WebDriverTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = [
-    'tour',
-    'tour_test',
-    'toolbar',
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected $defaultTheme = 'stark';
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-
-    $admin_user = $this->drupalCreateUser([
-      'access toolbar',
-      'access tour',
-    ]);
-    $this->drupalLogin($admin_user);
-  }
-
-  /**
-   * Confirm the 'tips' and 'tour 'query arguments.
-   */
-  public function testQueryArg() {
-    $assert_session = $this->assertSession();
-
-    $this->drupalGet('tour-test-1');
-    $assert_session->assertNoElementAfterWait('css', '.tip-tour-test-1');
-    $assert_session->pageTextContains('Where does the rain in Spain fail?');
-    $assert_session->pageTextNotContains('Im all these things');
-    $assert_session->pageTextNotContains('The first tip');
-
-    $this->drupalGet('tour-test-1', [
-      'query' => [
-        'tips' => 'tip-tour-test-6',
-      ],
-    ]);
-    $this->assertNotNull($assert_session->waitForElementVisible('css', '.tip-tour-test-6'));
-    $assert_session->pageTextContains('Im all these things');
-
-    $this->drupalGet('tour-test-1', [
-      'query' => [
-        'tour' => '1',
-      ],
-    ]);
-    $this->assertNotNull($assert_session->waitForElementVisible('css', '.tip-tour-test-1'));
-    $assert_session->pageTextContains('The first tip');
-  }
-
-  /**
-   * Tests stepping through a tour.
-   */
-  public function testGeneralTourUse() {
-    $page = $this->getSession()->getPage();
-    $assert_session = $this->assertSession();
-
-    $this->drupalGet('tour-test-1');
-
-    $assert_session->assertNoElementAfterWait('css', '.tip-tour-test-1');
-
-    // Open the tour.
-    $page->find('css', '#toolbar-tab-tour button')->press();
-
-    // Confirm the tour can be cancelled.
-    $tip_to_close = $assert_session->waitForElementVisible('css', '.shepherd-enabled.tip-tour-test-1');
-    $this->assertNotNull($tip_to_close);
-    $tip_text = $tip_to_close->getText();
-    $this->assertStringContainsString('always the best dressed', $tip_text);
-    $this->assertStringContainsString('1 of 3', $tip_text);
-    $this->assertStringNotContainsString('End tour', $tip_text);
-
-    // Cancel the tour.
-    $tip_to_close->find('css', '.shepherd-cancel-icon')->press();
-    $assert_session->assertNoElementAfterWait('css', '.tip-tour-test-1');
-    $assert_session->assertNoElementAfterWait('css', '.shepherd-enabled');
-
-    // Navigate through the three steps of the tour.
-    $page->find('css', '#toolbar-tab-tour button')->press();
-    $tip1 = $assert_session->waitForElementVisible('css', '.shepherd-enabled.tip-tour-test-1');
-    $this->assertNotNull($tip1);
-
-    // Click the next button.
-    $tip1->find('css', '.button--primary:contains("Next")')->press();
-
-    // The second tour tip should appear, confirm it has the expected content.
-    $tip2 = $assert_session->waitForElementVisible('css', '.shepherd-enabled.tip-tour-test-3');
-    $assert_session->pageTextNotContains('always the best dressed');
-    $tip_text = $tip2->getText();
-    $this->assertStringContainsString('The awesome image', $tip_text);
-    $this->assertStringContainsString('2 of 3', $tip_text);
-    $this->assertStringNotContainsString('End tour', $tip_text);
-
-    // Click the next button.
-    $tip2->find('css', '.button--primary:contains("Next")')->press();
-
-    // The third tour tip should appear, confirm it has the expected content.
-    $tip3 = $assert_session->waitForElementVisible('css', '.shepherd-enabled.tip-tour-test-6');
-    $assert_session->pageTextNotContains('The awesome image');
-    $tip_text = $tip3->getText();
-    $this->assertStringContainsString('Im all these things', $tip_text);
-    $this->assertStringContainsString('3 of 3', $tip_text);
-    $this->assertStringNotContainsString('Next', $tip_text);
-
-    // The final tip should have a button to end the tour. Press and confirm all
-    // tips removed.
-    $tip3->find('css', '.button--primary:contains("End tour")')->press();
-    $assert_session->assertNoElementAfterWait('css', '.shepherd-enabled');
-    $assert_session->pageTextNotContains('The awesome image');
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Kernel/TourPluginTest.php b/core/modules/tour/tests/src/Kernel/TourPluginTest.php
deleted file mode 100644
index d647716c2f..0000000000
--- a/core/modules/tour/tests/src/Kernel/TourPluginTest.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Kernel;
-
-use Drupal\KernelTests\KernelTestBase;
-
-/**
- * Tests the functionality of tour plugins.
- *
- * @group tour
- */
-class TourPluginTest extends KernelTestBase {
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  protected static $modules = ['tour'];
-
-  /**
-   * Stores the tour plugin manager.
-   *
-   * @var \Drupal\tour\TipPluginManager
-   */
-  protected $pluginManager;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-
-    $this->installConfig(['tour']);
-    $this->pluginManager = $this->container->get('plugin.manager.tour.tip');
-  }
-
-  /**
-   * Tests tour plugins.
-   */
-  public function testTourPlugins() {
-    $this->assertCount(1, $this->pluginManager->getDefinitions(), 'Only tour plugins for the enabled modules were returned.');
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Kernel/TourTipLegacyTest.php b/core/modules/tour/tests/src/Kernel/TourTipLegacyTest.php
deleted file mode 100644
index 039d84e441..0000000000
--- a/core/modules/tour/tests/src/Kernel/TourTipLegacyTest.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Kernel;
-
-use Drupal\tour\TourTipPluginInterface;
-use PHPUnit\Framework\TestCase;
-use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
-
-/**
- * @coversDefaultClass \Drupal\tour\TourTipPluginInterface
- * @group tour
- * @group legacy
- */
-class TourTipLegacyTest extends TestCase {
-  use ExpectDeprecationTrait;
-
-  public function testPluginHelperDeprecation(): void {
-    $this->expectDeprecation('The Drupal\tour\TourTipPluginInterface is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Implement Drupal\tour\TipPluginInterface instead. See https://www.drupal.org/node/3340701.');
-    $plugin = $this->createMock(TourTipPluginInterface::class);
-    $this->assertInstanceOf(TourTipPluginInterface::class, $plugin);
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Kernel/TourValidationTest.php b/core/modules/tour/tests/src/Kernel/TourValidationTest.php
deleted file mode 100644
index 42b0d28640..0000000000
--- a/core/modules/tour/tests/src/Kernel/TourValidationTest.php
+++ /dev/null
@@ -1,34 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Kernel;
-
-use Drupal\KernelTests\Core\Config\ConfigEntityValidationTestBase;
-use Drupal\tour\Entity\Tour;
-
-/**
- * Tests validation of tour entities.
- *
- * @group tour
- */
-class TourValidationTest extends ConfigEntityValidationTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected static $modules = ['tour'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp(): void {
-    parent::setUp();
-
-    $this->entity = Tour::create([
-      'id' => 'test',
-      'label' => 'Test',
-      'module' => 'system',
-    ]);
-    $this->entity->save();
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Unit/Entity/TourTest.php b/core/modules/tour/tests/src/Unit/Entity/TourTest.php
deleted file mode 100644
index b1f3db0bbc..0000000000
--- a/core/modules/tour/tests/src/Unit/Entity/TourTest.php
+++ /dev/null
@@ -1,138 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Unit\Entity;
-
-use Drupal\Tests\UnitTestCase;
-
-/**
- * @coversDefaultClass \Drupal\tour\Entity\Tour
- * @group tour
- */
-class TourTest extends UnitTestCase {
-
-  /**
-   * Tests \Drupal\tour\Entity\Tour::hasMatchingRoute().
-   *
-   * @param array $routes
-   *   Array of routes as per the Tour::routes property.
-   * @param string $route_name
-   *   The route name to match.
-   * @param array $route_params
-   *   Array of route params.
-   * @param bool $result
-   *   Expected result.
-   *
-   * @covers ::hasMatchingRoute
-   *
-   * @dataProvider routeProvider
-   */
-  public function testHasMatchingRoute($routes, $route_name, $route_params, $result) {
-    $tour = $this->getMockBuilder('\Drupal\tour\Entity\Tour')
-      ->disableOriginalConstructor()
-      ->onlyMethods(['getRoutes'])
-      ->getMock();
-
-    $tour->expects($this->any())
-      ->method('getRoutes')
-      ->willReturn($routes);
-
-    $this->assertSame($result, $tour->hasMatchingRoute($route_name, $route_params));
-
-    $tour->resetKeyedRoutes();
-  }
-
-  /**
-   * Provides sample routes for testing.
-   */
-  public function routeProvider() {
-    return [
-      // Simple match.
-      [
-        [
-          ['route_name' => 'some.route'],
-        ],
-        'some.route',
-        [],
-        TRUE,
-      ],
-      // Simple non-match.
-      [
-        [
-          ['route_name' => 'another.route'],
-        ],
-        'some.route',
-        [],
-        FALSE,
-      ],
-      // Empty params.
-      [
-        [
-          [
-            'route_name' => 'some.route',
-            'route_params' => ['foo' => 'bar'],
-          ],
-        ],
-        'some.route',
-        [],
-        FALSE,
-      ],
-      // Match on params.
-      [
-        [
-          [
-            'route_name' => 'some.route',
-            'route_params' => ['foo' => 'bar'],
-          ],
-        ],
-        'some.route',
-        ['foo' => 'bar'],
-        TRUE,
-      ],
-      // Non-matching params.
-      [
-        [
-          [
-            'route_name' => 'some.route',
-            'route_params' => ['foo' => 'bar'],
-          ],
-        ],
-        'some.route',
-        ['bar' => 'foo'],
-        FALSE,
-      ],
-      // One matching, one not.
-      [
-        [
-          [
-            'route_name' => 'some.route',
-            'route_params' => ['foo' => 'bar'],
-          ],
-          [
-            'route_name' => 'some.route',
-            'route_params' => ['bar' => 'foo'],
-          ],
-        ],
-        'some.route',
-        ['bar' => 'foo'],
-        TRUE,
-      ],
-      // One matching, one not.
-      [
-        [
-          [
-            'route_name' => 'some.route',
-            'route_params' => ['foo' => 'bar'],
-          ],
-          [
-            'route_name' => 'some.route',
-            'route_params' => ['foo' => 'baz'],
-          ],
-        ],
-        'some.route',
-        ['foo' => 'baz'],
-        TRUE,
-      ],
-    ];
-  }
-
-}
diff --git a/core/modules/tour/tests/src/Unit/TipPluginBaseTest.php b/core/modules/tour/tests/src/Unit/TipPluginBaseTest.php
deleted file mode 100644
index 5db0e3ab32..0000000000
--- a/core/modules/tour/tests/src/Unit/TipPluginBaseTest.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-
-namespace Drupal\Tests\tour\Unit;
-
-use Drupal\Tests\UnitTestCase;
-use Drupal\tour\TipPluginBase;
-
-/**
- * @coversDefaultClass \Drupal\tour\TipPluginBase
- *
- * @group tour
- */
-class TipPluginBaseTest extends UnitTestCase {
-
-  /**
-   * @covers ::getLocation
-   */
-  public function testGetLocationAssertion() {
-    $base_plugin = $this->getMockForAbstractClass(TipPluginBase::class, [], '', FALSE);
-
-    $base_plugin->set('position', 'right');
-    $this->assertSame('right', $base_plugin->getLocation());
-
-    $base_plugin->set('position', 'not_valid');
-    $this->expectException(\AssertionError::class);
-    $this->expectExceptionMessage('not_valid is not a valid Tour Tip position value');
-    $base_plugin->getLocation();
-  }
-
-}
diff --git a/core/modules/tour/tests/tour_test/config/install/language/it/tour.tour.tour-test.yml b/core/modules/tour/tests/tour_test/config/install/language/it/tour.tour.tour-test.yml
deleted file mode 100644
index e36e435b15..0000000000
--- a/core/modules/tour/tests/tour_test/config/install/language/it/tour.tour.tour-test.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-label: Tour test italian
-tips:
-  tour-test-1:
-    label: La pioggia cade in spagna
-    body: Per lo più in pianura.
diff --git a/core/modules/tour/tests/tour_test/config/install/tour.tour.tour-test-2.yml b/core/modules/tour/tests/tour_test/config/install/tour.tour.tour-test-2.yml
deleted file mode 100644
index 5531e285c4..0000000000
--- a/core/modules/tour/tests/tour_test/config/install/tour.tour.tour-test-2.yml
+++ /dev/null
@@ -1,15 +0,0 @@
-langcode: en
-id: tour-test-2
-label: 'Tour test english'
-module: tour_test
-routes:
-  -
-    route_name: tour_test.2
-tips:
-  tour-test-2:
-    id: tour-test-2
-    plugin: text
-    label: 'The quick brown fox'
-    weight: 2
-    selector: '#tour-test-2'
-    body: 'Per lo più in pianura.'
diff --git a/core/modules/tour/tests/tour_test/config/install/tour.tour.tour-test.yml b/core/modules/tour/tests/tour_test/config/install/tour.tour.tour-test.yml
deleted file mode 100644
index 5ca1fa4899..0000000000
--- a/core/modules/tour/tests/tour_test/config/install/tour.tour.tour-test.yml
+++ /dev/null
@@ -1,39 +0,0 @@
-langcode: en
-id: tour-test
-label: 'Tour test english'
-module: tour_test
-routes:
-  -
-    route_name: tour_test.1
-  -
-    route_name: tour_test.3
-    route_params:
-      locale: foo
-tips:
-  tour-test-1:
-    id: tour-test-1
-    plugin: text
-    label: 'The first tip'
-    weight: 1
-    selector: '#tour-test-1'
-    body: 'Is <a href="[site:url]">[site:name]</a> always the best dressed?'
-  tour-test-action:
-    id: tour-test-3
-    plugin: text
-    label: 'The action'
-    weight: 2
-    selector: .button-action
-    body: 'The action button of awesome'
-  tour-test-3:
-    id: tour-test-3
-    plugin: image
-    label: 'The awesome image'
-    url: 'http://local/image.png'
-    weight: 1
-  tour-test-6:
-    id: tour-test-6
-    plugin: text
-    label: 'Im a list'
-    weight: 6
-    selector: '#tour-test-3'
-    body: '<p>Im all these things:</p><ul><li>Modal</li><li>Awesome</li></ul>'
diff --git a/core/modules/tour/tests/tour_test/config/schema/tour_test.schema.yml b/core/modules/tour/tests/tour_test/config/schema/tour_test.schema.yml
deleted file mode 100644
index a43cc2682f..0000000000
--- a/core/modules/tour/tests/tour_test/config/schema/tour_test.schema.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-# Schema for the configuration files of the Tour Test module.
-
-tour.tip.image:
-  type: tour.tip
-  label: 'Image tour tip'
-  mapping:
-    url:
-      type: uri
-      label: 'Image URL'
diff --git a/core/modules/tour/tests/tour_test/src/Controller/TourTestController.php b/core/modules/tour/tests/tour_test/src/Controller/TourTestController.php
deleted file mode 100644
index 56505aa0a0..0000000000
--- a/core/modules/tour/tests/tour_test/src/Controller/TourTestController.php
+++ /dev/null
@@ -1,74 +0,0 @@
-<?php
-
-namespace Drupal\tour_test\Controller;
-
-/**
- * Controller routines for tour_test routes.
- */
-class TourTestController {
-
-  /**
-   * Outputs some content for testing tours.
-   *
-   * @param string $locale
-   *   (optional) Dummy locale variable for testing routing parameters. Defaults
-   *   to 'foo'.
-   *
-   * @return array
-   *   Array of markup.
-   */
-  public function tourTest1($locale = 'foo') {
-    return [
-      'tip-1' => [
-        '#type' => 'container',
-        '#attributes' => [
-          'id' => 'tour-test-1',
-        ],
-        '#children' => t('Where does the rain in Spain fail?'),
-      ],
-      'tip-3' => [
-        '#type' => 'container',
-        '#attributes' => [
-          'id' => 'tour-test-3',
-        ],
-        '#children' => t('Tip created now?'),
-      ],
-      'tip-4' => [
-        '#type' => 'container',
-        '#attributes' => [
-          'id' => 'tour-test-4',
-        ],
-        '#children' => t('Tip created later?'),
-      ],
-      'tip-5' => [
-        '#type' => 'container',
-        '#attributes' => [
-          'class' => ['tour-test-5'],
-        ],
-        '#children' => t('Tip created later?'),
-      ],
-      'code-tip-1' => [
-        '#type' => 'container',
-        '#attributes' => [
-          'id' => 'tour-code-test-1',
-        ],
-        '#children' => t('Tip created now?'),
-      ],
-    ];
-  }
-
-  /**
-   * Outputs some content for testing tours.
-   */
-  public function tourTest2() {
-    return [
-      '#type' => 'container',
-      '#attributes' => [
-        'id' => 'tour-test-2',
-      ],
-      '#children' => t('Pangram example'),
-    ];
-
-  }
-
-}
diff --git a/core/modules/tour/tests/tour_test/src/Plugin/tour/tip/TipPluginImage.php b/core/modules/tour/tests/tour_test/src/Plugin/tour/tip/TipPluginImage.php
deleted file mode 100644
index ed4a14b2ff..0000000000
--- a/core/modules/tour/tests/tour_test/src/Plugin/tour/tip/TipPluginImage.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-
-namespace Drupal\tour_test\Plugin\tour\tip;
-
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Utility\Token;
-use Drupal\tour\TipPluginBase;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Displays an image as a tip.
- *
- * @Tip(
- *   id = "image",
- *   title = @Translation("Image")
- * )
- */
-class TipPluginImage extends TipPluginBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The URL which is used for the image in this Tip.
-   *
-   * @var string
-   *   A URL used for the image.
-   */
-  protected $url;
-
-  /**
-   * The alt text which is used for the image in this Tip.
-   *
-   * @var string
-   *   An alt text used for the image.
-   */
-  protected $alt;
-
-  /**
-   * Token service.
-   *
-   * @var \Drupal\Core\Utility\Token
-   */
-  protected $token;
-
-  /**
-   * Constructs a \Drupal\tour\Plugin\tour\tip\TipPluginText object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Utility\Token $token
-   *   The token service.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, Token $token) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->token = $token;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('token'));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getBody(): array {
-    $image = [
-      '#theme' => 'image',
-      '#uri' => $this->get('url'),
-      '#alt' => $this->get('alt'),
-    ];
-
-    return [
-      '#type' => 'html_tag',
-      '#tag' => 'p',
-      '#attributes' => [
-        'class' => ['tour-tip-image'],
-      ],
-      'image' => $image,
-    ];
-  }
-
-}
diff --git a/core/modules/tour/tests/tour_test/src/Plugin/tour/tip/TipPluginImageLegacy.php b/core/modules/tour/tests/tour_test/src/Plugin/tour/tip/TipPluginImageLegacy.php
deleted file mode 100644
index 580063eb6a..0000000000
--- a/core/modules/tour/tests/tour_test/src/Plugin/tour/tip/TipPluginImageLegacy.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-
-namespace Drupal\tour_test\Plugin\tour\tip;
-
-use Drupal\Component\Utility\Html;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Utility\Token;
-use Drupal\tour\TipPluginBase;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Displays an image as a tip.
- *
- * @Tip(
- *   id = "image_legacy",
- *   title = @Translation("Image Legacy")
- * )
- */
-class TipPluginImageLegacy extends TipPluginBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The URL which is used for the image in this Tip.
-   *
-   * @var string
-   *   A URL used for the image.
-   */
-  protected $url;
-
-  /**
-   * The alt text which is used for the image in this Tip.
-   *
-   * @var string
-   *   An alt text used for the image.
-   */
-  protected $alt;
-
-  /**
-   * Token service.
-   *
-   * @var \Drupal\Core\Utility\Token
-   */
-  protected $token;
-
-  /**
-   * Constructs a TipPluginImageLegacy object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Utility\Token $token
-   *   The token service.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, Token $token) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->token = $token;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('token'));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getConfigurationOrNot() {
-    $image = [
-      '#theme' => 'image',
-      '#uri' => $this->get('url'),
-      '#alt' => $this->get('alt'),
-    ];
-
-    return [
-      'title' => Html::escape($this->get('label')),
-      'body' => $this->token->replace(\Drupal::service('renderer')->renderPlain($image)),
-    ];
-  }
-
-}
diff --git a/core/modules/tour/tests/tour_test/src/Plugin/tour/tip/TipPluginTextLegacy.php b/core/modules/tour/tests/tour_test/src/Plugin/tour/tip/TipPluginTextLegacy.php
deleted file mode 100644
index 9cfc2dba31..0000000000
--- a/core/modules/tour/tests/tour_test/src/Plugin/tour/tip/TipPluginTextLegacy.php
+++ /dev/null
@@ -1,96 +0,0 @@
-<?php
-
-namespace Drupal\tour_test\Plugin\tour\tip;
-
-use Drupal\Component\Utility\Html;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Utility\Token;
-use Drupal\tour\TipPluginBase;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Displays some text as a tip.
- *
- * @Tip(
- *   id = "text_legacy",
- *   title = @Translation("Text Legacy")
- * )
- */
-class TipPluginTextLegacy extends TipPluginBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The body text which is used for render of this Text Tip.
-   *
-   * @var string
-   */
-  protected $body;
-
-  /**
-   * Token service.
-   *
-   * @var \Drupal\Core\Utility\Token
-   */
-  protected $token;
-
-  /**
-   * The forced position of where the tip will be located.
-   *
-   * @var string
-   */
-  protected $location;
-
-  /**
-   * Unique aria-id.
-   *
-   * @var string
-   */
-  protected $ariaId;
-
-  /**
-   * Constructs a TipPluginTextLegacy object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Utility\Token $token
-   *   The token service.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, Token $token) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->token = $token;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('token'));
-  }
-
-  /**
-   * Returns an ID that is guaranteed uniqueness.
-   *
-   * @return string
-   *   A unique id to be used to generate aria attributes.
-   */
-  public function getAriaId() {
-    if (!$this->ariaId) {
-      $this->ariaId = Html::getUniqueId($this->get('id'));
-    }
-    return $this->ariaId;
-  }
-
-  /**
-   * Returns body of the text tip.
-   *
-   * @return array
-   *   The tip body.
-   */
-  public function getBody(): array {
-    return [$this->get('body')];
-  }
-
-}
diff --git a/core/modules/tour/tests/tour_test/tour_test.info.yml b/core/modules/tour/tests/tour_test/tour_test.info.yml
deleted file mode 100644
index 7111abf832..0000000000
--- a/core/modules/tour/tests/tour_test/tour_test.info.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: Tour module tests
-type: module
-description: Tests module for tour module.
-package: Testing
-version: VERSION
-dependencies:
-  - drupal:tour
diff --git a/core/modules/tour/tests/tour_test/tour_test.links.action.yml b/core/modules/tour/tests/tour_test/tour_test.links.action.yml
deleted file mode 100644
index db52cb5806..0000000000
--- a/core/modules/tour/tests/tour_test/tour_test.links.action.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-tour_test_action:
-  route_name: tour_test.1_action
-  title: 'Tour test action'
-  appears_on:
-    - tour_test.1
diff --git a/core/modules/tour/tests/tour_test/tour_test.module b/core/modules/tour/tests/tour_test/tour_test.module
deleted file mode 100644
index a299ec88b8..0000000000
--- a/core/modules/tour/tests/tour_test/tour_test.module
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-/**
- * @file
- * Provides tests for tour module.
- */
-
-use Drupal\Core\Entity\EntityInterface;
-
-/**
- * Implements hook_ENTITY_TYPE_load() for tour.
- */
-function tour_test_tour_load($entities) {
-  if (isset($entities['tour-entity-create-test-en'])) {
-    $entities['tour-entity-create-test-en']->loaded = 'Load hooks work';
-  }
-}
-
-/**
- * Implements hook_ENTITY_TYPE_presave() for tour.
- */
-function tour_test_tour_presave($entity) {
-  if ($entity->id() == 'tour-entity-create-test-en') {
-    $entity->set('label', $entity->label() . ' alter');
-  }
-}
-
-/**
- * Implements hook_tour_tips_alter().
- */
-function tour_test_tour_tips_alter(array &$tour_tips, EntityInterface $entity) {
-  foreach ($tour_tips as $tour_tip) {
-    if ($tour_tip->get('id') == 'tour-code-test-1') {
-      $tour_tip->set('body', 'Altered by hook_tour_tips_alter');
-    }
-  }
-}
diff --git a/core/modules/tour/tests/tour_test/tour_test.routing.yml b/core/modules/tour/tests/tour_test/tour_test.routing.yml
deleted file mode 100644
index 86ffeacb56..0000000000
--- a/core/modules/tour/tests/tour_test/tour_test.routing.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-tour_test.1:
-  path: '/tour-test-1'
-  defaults:
-    _controller: '\Drupal\tour_test\Controller\TourTestController::tourTest1'
-  options:
-    _admin_route: TRUE
-  requirements:
-    _access: 'TRUE'
-
-tour_test.1_action:
-  path: '/tour-test-1/action'
-  defaults:
-    _controller: '\Drupal\tour_test\Controller\TourTestController::tourTest1'
-  requirements:
-    _access: 'TRUE'
-
-tour_test.2:
-  path: '/tour-test-2/subpath'
-  defaults:
-    _controller: '\Drupal\tour_test\Controller\TourTestController::tourTest2'
-  requirements:
-    _access: 'TRUE'
-
-tour_test.3:
-  path: '/tour-test-3/{locale}'
-  defaults:
-    locale: 'foo'
-    _controller: '\Drupal\tour_test\Controller\TourTestController::tourTest1'
-  requirements:
-    _access: 'TRUE'
diff --git a/core/modules/tour/tour.api.php b/core/modules/tour/tour.api.php
deleted file mode 100644
index ee425afd4b..0000000000
--- a/core/modules/tour/tour.api.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
- * @file
- * Describes API functions for tour module.
- */
-
-/**
- * @addtogroup hooks
- * @{
- */
-
-/**
- * Allow modules to alter tour items before render.
- *
- * @param array $tour_tips
- *   Array of \Drupal\tour\TipPluginInterface items.
- * @param \Drupal\Core\Entity\EntityInterface $entity
- *   The tour which contains the $tour_tips.
- */
-function hook_tour_tips_alter(array &$tour_tips, \Drupal\Core\Entity\EntityInterface $entity) {
-  foreach ($tour_tips as $tour_tip) {
-    if ($tour_tip->get('id') == 'tour-code-test-1') {
-      $tour_tip->set('body', 'Altered by hook_tour_tips_alter');
-    }
-  }
-}
-
-/**
- * Allow modules to alter tip plugin definitions.
- *
- * @param array $info
- *   The array of tip plugin definitions, keyed by plugin ID.
- *
- * @see \Drupal\tour\Annotation\Tip
- */
-function hook_tour_tips_info_alter(&$info) {
-  // Swap out the class used for this tip plugin.
-  if (isset($info['text'])) {
-    $info['class'] = 'Drupal\mymodule\Plugin\tour\tip\MyCustomTipPlugin';
-  }
-}
-
-/**
- * @} End of "addtogroup hooks".
- */
diff --git a/core/modules/tour/tour.info.yml b/core/modules/tour/tour.info.yml
deleted file mode 100644
index 29d4287151..0000000000
--- a/core/modules/tour/tour.info.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-name: Tour
-type: module
-description: 'Displays guided tours of the site interface.'
-package: Core
-version: VERSION
diff --git a/core/modules/tour/tour.libraries.yml b/core/modules/tour/tour.libraries.yml
deleted file mode 100644
index 52cbc50573..0000000000
--- a/core/modules/tour/tour.libraries.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-tour:
-  version: VERSION
-  js:
-    js/tour.js: {}
-  dependencies:
-    - core/jquery
-    - core/once
-    - core/drupal
-    # @todo Remove this in https://www.drupal.org/project/drupal/issues/3204011
-    - core/internal.backbone
-    - core/internal.shepherd
-    - tour/tour-styling
-
-tour-styling:
-  version: VERSION
-  css:
-    component:
-      css/tour.module.css: { media: screen }
diff --git a/core/modules/tour/tour.module b/core/modules/tour/tour.module
deleted file mode 100644
index 3d9432654b..0000000000
--- a/core/modules/tour/tour.module
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-
-/**
- * @file
- * Main functions of the module.
- */
-
-use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\tour\Entity\Tour;
-
-/**
- * Implements hook_help().
- */
-function tour_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.tour':
-      $output = '';
-      $output .= '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t("The Tour module provides users with guided tours of the site interface. Each tour consists of several tips that highlight elements of the user interface, guide the user through a workflow, or explain key concepts of the website. For more information, see the <a href=':tour'>online documentation for the Tour module</a>.", [':tour' => 'https://www.drupal.org/documentation/modules/tour']) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<dl>';
-      $output .= '<dt>' . t('Viewing tours') . '</dt>';
-      $output .= '<dd>' . t("If a tour is available on a page, a <em>Tour</em> button will be visible in the toolbar. If you click this button the first tip of the tour will appear. The tour continues after clicking the <em>Next</em> button in the tip. To see a tour users must have the permission <em>Access tour</em> and JavaScript must be enabled in the browser") . '</dd>';
-      $output .= '<dt>' . t('Creating tours') . '</dt>';
-      $output .= '<dd>' . t("Tours can be written as YAML-documents with a text editor, or using the contributed <a href=':tour_ui'>Tour UI</a> module. For more information, see <a href=':doc_url'>the online documentation for writing tours</a>.", [':doc_url' => 'https://www.drupal.org/developing/api/tour', ':tour_ui' => 'https://www.drupal.org/project/tour_ui']) . '</dd>';
-      $output .= '</dl>';
-      return $output;
-  }
-}
-
-/**
- * Implements hook_toolbar().
- */
-function tour_toolbar() {
-  $items = [];
-  $items['tour'] = [
-    '#cache' => [
-      'contexts' => [
-        'user.permissions',
-      ],
-    ],
-  ];
-
-  if (!\Drupal::currentUser()->hasPermission('access tour')) {
-    return $items;
-  }
-
-  $items['tour'] += [
-    '#type' => 'toolbar_item',
-    'tab' => [
-      '#type' => 'html_tag',
-      '#tag' => 'button',
-      '#value' => t('Tour'),
-      '#attributes' => [
-        'class' => ['toolbar-icon', 'toolbar-icon-help'],
-        'aria-pressed' => 'false',
-        'type' => 'button',
-      ],
-    ],
-    '#wrapper_attributes' => [
-      'class' => ['tour-toolbar-tab', 'hidden'],
-      'id' => 'toolbar-tab-tour',
-    ],
-    '#attached' => [
-      'library' => [
-        'tour/tour',
-      ],
-    ],
-  ];
-
-  return $items;
-}
-
-/**
- * Implements hook_page_bottom().
- */
-function tour_page_bottom(array &$page_bottom) {
-  if (!\Drupal::currentUser()->hasPermission('access tour')) {
-    return;
-  }
-
-  // Load all of the items and match on route name.
-  $route_match = \Drupal::routeMatch();
-  $route_name = $route_match->getRouteName();
-
-  $results = \Drupal::entityQuery('tour')
-    ->condition('routes.*.route_name', $route_name)
-    ->condition('status', TRUE)
-    ->execute();
-  if (!empty($results) && $tours = Tour::loadMultiple(array_keys($results))) {
-    foreach ($tours as $id => $tour) {
-      // Match on params.
-      if (!$tour->hasMatchingRoute($route_name, $route_match->getRawParameters()->all())) {
-        unset($tours[$id]);
-      }
-    }
-    if (!empty($tours)) {
-      $page_bottom['tour'] = \Drupal::entityTypeManager()
-        ->getViewBuilder('tour')
-        ->viewMultiple($tours, 'full');
-    }
-  }
-}
-
-/**
- * Implements hook_ENTITY_TYPE_insert() for tour entities.
- */
-function tour_tour_insert($entity) {
-  \Drupal::service('plugin.manager.tour.tip')->clearCachedDefinitions();
-}
-
-/**
- * Implements hook_ENTITY_TYPE_update() for tour entities.
- */
-function tour_tour_update($entity) {
-  \Drupal::service('plugin.manager.tour.tip')->clearCachedDefinitions();
-}
diff --git a/core/modules/tour/tour.permissions.yml b/core/modules/tour/tour.permissions.yml
deleted file mode 100644
index d5a4ebcc95..0000000000
--- a/core/modules/tour/tour.permissions.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-access tour:
-  title: 'Access tours'
diff --git a/core/modules/tour/tour.services.yml b/core/modules/tour/tour.services.yml
deleted file mode 100644
index 38f310e997..0000000000
--- a/core/modules/tour/tour.services.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-services:
-  plugin.manager.tour.tip:
-    class: Drupal\tour\TipPluginManager
-    parent: default_plugin_manager
