diff --git a/config/install/webform.webform.contact.yml b/config/install/webform.webform.contact.yml
index fd21d1e0..50d07955 100644
--- a/config/install/webform.webform.contact.yml
+++ b/config/install/webform.webform.contact.yml
@@ -40,6 +40,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/config/schema/webform.schema.yml b/config/schema/webform.schema.yml
index bfd6d828..397fe3ce 100644
--- a/config/schema/webform.schema.yml
+++ b/config/schema/webform.schema.yml
@@ -372,6 +372,9 @@ webform.webform.*:
       type: mapping
       label: 'Settings'
       mapping:
+        ajax:
+          type: boolean
+          label: 'Use Ajax'
         page:
           type: boolean
           label: 'Enable page'
diff --git a/includes/webform.theme.inc b/includes/webform.theme.inc
index 7ebef4e5..71dd2f2a 100644
--- a/includes/webform.theme.inc
+++ b/includes/webform.theme.inc
@@ -165,9 +165,19 @@ function template_preprocess_webform_confirmation(array &$variables) {
   $variables['back_label'] = $settings['confirmation_back_label'] ?: \Drupal::config('webform.settings')->get('settings.default_confirmation_back_label');
   $variables['back_attributes'] = new Attribute($settings['confirmation_back_attributes']);
 
-  // Apply all passed query string parameters to the 'Back to form' link.
+  // Get query string parameters.
   $query = \Drupal::request()->query->all();
-  unset($query['webform_id']);
+
+  // Add Ajax trigger to back link.
+  // @see \Drupal\webform\WebformSubmissionForm::getCustomForm
+  // @see Drupal.behaviors.webformConfirmationBackAjax (js/webform.ajax.js)
+  $is_ajax = (!empty($query['ajax_form'])) ? TRUE : FALSE;
+  if (!empty($is_ajax)) {
+    $variables['back_attributes']->addClass('js-webform-confirmation-back-link-ajax');
+  }
+
+  // Apply all passed query string parameters to the 'Back to form' link.
+  unset($query['webform_id'], $query['ajax_form'], $query['_wrapper_format']);
   $options = ($query) ? ['query' => $query] : [];
 
   // Set back_url.
diff --git a/js/webform.ajax.js b/js/webform.ajax.js
index 9c38f97b..05f2f9a8 100644
--- a/js/webform.ajax.js
+++ b/js/webform.ajax.js
@@ -8,6 +8,40 @@
   'use strict';
 
   /**
+   * Provide Ajax callback for confirmation back to link.
+   *
+   * @type {Drupal~behavior}
+   *
+   * @prop {Drupal~behaviorAttach} attach
+   *   Attaches the behavior to confirmation back to link.
+   */
+
+  Drupal.behaviors.webformConfirmationBackAjax = {
+    attach: function (context) {
+      $('.js-webform-confirmation-back-link-ajax', context)
+        .once('webform-confirmation-back-ajax')
+        .click(function(event) {
+          var $form = $(this).parents('form');
+
+          // Trigger the Ajax call back for the hidden submit button.
+          // @see \Drupal\webform\WebformSubmissionForm::getCustomForm
+          $form.find('.js-webform-confirmation-back-submit-ajax').click();
+
+          // Move the progress indicator from the submit button to after this link.
+          // @todo Figure out a better way to set a progress indicator.
+          var $progress_indicator = $form.find('.ajax-progress');
+          if ($progress_indicator) {
+            $(this).after($progress_indicator);
+          }
+
+          // Cancel the click event.
+          event.preventDefault();
+          event.stopPropagation();
+        });
+    }
+  };
+
+  /**
    * Scroll to top ajax command.
    *
    * @param {Drupal.Ajax} [ajax]
diff --git a/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml b/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml
index 53c11810..cff57ec7 100644
--- a/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml
+++ b/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml
@@ -29,6 +29,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml b/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml
index 5211fd47..45d53c7e 100644
--- a/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml
+++ b/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml
@@ -28,6 +28,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.features.yml b/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.features.yml
index 6578fd5a..f32a5804 100644
--- a/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.features.yml
+++ b/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.features.yml
@@ -1 +1 @@
-{  }
+true
\ No newline at end of file
diff --git a/modules/webform_examples/config/install/webform.webform.example_elements.yml b/modules/webform_examples/config/install/webform.webform.example_elements.yml
index 4de25c47..4d75a441 100644
--- a/modules/webform_examples/config/install/webform.webform.example_elements.yml
+++ b/modules/webform_examples/config/install/webform.webform.example_elements.yml
@@ -524,6 +524,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_examples/config/install/webform.webform.example_elements_composite.yml b/modules/webform_examples/config/install/webform.webform.example_elements_composite.yml
index 40c38e69..71799819 100644
--- a/modules/webform_examples/config/install/webform.webform.example_elements_composite.yml
+++ b/modules/webform_examples/config/install/webform.webform.example_elements_composite.yml
@@ -139,6 +139,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_examples/config/install/webform.webform.example_elements_computed.yml b/modules/webform_examples/config/install/webform.webform.example_elements_computed.yml
index 09c29973..e3006c59 100644
--- a/modules/webform_examples/config/install/webform.webform.example_elements_computed.yml
+++ b/modules/webform_examples/config/install/webform.webform.example_elements_computed.yml
@@ -47,6 +47,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_examples/config/install/webform.webform.example_elements_masks.yml b/modules/webform_examples/config/install/webform.webform.example_elements_masks.yml
index 6503df07..5575a0e4 100644
--- a/modules/webform_examples/config/install/webform.webform.example_elements_masks.yml
+++ b/modules/webform_examples/config/install/webform.webform.example_elements_masks.yml
@@ -78,6 +78,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_examples/config/install/webform.webform.example_elements_states.yml b/modules/webform_examples/config/install/webform.webform.example_elements_states.yml
index 81ad528d..8887c706 100644
--- a/modules/webform_examples/config/install/webform.webform.example_elements_states.yml
+++ b/modules/webform_examples/config/install/webform.webform.example_elements_states.yml
@@ -178,6 +178,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_examples/config/install/webform.webform.example_layout_basic.yml b/modules/webform_examples/config/install/webform.webform.example_layout_basic.yml
index b9e1a2e5..80738de5 100644
--- a/modules/webform_examples/config/install/webform.webform.example_layout_basic.yml
+++ b/modules/webform_examples/config/install/webform.webform.example_layout_basic.yml
@@ -214,6 +214,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_examples/config/install/webform.webform.example_layout_flexbox.yml b/modules/webform_examples/config/install/webform.webform.example_layout_flexbox.yml
index 93b34e53..8244e5f4 100644
--- a/modules/webform_examples/config/install/webform.webform.example_layout_flexbox.yml
+++ b/modules/webform_examples/config/install/webform.webform.example_layout_flexbox.yml
@@ -118,6 +118,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_examples/config/install/webform.webform.example_wizard.yml b/modules/webform_examples/config/install/webform.webform.example_wizard.yml
index a582346a..0618b6c3 100644
--- a/modules/webform_examples/config/install/webform.webform.example_wizard.yml
+++ b/modules/webform_examples/config/install/webform.webform.example_wizard.yml
@@ -56,6 +56,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_scheduled_email/test/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml b/modules/webform_scheduled_email/test/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml
index 4682ec20..81c573c1 100644
--- a/modules/webform_scheduled_email/test/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml
+++ b/modules/webform_scheduled_email/test/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml
@@ -37,6 +37,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_scheduled_email/test/modules/webform_scheduled_email_test/webform_scheduled_email_test.features.yml b/modules/webform_scheduled_email/test/modules/webform_scheduled_email_test/webform_scheduled_email_test.features.yml
index 27ba77dd..f32a5804 100644
--- a/modules/webform_scheduled_email/test/modules/webform_scheduled_email_test/webform_scheduled_email_test.features.yml
+++ b/modules/webform_scheduled_email/test/modules/webform_scheduled_email_test/webform_scheduled_email_test.features.yml
@@ -1 +1 @@
-true
+true
\ No newline at end of file
diff --git a/modules/webform_templates/config/install/webform.webform.template_contact.yml b/modules/webform_templates/config/install/webform.webform.template_contact.yml
index 5e8aa2a5..3e4a4c44 100644
--- a/modules/webform_templates/config/install/webform.webform.template_contact.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_contact.yml
@@ -36,6 +36,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/config/install/webform.webform.template_donation.yml b/modules/webform_templates/config/install/webform.webform.template_donation.yml
index ca975001..7004bb4d 100644
--- a/modules/webform_templates/config/install/webform.webform.template_donation.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_donation.yml
@@ -87,6 +87,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml b/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml
index 33b9dd80..044b784f 100644
--- a/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml
@@ -83,6 +83,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/config/install/webform.webform.template_feedback.yml b/modules/webform_templates/config/install/webform.webform.template_feedback.yml
index c7b4e508..574b7718 100644
--- a/modules/webform_templates/config/install/webform.webform.template_feedback.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_feedback.yml
@@ -41,6 +41,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/config/install/webform.webform.template_issue.yml b/modules/webform_templates/config/install/webform.webform.template_issue.yml
index ad252b03..ed8405de 100644
--- a/modules/webform_templates/config/install/webform.webform.template_issue.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_issue.yml
@@ -124,6 +124,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/config/install/webform.webform.template_job_application.yml b/modules/webform_templates/config/install/webform.webform.template_job_application.yml
index 8d96616f..ade03c2d 100644
--- a/modules/webform_templates/config/install/webform.webform.template_job_application.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_job_application.yml
@@ -84,6 +84,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml b/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml
index fced9290..0ae7e3d3 100644
--- a/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml
@@ -83,6 +83,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/config/install/webform.webform.template_registration.yml b/modules/webform_templates/config/install/webform.webform.template_registration.yml
index 51247108..2ddf61aa 100644
--- a/modules/webform_templates/config/install/webform.webform.template_registration.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_registration.yml
@@ -53,6 +53,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml b/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml
index 23f7d5b0..7a6e1091 100644
--- a/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml
@@ -45,6 +45,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/config/install/webform.webform.template_subscribe.yml b/modules/webform_templates/config/install/webform.webform.template_subscribe.yml
index 9b9e05cf..4a008219 100644
--- a/modules/webform_templates/config/install/webform.webform.template_subscribe.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_subscribe.yml
@@ -32,6 +32,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/config/install/webform.webform.template_user_profile.yml b/modules/webform_templates/config/install/webform.webform.template_user_profile.yml
index 331fc4d1..80961fc2 100644
--- a/modules/webform_templates/config/install/webform.webform.template_user_profile.yml
+++ b/modules/webform_templates/config/install/webform.webform.template_user_profile.yml
@@ -126,6 +126,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/modules/webform_templates/src/WebformTemplatesSubmissionPreviewForm.php b/modules/webform_templates/src/WebformTemplatesSubmissionPreviewForm.php
index f16a79e3..b73aa27c 100644
--- a/modules/webform_templates/src/WebformTemplatesSubmissionPreviewForm.php
+++ b/modules/webform_templates/src/WebformTemplatesSubmissionPreviewForm.php
@@ -20,7 +20,7 @@ class WebformTemplatesSubmissionPreviewForm extends WebformSubmissionForm {
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
     $form = parent::buildForm($form, $form_state);
-    if ($this->isModalDialog()) {
+    if ($this->isDialog()) {
       // Disable validation.
       $form['#attributes']['novalidate'] = 'novalidate';
 
@@ -57,7 +57,7 @@ class WebformTemplatesSubmissionPreviewForm extends WebformSubmissionForm {
    * {@inheritdoc}
    */
   public function validateForm(array &$form, FormStateInterface $form_state) {
-    if ($this->isModalDialog()) {
+    if ($this->isDialog()) {
       $form_state->clearErrors();
     }
     else {
diff --git a/modules/webform_ui/js/webform_ui.js b/modules/webform_ui/js/webform_ui.js
index 5ae6c89a..1ffb8fd8 100644
--- a/modules/webform_ui/js/webform_ui.js
+++ b/modules/webform_ui/js/webform_ui.js
@@ -43,4 +43,22 @@
     }
   };
 
+  /**
+   * Lock the default actions element by moving it to the table footer (<tfoot>).
+   *
+   * @type {Drupal~behavior}
+   *
+   * @prop {Drupal~behaviorAttach} attach
+   *   Attaches the behavior for locking the default actions  element by moving it to the table footer (<tfoot>).
+   */
+  Drupal.behaviors.webformUiElementsActionsDefault = {
+    attach: function (context, settings) {
+      $(context).find('[data-drupal-selector="edit-webform-ui-elements-webform-actions-default"]').once('webform-ui-elements-webform-actions-default').each(function () {
+        var $tr = $(this);
+        var $table = $tr.parents('table');
+        $table.append($('<tfoot></tfoot>').append($tr));
+      });
+    }
+  }
+
 })(jQuery, Drupal, drupalSettings);
diff --git a/modules/webform_ui/src/Form/WebformUiElementDeleteForm.php b/modules/webform_ui/src/Form/WebformUiElementDeleteForm.php
index ca9fa3a4..8156feef 100644
--- a/modules/webform_ui/src/Form/WebformUiElementDeleteForm.php
+++ b/modules/webform_ui/src/Form/WebformUiElementDeleteForm.php
@@ -194,7 +194,7 @@ class WebformUiElementDeleteForm extends ConfirmFormBase {
     $this->webformElement = $element_manager->createInstance($plugin_id, $this->element);
 
     $form = parent::buildForm($form, $form_state);
-    $form = $this->buildConfirmFormDialog($form, $form_state);
+    $form = $this->buildDialogConfirmForm($form, $form_state);
     return $form;
   }
 
@@ -206,14 +206,7 @@ class WebformUiElementDeleteForm extends ConfirmFormBase {
     $this->webform->save();
 
     drupal_set_message($this->t('The webform element %title has been deleted.', ['%title' => $this->getElementTitle()]));
-    $form_state->setRedirectUrl($this->getRedirectUrl());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getRedirectUrl() {
-    return $this->webform->toUrl('edit-form');
+    $form_state->setRedirectUrl($this->webform->toUrl('edit-form'));
   }
 
   /**
diff --git a/modules/webform_ui/src/Form/WebformUiElementEditForm.php b/modules/webform_ui/src/Form/WebformUiElementEditForm.php
index 1e6c6344..4857750f 100644
--- a/modules/webform_ui/src/Form/WebformUiElementEditForm.php
+++ b/modules/webform_ui/src/Form/WebformUiElementEditForm.php
@@ -69,7 +69,7 @@ class WebformUiElementEditForm extends WebformUiElementFormBase {
 
     // WORKAROUND:
     // Create a hidden link that is click using jQuery.
-    if ($this->isModalDialog()) {
+    if ($this->isDialog()) {
       $form['delete'] = [
         '#type' => 'link',
         '#title' => $this->t('Delete'),
diff --git a/modules/webform_ui/src/Form/WebformUiElementFormBase.php b/modules/webform_ui/src/Form/WebformUiElementFormBase.php
index 4a505aca..69b6a21b 100644
--- a/modules/webform_ui/src/Form/WebformUiElementFormBase.php
+++ b/modules/webform_ui/src/Form/WebformUiElementFormBase.php
@@ -264,7 +264,7 @@ abstract class WebformUiElementFormBase extends FormBase implements WebformUiEle
       '#_validate_form' => TRUE,
     ];
 
-    return $this->buildFormDialog($form, $form_state);
+    return $this->buildDialogForm($form, $form_state);
   }
 
   /**
@@ -349,18 +349,9 @@ abstract class WebformUiElementFormBase extends FormBase implements WebformUiEle
     ];
     drupal_set_message($this->t('%title has been @action.', $t_args));
 
-    $form_state->setRedirectUrl($this->getRedirectUrl());
+    $form_state->setRedirectUrl($this->webform->toUrl('edit-form', ['query' => ['element-update' => $this->key]]));
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  protected function getRedirectUrl() {
-    if ($url = $this->getRedirectDestinationUrl()) {
-      return $url;
-    }
-    return $this->webform->toUrl('edit-form', ['query' => ['element-update' => $this->key]]);
-  }
 
   /**
    * Determines if the webform element key already exists.
diff --git a/modules/webform_ui/src/WebformUiEntityForm.php b/modules/webform_ui/src/WebformUiEntityForm.php
index bd538cd0..338b16d8 100644
--- a/modules/webform_ui/src/WebformUiEntityForm.php
+++ b/modules/webform_ui/src/WebformUiEntityForm.php
@@ -271,7 +271,7 @@ class WebformUiEntityForm extends WebformEntityForm {
         'class' => [RESPONSIVE_PRIORITY_MEDIUM, 'webform-ui-element-operations'],
       ];
     }
-    if (!$this->isModalDialog()) {
+    if (!$this->isDialog()) {
       $header['key'] = [
         'data' => $this->t('Key'),
         'class' => [RESPONSIVE_PRIORITY_LOW],
@@ -293,7 +293,7 @@ class WebformUiEntityForm extends WebformEntityForm {
     }
     $header['weight'] = $this->t('Weight');
     $header['parent'] = $this->t('Parent');
-    if (!$this->isModalDialog()) {
+    if (!$this->isDialog()) {
       $header['operations'] = [
         'data' => $this->t('Operations'),
         'class' => ['webform-ui-element-operations'],
@@ -400,7 +400,7 @@ class WebformUiEntityForm extends WebformEntityForm {
         $row['add'] = ['#markup' => ''];
       }
     }
-    if (!$this->isModalDialog()) {
+    if (!$this->isDialog()) {
       $row['name'] = [
         '#markup' => $element['#webform_key'],
       ];
@@ -458,7 +458,7 @@ class WebformUiEntityForm extends WebformEntityForm {
       ],
     ];
 
-    if (!$this->isModalDialog()) {
+    if (!$this->isDialog()) {
       $row['operations'] = [
         '#type' => 'operations',
       ];
@@ -528,7 +528,7 @@ class WebformUiEntityForm extends WebformEntityForm {
     if ($webform->hasContainer()) {
       $row['add'] = ['#markup' => ''];
     }
-    if (!$this->isModalDialog()) {
+    if (!$this->isDialog()) {
       $row['name'] = ['#markup' => 'actions'];
       $row['type'] = [
         '#markup' => $this->t('Submit button(s)'),
@@ -542,7 +542,7 @@ class WebformUiEntityForm extends WebformEntityForm {
     }
     $row['weight'] = ['#markup' => ''];
     $row['parent'] = ['#markup' => ''];
-    if (!$this->isModalDialog()) {
+    if (!$this->isDialog()) {
       $row['operations'] = [
         '#type' => 'operations',
       ];
diff --git a/src/Controller/WebformController.php b/src/Controller/WebformController.php
index 0fe9e2ae..2f6587c8 100644
--- a/src/Controller/WebformController.php
+++ b/src/Controller/WebformController.php
@@ -8,6 +8,7 @@ use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\webform\WebformInterface;
 use Drupal\webform\WebformRequestInterface;
+use Drupal\webform\WebformSubmissionInterface;
 use Drupal\webform\WebformTokenManagerInterface;
 use Symfony\Component\HttpFoundation\JsonResponse;
 use Symfony\Component\HttpFoundation\Request;
@@ -121,11 +122,13 @@ class WebformController extends ControllerBase implements ContainerInjectionInte
    *   The current request.
    * @param \Drupal\webform\WebformInterface|null $webform
    *   A webform.
+   * @param \Drupal\webform\WebformSubmissionInterface|null $webform_submission
+   *   A webform submission.
    *
    * @return array
    *   A render array representing a webform confirmation page
    */
-  public function confirmation(Request $request, WebformInterface $webform = NULL) {
+  public function confirmation(Request $request, WebformInterface $webform = NULL, WebformSubmissionInterface $webform_submission = NULL) {
     /** @var \Drupal\Core\Entity\EntityInterface $source_entity */
     if (!$webform) {
       list($webform, $source_entity) = $this->requestHandler->getWebformEntities();
@@ -134,9 +137,6 @@ class WebformController extends ControllerBase implements ContainerInjectionInte
       $source_entity = $this->requestHandler->getCurrentSourceEntity('webform');
     }
 
-    /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
-    $webform_submission = NULL;
-
     if ($token = $request->get('token')) {
       /** @var \Drupal\webform\WebformSubmissionStorageInterface $webform_submission_storage */
       $webform_submission_storage = $this->entityTypeManager()->getStorage('webform_submission');
@@ -160,6 +160,7 @@ class WebformController extends ControllerBase implements ContainerInjectionInte
     ];
 
     $this->renderer->addCacheableDependency($build, $webform);
+
     return $build;
   }
 
diff --git a/src/Entity/Webform.php b/src/Entity/Webform.php
index c3dbd1ab..1b177e17 100644
--- a/src/Entity/Webform.php
+++ b/src/Entity/Webform.php
@@ -689,6 +689,7 @@ class Webform extends ConfigEntityBundleBase implements WebformInterface {
    */
   public static function getDefaultSettings() {
     return [
+      'ajax' => FALSE,
       'page' => TRUE,
       'page_submit_path' => '',
       'page_confirm_path' => '',
diff --git a/src/Form/WebformAjaxFormTrait.php b/src/Form/WebformAjaxFormTrait.php
new file mode 100644
index 00000000..9df30a36
--- /dev/null
+++ b/src/Form/WebformAjaxFormTrait.php
@@ -0,0 +1,202 @@
+<?php
+
+namespace Drupal\webform\Form;
+
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\HtmlCommand;
+use Drupal\Core\Ajax\RedirectCommand;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
+use Drupal\Core\Url;
+use Drupal\webform\Ajax\ScrollTopCommand;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+
+/**
+ * Trait class for Webform Ajax support.
+ */
+trait WebformAjaxFormTrait {
+
+  /**
+   * Returns if webform is using Ajax.
+   *
+   * @return bool
+   *   TRUE if webform is using Ajax.
+   */
+  abstract protected function isAjax();
+
+  /**
+   * Cancel form #ajax callback.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @return \Drupal\Core\Ajax\AjaxResponse
+   *   An Ajax response that display validation error messages or redirects
+   *   to a URL
+   */
+  abstract public function cancelAjaxForm(array &$form, FormStateInterface $form_state);
+
+  /**
+   * Get the form's Ajax wrapper id.
+   * @return string
+   */
+  protected function getWrapperId() {
+    return $this->getFormId() . '-ajax';
+  }
+
+  /**
+   * Add Ajax support to a form.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   * @param array $setting
+   *   Ajax settings.
+   *
+   * @return array
+   *   The form with Ajax callbacks.
+   */
+  protected function buildAjaxForm(array &$form, FormStateInterface $form_state, array $settings = []) {
+    if (!$this->isAjax()) {
+      return $form;
+    }
+
+    // Apply default settings.
+    $settings += [
+      'disable-refocus' => TRUE,
+      'effect' => 'fade',
+      'speed' => 1000,
+      'progress' => [
+        'type' => 'throbber',
+        'message' => '',
+      ],
+    ];
+
+    // Make sure the form has (submit) actions.
+    if (!isset($form['actions'])) {
+      return $form;
+    }
+
+    // Add Ajax callback to all submit buttons.
+    foreach (Element::children($form['actions']) as $key) {
+      $is_submit_button = (isset($form['actions'][$key]['#type']) && $form['actions'][$key]['#type'] == 'submit');
+      if ($is_submit_button) {
+        $form['actions'][$key]['#ajax'] = [
+          'callback' => '::submitAjaxForm',
+          'event' => 'click',
+        ] + $settings;
+      }
+    }
+
+    // Add Ajax wrapper around the form.
+    $form['#form_wrapper_id'] = $this->getWrapperId();
+    $form['#prefix'] = '<div id="' . $this->getWrapperId() . '">';
+    $form['#suffix'] = '</div>';
+
+    // Add Ajax library which contains 'Scroll to top' Ajax command and
+    // Ajax callback for confirmation back to link.
+    $form['#attached']['library'][] = 'webform/webform.ajax';
+
+    return $form;
+  }
+
+  /**
+   * Submit form #ajax callback.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @return \Drupal\Core\Ajax\AjaxResponse
+   *   An Ajax response that display validation error messages or redirects
+   *   to a URL
+   */
+  public function submitAjaxForm(array &$form, FormStateInterface $form_state) {
+    if ($form_state->hasAnyErrors()) {
+      // Display validation errors.
+      return $this->replaceForm($form);
+    }
+    elseif ($form_state->isRebuilding()) {
+      // Rebuild form.
+      return $this->replaceForm($form);
+    }
+    elseif ($redirect_url = $this->getFormStateRedirectUrl($form_state)){
+      // Redirect to URL.
+      $response = new AjaxResponse();
+      $response->addCommand(new RedirectCommand($redirect_url));
+      return $response;
+    }
+    else {
+      return $this->cancelAjaxForm($form, $form_state);
+    }
+  }
+
+  /**
+   * Replace form via an Ajax response.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   *
+   * @return \Drupal\Core\Ajax\AjaxResponse
+   *   An Ajax response that replaces a form.
+   */
+  protected function replaceForm(array $form) {
+    // Always diplay messages.
+    $form['status_messages'] = [
+      '#type' => 'status_messages',
+      '#weight' => -1000,
+    ];
+
+    // Remove wrapper.
+    unset($form['#prefix'], $form['#suffix']);
+
+    // Get wrapper id.
+    $wrapper_id  = '#' . $this->getWrapperId();
+
+    $response = new AjaxResponse();
+    $response->addCommand(new HtmlCommand($wrapper_id, $form));
+    $response->addCommand(new ScrollTopCommand($wrapper_id));
+    return $response;
+  }
+
+  /**
+   * Get redirect URL from the form's state.
+   *
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @return bool|\Drupal\Core\GeneratedUrl|string
+   *   The redirect URL or FALSE if the form is not redirecting.
+   */
+  protected function getFormStateRedirectUrl(FormStateInterface $form_state) {
+    // Always check the ?destination which is used by the off-canvas/system tray.
+    if ($this->requestStack->getCurrentRequest()->get('destination')) {
+      return base_path() . $this->getRedirectDestination()->get();
+    }
+
+    // ISSUE:
+    // Can't get the redirect URL from the form state during an AJAX submission.
+    //
+    // WORKAROUND:
+    // Re-enable redirect, grab the URL, and then disable again.
+    $no_redirect = $form_state->isRedirectDisabled();
+    $form_state->disableRedirect(FALSE);
+    $redirect = $form_state->getRedirect() ?: $form_state->getResponse();
+    $form_state->disableRedirect($no_redirect);
+
+    if ($redirect instanceof RedirectResponse) {
+      return $redirect->getTargetUrl();
+    }
+    elseif ($redirect instanceof Url) {
+      return $redirect->setAbsolute()->toString();
+    }
+    else {
+      return FALSE;
+    }
+  }
+  
+}
diff --git a/src/Form/WebformDialogFormTrait.php b/src/Form/WebformDialogFormTrait.php
index 40597935..a01e90a3 100644
--- a/src/Form/WebformDialogFormTrait.php
+++ b/src/Form/WebformDialogFormTrait.php
@@ -13,20 +13,29 @@ use Drupal\webform\Ajax\ScrollTopCommand;
 use Drupal\webform\Utility\WebformDialogHelper;
 
 /**
- * Trait class for dialogs.
+ * Trait class for Webform Ajax dialog support.
  *
  * @todo Issue #2785047: In Outside In mode, messages should appear in the off-canvas tray, not the main page.
  * @see https://www.drupal.org/node/2785047
  */
 trait WebformDialogFormTrait {
 
+  use WebformAjaxFormTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function isAjax() {
+    return $this->isDialog();
+  }
+
   /**
-   * Is the current request for an Ajax modal dialog.
+   * Is the current request for an Ajax modal/dialog.
    *
    * @return bool
-   *   TRUE if the current request is for an Ajax modal dialog.
+   *   TRUE if the current request is for an Ajax modal/dialog.
    */
-  protected function isModalDialog() {
+  protected function isDialog() {
     $wrapper_format = $this->getRequest()
       ->get(MainContentViewSubscriber::WRAPPER_FORMAT);
     return (in_array($wrapper_format, [
@@ -58,23 +67,14 @@ trait WebformDialogFormTrait {
    *   An associative array containing the structure of the form.
    * @param \Drupal\Core\Form\FormStateInterface $form_state
    *   The current state of the form.
+   * @param array $setting
+   *   Ajax settings.
    *
    * @return array
    *   The webform with modal dialog support.
    */
-  protected function buildFormDialog(array &$form, FormStateInterface $form_state) {
-    if (!$this->isModalDialog()) {
-      return $form;
-    }
-
-    $form['actions']['submit']['#ajax'] = [
-      'callback' => '::submitFormDialog',
-      'event' => 'click',
-    ];
-    $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
-    $form['#prefix'] = '<div id="webform-dialog">';
-    $form['#suffix'] = '</div>';
-    return $form;
+  protected function buildDialogForm(array &$form, FormStateInterface $form_state, array $settings = []) {
+    return $this->buildAjaxForm($form, $form_state, $settings);
   }
 
   /**
@@ -88,12 +88,12 @@ trait WebformDialogFormTrait {
    * @return array
    *   The webform with modal dialog support.
    */
-  protected function buildConfirmFormDialog(array &$form, FormStateInterface $form_state) {
-    if (!$this->isModalDialog() || $this->isOffCanvasDialog()) {
+  protected function buildDialogConfirmForm(array &$form, FormStateInterface $form_state) {
+    if (!$this->isDialog() || $this->isOffCanvasDialog()) {
       return $form;
     }
 
-    $this->buildFormDialog($form, $form_state);
+    $this->buildDialogForm($form, $form_state);
 
     // Replace 'Cancel' link button with a close dialog button.
     $form['actions']['cancel'] = [
@@ -103,7 +103,7 @@ trait WebformDialogFormTrait {
       '#limit_validation_errors' => [],
       '#weight' => 100,
       '#ajax' => [
-        'callback' => '::closeDialog',
+        'callback' => '::cancelAjaxForm',
         'event' => 'click',
       ],
     ];
@@ -115,56 +115,9 @@ trait WebformDialogFormTrait {
   /****************************************************************************/
 
   /**
-   * Submit form dialog #ajax callback.
-   *
-   * @param array $form
-   *   An associative array containing the structure of the form.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The current state of the form.
-   *
-   * @return \Drupal\Core\Ajax\AjaxResponse
-   *   An Ajax response that display validation error messages or redirects
-   *   to a URL
+   * {@inheritdoc}
    */
-  public function submitFormDialog(array &$form, FormStateInterface $form_state) {
-    if ($form_state->hasAnyErrors()) {
-      unset($form['#prefix'], $form['#suffix']);
-      $form['status_messages'] = [
-        '#type' => 'status_messages',
-        '#weight' => -1000,
-      ];
-      $response = new AjaxResponse();
-      $response->addCommand(new HtmlCommand('#webform-dialog', $form));
-      $response->addCommand(new ScrollTopCommand('#webform-dialog'));
-      return $response;
-    }
-    else {
-      $response = new AjaxResponse();
-      if ($path = $this->getRedirectDestinationPath()) {
-        $response->addCommand(new RedirectCommand(base_path() . $path));
-      }
-      elseif ($redirect_url = $this->getRedirectUrl()) {
-        $response->addCommand(new RedirectCommand($redirect_url->toString()));
-      }
-      else {
-        $response->addCommand(new CloseDialogCommand());
-      }
-      return $response;
-    }
-  }
-
-  /**
-   * Close dialog #ajax callback.
-   *
-   * @param array $form
-   *   An associative array containing the structure of the form.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The current state of the form.
-   *
-   * @return bool|\Drupal\Core\Ajax\AjaxResponse
-   *   An Ajax response that display validation error messages.
-   */
-  public function closeDialog(array &$form, FormStateInterface $form_state) {
+  public function cancelAjaxForm(array &$form, FormStateInterface $form_state) {
     $response = new AjaxResponse();
     $response->addCommand(new CloseDialogCommand());
     return $response;
@@ -174,49 +127,8 @@ trait WebformDialogFormTrait {
    * Empty submit callback used to only have the submit button to use an #ajax submit callback.
    *
    * This allows modal dialog to using ::submitCallback to validate and submit
-   * the form via one ajax required.
-   */
-  public function noSubmit(array &$form, FormStateInterface $form_state) {
-  }
-
-  /**
-   * Get the form's redirect URL.
-   *
-   * Isolate a form's redirect URL/destination so that it can be used by
-   * ::submitFormDialog or ::submitForm.
-   *
-   * @return \Drupal\Core\Url|NULL
-   *   The redirect URL or NULL if dialog should just be closed.
+   * the form via one ajax request.
    */
-  protected function getRedirectUrl() {
-    return getDestinationUrl();
-  }
-
-  /**
-   * Get the current request's redirect destination URL.
-   *
-   * @return \Drupal\Core\Url|null
-   *   The current request's redirect destination or NULL if no
-   *   destination available.
-   */
-  protected function getRedirectDestinationUrl() {
-    if ($destination = $this->getRedirectDestinationPath()) {
-      return Url::fromUserInput(base_path() . $destination);
-    }
-    return NULL;
-  }
-
-  /**
-   * Get the redirect destination path if specified in request.
-   *
-   * @return string|null
-   *   The redirect path or NULL if it is not specified.
-   */
-  protected function getRedirectDestinationPath() {
-    if ($this->requestStack->getCurrentRequest()->get('destination')) {
-      return $this->getRedirectDestination()->get();
-    }
-    return NULL;
-  }
+  public function noSubmit(array &$form, FormStateInterface $form_state) {}
 
 }
diff --git a/src/Form/WebformHandlerDeleteForm.php b/src/Form/WebformHandlerDeleteForm.php
index abe31a1b..011c476d 100644
--- a/src/Form/WebformHandlerDeleteForm.php
+++ b/src/Form/WebformHandlerDeleteForm.php
@@ -63,7 +63,7 @@ class WebformHandlerDeleteForm extends ConfirmFormBase {
     $this->webformHandler = $this->webform->getHandler($webform_handler);
 
     $form = parent::buildForm($form, $form_state);
-    $this->buildConfirmFormDialog($form, $form_state);
+    $this->buildDialogConfirmForm($form, $form_state);
     return $form;
   }
 
@@ -73,14 +73,7 @@ class WebformHandlerDeleteForm extends ConfirmFormBase {
   public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->webform->deleteWebformHandler($this->webformHandler);
     drupal_set_message($this->t('The webform handler %name has been deleted.', ['%name' => $this->webformHandler->label()]));
-    $form_state->setRedirectUrl($this->getRedirectUrl());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getRedirectUrl() {
-    return $this->webform->toUrl('handlers-form');
+    $form_state->setRedirectUrl($this->webform->toUrl('handlers-form'));
   }
 
 }
diff --git a/src/Form/WebformHandlerFormBase.php b/src/Form/WebformHandlerFormBase.php
index 79ff9b5d..28cb9b5b 100644
--- a/src/Form/WebformHandlerFormBase.php
+++ b/src/Form/WebformHandlerFormBase.php
@@ -158,7 +158,7 @@ abstract class WebformHandlerFormBase extends FormBase {
       '#button_type' => 'primary',
     ];
 
-    return $this->buildFormDialog($form, $form_state);
+    return $this->buildDialogForm($form, $form_state);
   }
 
   /**
@@ -205,14 +205,7 @@ abstract class WebformHandlerFormBase extends FormBase {
       drupal_set_message($this->t('The webform handler was successfully updated.'));
     }
 
-    $form_state->setRedirectUrl($this->getRedirectUrl());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getRedirectUrl() {
-    return $this->webform->toUrl('handlers-form');
+    $form_state->setRedirectUrl($this->webform->toUrl('handlers-form'));
   }
 
   /**
diff --git a/src/Tests/WebformConfirmationTest.php b/src/Tests/WebformConfirmationTest.php
index 9851dd24..b93fddf8 100644
--- a/src/Tests/WebformConfirmationTest.php
+++ b/src/Tests/WebformConfirmationTest.php
@@ -52,13 +52,13 @@ class WebformConfirmationTest extends WebformTestBase {
 
     // Check confirmation inline.
     $this->drupalPostForm('webform/test_confirmation_inline', [], t('Submit'));
-    $this->assertRaw('<a href="' . $webform_confirmation_inline->toUrl()->toString() . '" rel="back" title="Back to form">Back to form</a>');
-    $this->assertUrl('webform/test_confirmation_inline', ['query' => ['webform_id' => $webform_confirmation_inline->id()]]);
+    $this->assertRaw('<a href="' . $webform_confirmation_inline->toUrl('canonical', ['absolute' => TRUE])->toString() . '" rel="back" title="Back to form">Back to form</a>');
+    $this->assertUrl('webform/test_confirmation_inline');
 
     // Check confirmation inline with custom query parameters.
     $this->drupalPostForm('webform/test_confirmation_inline', [], t('Submit'), ['query' => ['custom' => 'param']]);
-    $this->assertRaw('<a href="' . $webform_confirmation_inline->toUrl()->toString() . '?custom=param" rel="back" title="Back to form">Back to form</a>');
-    $this->assertUrl('webform/test_confirmation_inline', ['query' => ['custom' => 'param', 'webform_id' => $webform_confirmation_inline->id()]]);
+    $this->assertRaw('<a href="' . $webform_confirmation_inline->toUrl('canonical', ['absolute' => TRUE, 'query' => ['custom' => 'param']])->toString() . '" rel="back" title="Back to form">Back to form</a>');
+    $this->assertUrl('webform/test_confirmation_inline', ['query' => ['custom' => 'param']]);
 
     /* Test confirmation page (confirmation_type=page) */
 
diff --git a/src/Tests/WebformTestBase.php b/src/Tests/WebformTestBase.php
index cc7ab6ad..af057020 100644
--- a/src/Tests/WebformTestBase.php
+++ b/src/Tests/WebformTestBase.php
@@ -23,6 +23,8 @@ use Drupal\webform\Entity\WebformSubmission;
  */
 abstract class WebformTestBase extends WebTestBase {
 
+  use WebformTestTrait;
+
   /**
    * Modules to enable.
    *
@@ -309,65 +311,6 @@ abstract class WebformTestBase extends WebTestBase {
   /****************************************************************************/
 
   /**
-   * Lazy load a test webforms.
-   *
-   * @param array $ids
-   *   Webform ids.
-   */
-  protected function loadWebforms(array $ids) {
-    foreach ($ids as $id) {
-      $this->loadWebform($id);
-    }
-    $this->pass(new FormattableMarkup('Loaded webforms: %webforms.', [
-      '%webforms' => implode(', ', $ids),
-    ]));
-
-  }
-
-  /**
-   * Lazy load a test webform.
-   *
-   * @param string $id
-   *   Webform id.
-   *
-   * @return \Drupal\webform\WebformInterface|null
-   *   A webform.
-   *
-   * @see \Drupal\views\Tests\ViewTestData::createTestViews
-   */
-  protected function loadWebform($id) {
-    $storage = \Drupal::entityTypeManager()->getStorage('webform');
-    if ($webform = $storage->load($id)) {
-      return $webform;
-    }
-    else {
-      $config_name = 'webform.webform.' . $id;
-      if (strpos($id, 'test_') === 0) {
-        $config_directory = drupal_get_path('module', 'webform') . '/tests/modules/webform_test/config/install';
-      }
-      elseif (strpos($id, 'example_') === 0) {
-        $config_directory = drupal_get_path('module', 'webform') . '/modules/webform_examples/config/install';
-      }
-      elseif (strpos($id, 'template_') === 0) {
-        $config_directory = drupal_get_path('module', 'webform') . '/modules/webform_templates/config/install';
-      }
-      else {
-        throw new \Exception("Webform $id not valid");
-      }
-
-      if (!file_exists("$config_directory/$config_name.yml")) {
-        throw new \Exception("Webform $id does not exist in $config_directory");
-      }
-
-      $file_storage = new FileStorage($config_directory);
-      $values = $file_storage->read($config_name);
-      $webform = $storage->create($values);
-      $webform->save();
-      return $webform;
-    }
-  }
-
-  /**
    * Create a webform.
    *
    * @param array|null $elements
@@ -474,29 +417,6 @@ abstract class WebformTestBase extends WebTestBase {
   /****************************************************************************/
 
   /**
-   * Load the specified webform submission from the storage.
-   *
-   * @param int $sid
-   *   The submission identifier.
-   *
-   * @return \Drupal\webform\WebformSubmissionInterface
-   *   The loaded webform submission.
-   */
-  protected function loadSubmission($sid) {
-    /** @var \Drupal\webform\WebformSubmissionStorage $storage */
-    $storage = $this->container->get('entity_type.manager')->getStorage('webform_submission');
-    $storage->resetCache([$sid]);
-    return $storage->load($sid);
-  }
-
-  /**
-   * Purge all submission before the webform.module is uninstalled.
-   */
-  protected function purgeSubmissions() {
-    \Drupal::database()->query('DELETE FROM {webform_submission}');
-  }
-
-  /**
    * Post a new submission to a webform.
    *
    * @param \Drupal\webform\WebformInterface $webform
@@ -534,51 +454,6 @@ abstract class WebformTestBase extends WebTestBase {
     return $this->getLastSubmissionId($webform);
   }
 
-  /**
-   * Get a webform's submit button label.
-   *
-   * @param \Drupal\webform\WebformInterface $webform
-   *   A webform.
-   * @param string $submit
-   *   Value of the submit button whose click is to be emulated.
-   *
-   * @return \Drupal\Core\StringTranslation\TranslatableMarkup|string
-   *   The webform's submit button label.
-   */
-  protected function getWebformSubmitButtonLabel(WebformInterface $webform, $submit = NULL) {
-    if ($submit) {
-      return $submit;
-    }
-
-    $actions_element = $webform->getElement('actions');
-    if ($actions_element && isset($actions_element['#submit__label'])) {
-      return $actions_element['#submit__label'];
-    }
-
-    return t('Submit');
-  }
-
-  /**
-   * Get the last submission id.
-   *
-   * @return int
-   *   The last submission id.
-   */
-  protected function getLastSubmissionId($webform) {
-    // Get submission sid.
-    $url = UrlHelper::parse($this->getUrl());
-    if (isset($url['query']['sid'])) {
-      return $url['query']['sid'];
-    }
-    else {
-      $entity_ids = \Drupal::entityQuery('webform_submission')
-        ->sort('sid', 'DESC')
-        ->condition('webform_id', $webform->id())
-        ->execute();
-      return reset($entity_ids);
-    }
-  }
-
   /****************************************************************************/
   // Log.
   /****************************************************************************/
diff --git a/src/Tests/WebformTestTrait.php b/src/Tests/WebformTestTrait.php
new file mode 100644
index 00000000..bef62711
--- /dev/null
+++ b/src/Tests/WebformTestTrait.php
@@ -0,0 +1,164 @@
+<?php
+
+namespace Drupal\webform\Tests;
+
+use Drupal\Component\Render\FormattableMarkup;
+use Drupal\Component\Utility\UrlHelper;
+use Drupal\Core\Config\FileStorage;
+use Drupal\Core\Serialization\Yaml;
+use Drupal\webform\WebformInterface;
+use Drupal\webform\Entity\Webform;
+
+/**
+ * Trait class for Webform tests.
+ *
+ * Below are helper methods are shared by SimpleTest and PHPUnit.
+ *
+ * @see \Drupal\webform\Tests\WebformTestBase
+ * @see \Drupal\Tests\webform\FunctionalJavascript\WebformJavaScriptTestBase
+ */
+trait WebformTestTrait {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+    $this->loadWebforms(static::$testWebforms);
+  }
+
+  /****************************************************************************/
+  // Webform.
+  /****************************************************************************/
+
+  /**
+   * Lazy load a test webforms.
+   *
+   * @param array $ids
+   *   Webform ids.
+   */
+  protected function loadWebforms(array $ids) {
+    foreach ($ids as $id) {
+      $this->loadWebform($id);
+    }
+    $this->pass(new FormattableMarkup('Loaded webforms: %webforms.', [
+      '%webforms' => implode(', ', $ids),
+    ]));
+  }
+
+  /**
+   * Lazy load a test webform.
+   *
+   * @param string $id
+   *   Webform id.
+   *
+   * @return \Drupal\webform\WebformInterface|null
+   *   A webform.
+   *
+   * @see \Drupal\views\Tests\ViewTestData::createTestViews
+   */
+  protected function loadWebform($id) {
+    $storage = \Drupal::entityTypeManager()->getStorage('webform');
+    if ($webform = $storage->load($id)) {
+      return $webform;
+    }
+    else {
+      $config_name = 'webform.webform.' . $id;
+      if (strpos($id, 'test_') === 0) {
+        $config_directory = drupal_get_path('module', 'webform') . '/tests/modules/webform_test/config/install';
+      }
+      elseif (strpos($id, 'example_') === 0) {
+        $config_directory = drupal_get_path('module', 'webform') . '/modules/webform_examples/config/install';
+      }
+      elseif (strpos($id, 'template_') === 0) {
+        $config_directory = drupal_get_path('module', 'webform') . '/modules/webform_templates/config/install';
+      }
+      else {
+        throw new \Exception("Webform $id not valid");
+      }
+
+      if (!file_exists("$config_directory/$config_name.yml")) {
+        throw new \Exception("Webform $id does not exist in $config_directory");
+      }
+
+      $file_storage = new FileStorage($config_directory);
+      $values = $file_storage->read($config_name);
+      $webform = $storage->create($values);
+      $webform->save();
+      return $webform;
+    }
+  }
+
+  /****************************************************************************/
+  // Submission.
+  /****************************************************************************/
+
+  /**
+   * Load the specified webform submission from the storage.
+   *
+   * @param int $sid
+   *   The submission identifier.
+   *
+   * @return \Drupal\webform\WebformSubmissionInterface
+   *   The loaded webform submission.
+   */
+  protected function loadSubmission($sid) {
+    /** @var \Drupal\webform\WebformSubmissionStorage $storage */
+    $storage = $this->container->get('entity_type.manager')->getStorage('webform_submission');
+    $storage->resetCache([$sid]);
+    return $storage->load($sid);
+  }
+
+  /**
+   * Purge all submission before the webform.module is uninstalled.
+   */
+  protected function purgeSubmissions() {
+    \Drupal::database()->query('DELETE FROM {webform_submission}');
+  }
+
+  /**
+   * Get a webform's submit button label.
+   *
+   * @param \Drupal\webform\WebformInterface $webform
+   *   A webform.
+   * @param string $submit
+   *   Value of the submit button whose click is to be emulated.
+   *
+   * @return \Drupal\Core\StringTranslation\TranslatableMarkup|string
+   *   The webform's submit button label.
+   */
+  protected function getWebformSubmitButtonLabel(WebformInterface $webform, $submit = NULL) {
+    if ($submit) {
+      return $submit;
+    }
+
+    $actions_element = $webform->getElement('actions');
+    if ($actions_element && isset($actions_element['#submit__label'])) {
+      return $actions_element['#submit__label'];
+    }
+
+    return t('Submit');
+  }
+
+  /**
+   * Get the last submission id.
+   *
+   * @return int
+   *   The last submission id.
+   */
+  protected function getLastSubmissionId($webform) {
+    // Get submission sid.
+    $url = UrlHelper::parse($this->getUrl());
+    if (isset($url['query']['sid'])) {
+      return $url['query']['sid'];
+    }
+    else {
+      $entity_ids = \Drupal::entityQuery('webform_submission')
+        ->sort('sid', 'DESC')
+        ->condition('webform_id', $webform->id())
+        ->execute();
+      return reset($entity_ids);
+    }
+  }
+
+}
diff --git a/src/WebformEntityDeleteForm.php b/src/WebformEntityDeleteForm.php
index 06173c93..2214cc89 100644
--- a/src/WebformEntityDeleteForm.php
+++ b/src/WebformEntityDeleteForm.php
@@ -26,7 +26,7 @@ class WebformEntityDeleteForm extends EntityDeleteForm {
       '#weight' => 10,
     ];
 
-    return $this->buildConfirmFormDialog($form, $form_state);
+    return $this->buildDialogConfirmForm($form, $form_state);
   }
 
   /**
diff --git a/src/WebformEntityForm.php b/src/WebformEntityForm.php
index 084a90f4..9266ba8a 100644
--- a/src/WebformEntityForm.php
+++ b/src/WebformEntityForm.php
@@ -118,7 +118,7 @@ class WebformEntityForm extends BundleEntityFormBase {
 
     $form = parent::buildForm($form, $form_state);
 
-    return $this->buildFormDialog($form, $form_state);
+    return $this->buildDialogForm($form, $form_state);
   }
 
   /**
@@ -255,17 +255,7 @@ class WebformEntityForm extends BundleEntityFormBase {
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
     parent::submitForm($form, $form_state);
-    $form_state->setRedirectUrl($this->getRedirectUrl());
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRedirectUrl() {
-    if ($url = $this->getRedirectDestinationUrl()) {
-      return $url;
-    }
-    return Url::fromRoute('entity.webform.edit_form', ['webform' => $this->getEntity()->id()]);
+    $form_state->setRedirectUrl(Url::fromRoute('entity.webform.edit_form', ['webform' => $this->getEntity()->id()]));
   }
 
   /**
diff --git a/src/WebformEntitySettingsForm.php b/src/WebformEntitySettingsForm.php
index 06353988..3a88c559 100644
--- a/src/WebformEntitySettingsForm.php
+++ b/src/WebformEntitySettingsForm.php
@@ -702,6 +702,24 @@ class WebformEntitySettingsForm extends EntityForm {
       '#field_suffix' => $this->t('days'),
     ];
 
+    // Ajax settings.
+    $form['ajax_settings'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Ajax settings'),
+      '#states' => [
+        'visible' => [
+          ':input[name="method"]' => ['value' => ''],
+        ],
+      ],
+    ];
+    $form['ajax_settings']['ajax'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Use Ajax'),
+      '#description' => $this->t('If checked, paging, saving of drafts, previews, submissions, and confirmations will not initiate a page refresh.'),
+      '#return_value' => TRUE,
+      '#default_value' => $settings['ajax'],
+    ];
+
     // Confirmation settings.
     $form['confirmation_settings'] = [
       '#type' => 'details',
@@ -712,6 +730,14 @@ class WebformEntitySettingsForm extends EntityForm {
         ],
       ],
     ];
+    $form['confirmation_settings']['ajax_confirmation'] = [
+      '#type' => 'webform_message',
+      '#message_type' => 'warning',
+      '#message_message' => $this->t("Only 'Inline' and 'Message' confirmation types are fully supported by Ajax."),
+      '#states' => [
+        'visible' => [':input[name="ajax"]' => ['checked' => TRUE]],
+      ],
+    ];
     $form['confirmation_settings']['confirmation_type'] = [
       '#title' => $this->t('Confirmation type'),
       '#type' => 'radios',
diff --git a/src/WebformMessageManager.php b/src/WebformMessageManager.php
index 24126aa3..f074d45b 100644
--- a/src/WebformMessageManager.php
+++ b/src/WebformMessageManager.php
@@ -151,9 +151,7 @@ class WebformMessageManager implements WebformMessageManagerInterface {
    * {@inheritdoc}
    */
   public function display($key, $type = 'status') {
-    $build = $this->build($key);
-    // Do not display message via Ajax request.
-    if ($build && !$this->requestHandler->isAjax()) {
+    if ($build = $this->build($key)) {
       drupal_set_message($this->renderer->renderPlain($build), $type);
       return TRUE;
     }
diff --git a/src/WebformSubmissionForm.php b/src/WebformSubmissionForm.php
index 8557e9a2..409b0c4d 100644
--- a/src/WebformSubmissionForm.php
+++ b/src/WebformSubmissionForm.php
@@ -13,8 +13,8 @@ use Drupal\Core\Render\Element;
 use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Routing\TrustedRedirectResponse;
 use Drupal\Core\Url;
-use Drupal\webform\Controller\WebformController;
 use Drupal\webform\Entity\WebformSubmission;
+use Drupal\webform\Form\WebformAjaxFormTrait;
 use Drupal\webform\Form\WebformDialogFormTrait;
 use Drupal\webform\Plugin\Field\FieldType\WebformEntityReferenceItem;
 use Drupal\webform\Plugin\WebformElementManagerInterface;
@@ -279,6 +279,9 @@ class WebformSubmissionForm extends ContentEntityForm {
     $form_id = $this->getFormId();
     $this->thirdPartySettingsManager->alter('webform_submission_form', $form, $form_state, $form_id);
 
+    // Add Ajax callback to form.
+    $this->buildAjaxForm($form, $form_state);
+
     return $form;
   }
 
@@ -465,11 +468,26 @@ class WebformSubmissionForm extends ContentEntityForm {
       return $form;
     }
 
-    // Display inline confirmation message with back to link which is rendered
-    // via the controller.
-    if ($this->getWebformSetting('confirmation_type') == 'inline' && $this->getRequest()->query->get('webform_id') == $webform->id()) {
-      $webform_controller = new WebformController($this->renderer, $this->requestHandler, $this->tokenManager);
-      $form['confirmation'] = $webform_controller->confirmation($this->getRequest(), $webform);
+    // Display inline confirmation message with back to link.
+    if ($form_state->get('current_page') === 'webform_confirmation') {
+      $form['confirmation'] = [
+        '#theme' => 'webform_confirmation',
+        '#webform' => $webform,
+        '#source_entity' => $webform_submission->getSourceEntity(),
+        '#webform_submission' => $webform_submission,
+      ];
+
+      // Add hidden submit button which is used as the Ajax callback.
+      // @see \Drupal\webform\Form\WebformAjaxFormTrait::buildAjaxForm
+      // @see Drupal.behaviors.webformConfirmationBackAjax (js/webform.ajax.js)
+      $form['actions']['submit'] = [
+        '#type' => 'submit',
+        '#value' => $this->t('Back'),
+        '#attributes' => [
+          'style' => 'display:none',
+          'class' => ['js-webform-confirmation-back-submit-ajax'],
+        ],
+      ];
       return $form;
     }
 
@@ -478,7 +496,7 @@ class WebformSubmissionForm extends ContentEntityForm {
       // If the current user can update any submission just display the closed
       // message and still allow them to create new submissions.
       if ($webform->isTemplate() && $webform->access('duplicate')) {
-        if (!$this->isModalDialog()) {
+        if (!$this->isDialog()) {
           $this->messageManager->display(WebformMessageManagerInterface::TEMPLATE_PREVIEW, 'warning');
         }
       }
@@ -1003,11 +1021,16 @@ class WebformSubmissionForm extends ContentEntityForm {
     $webform_submission = $this->getEntity();
 
     // Make sure the uri and remote addr are set correctly because
-    // Ajax requests via 'managed_file' uploads can cause these values to be
-    // reset.
+    // Ajax requests can cause these values to be reset.
     if ($webform_submission->isNew()) {
-      $webform_submission->set('uri', preg_replace('#^' . base_path() . '#', '/', $this->getRequest()->getRequestUri()));
-      $webform_submission->set('remote_addr', ($this->isConfidential()) ? '' : $this->getRequest()->getClientIp());
+      $uri = preg_replace('#^' . base_path() . '#', '/', $this->getRequest()->getRequestUri());
+      // Remove Ajax query string parameters.
+      $uri = preg_replace('/(ajax_form=1|_wrapper_format=drupal_ajax)(&|$)/', '', $uri);
+      // Remove empty query string.
+      $uri = preg_replace('/\?$/', '', $uri);
+      $remote_addr = ($this->isConfidential()) ? '' : $this->getRequest()->getClientIp();
+      $webform_submission->set('uri', $uri);
+      $webform_submission->set('remote_addr', $remote_addr);
     }
 
     // Block users from submitting templates that they can't update.
@@ -1267,7 +1290,12 @@ class WebformSubmissionForm extends ContentEntityForm {
     $route_name = $this->getRouteMatch()->getRouteName();
     $route_parameters = $this->getRouteMatch()->getRawParameters()->all();
     $route_options = [];
-    if ($query = $this->getRequest()->query->all()) {
+
+    // Add current query to route options.
+    $query = $this->getRequest()->query->all();
+    // Remove Ajax parameters from query.
+    unset($query['ajax_form'], $query['_wrapper_format']);
+    if ($query) {
       $route_options['query'] = $query;
     }
 
@@ -1315,23 +1343,22 @@ class WebformSubmissionForm extends ContentEntityForm {
         // If confirmation URL is invalid display message.
         $this->messageManager->display(WebformMessageManagerInterface::SUBMISSION_CONFIRMATION);
         $route_options['query']['webform_id'] = $webform->id();
-        break;
+        $form_state->setRedirect($route_name, $route_parameters, $route_options);
+        return;
 
       case 'inline':
-        $route_options['query']['webform_id'] = $webform->id();
-        break;
+        $form_state->set('current_page', 'webform_confirmation');
+        $form_state->setRebuild();
+        return;
 
       case 'message':
       default:
-        // Unset token if we are just reloading the current webform.
-        unset($route_options['query']['token']);
         if (!$this->messageManager->display(WebformMessageManagerInterface::SUBMISSION_CONFIRMATION)) {
           $this->messageManager->display(WebformMessageManagerInterface::SUBMISSION_DEFAULT_CONFIRMATION);
         }
-        break;
+        return;
     }
 
-    $form_state->setRedirect($route_name, $route_parameters, $route_options);
   }
 
   /****************************************************************************/
@@ -1573,7 +1600,7 @@ class WebformSubmissionForm extends ContentEntityForm {
    * Returns the webform confidential indicator.
    *
    * @return bool
-   *   TRUE if the webform is confidential .
+   *   TRUE if the webform is confidential.
    */
   protected function isConfidential() {
     return $this->getWebformSetting('form_confidential', FALSE);
@@ -1707,6 +1734,43 @@ class WebformSubmissionForm extends ContentEntityForm {
   }
 
   /****************************************************************************/
+  // Ajax functions.
+  // @see \Drupal\webform\Form\WebformAjaxFormTrait
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function isAjax() {
+    return $this->getWebformSetting('ajax', FALSE);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function cancelAjaxForm(array &$form, FormStateInterface $form_state) {
+    // Get form object.
+    $form_object = $this->entityManager->getFormObject('webform_submission', 'default');
+
+    // Set form entity.
+    $webform_submission = $this->storage->create(['webform_id' => $this->getWebform()->id()]);
+    $form_object->setEntity($webform_submission);
+
+    // Set form state.
+    $form_state = new FormState();
+    $form_state->setFormState([]);
+    $form_state->setUserInput([]);
+
+    // Build form.
+    /** @var \Drupal\Core\Form\FormBuilderInterface $form_builder */
+    $form_builder = \Drupal::service('form_builder');
+    $form = $form_builder->buildForm($form_object, $form_state);
+
+    // Return replace form as response.
+    return $this->replaceForm($form);
+  }
+
+  /****************************************************************************/
   // API helper functions.
   /****************************************************************************/
 
diff --git a/src/WebformSubmissionNotesForm.php b/src/WebformSubmissionNotesForm.php
index b6923dad..59c06823 100644
--- a/src/WebformSubmissionNotesForm.php
+++ b/src/WebformSubmissionNotesForm.php
@@ -54,13 +54,13 @@ class WebformSubmissionNotesForm extends ContentEntityForm {
     $form['navigation'] = [
       '#theme' => 'webform_submission_navigation',
       '#webform_submission' => $webform_submission,
-      '#access' => $this->isModalDialog() ? FALSE : TRUE,
+      '#access' => $this->isDialog() ? FALSE : TRUE,
     ];
     $form['information'] = [
       '#theme' => 'webform_submission_information',
       '#webform_submission' => $webform_submission,
       '#source_entity' => $source_entity,
-      '#access' => $this->isModalDialog() ? FALSE : TRUE,
+      '#access' => $this->isDialog() ? FALSE : TRUE,
     ];
 
     $form['notes'] = [
@@ -74,7 +74,7 @@ class WebformSubmissionNotesForm extends ContentEntityForm {
       '#title' => $this->t('Star/flag the status of this submission.'),
       '#default_value' => $webform_submission->isSticky(),
       '#return_value' => TRUE,
-      '#access' => $this->isModalDialog() ? FALSE : TRUE,
+      '#access' => $this->isDialog() ? FALSE : TRUE,
     ];
     $form['uid'] = [
       '#type' => 'entity_autocomplete',
@@ -98,7 +98,7 @@ class WebformSubmissionNotesForm extends ContentEntityForm {
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
     $form = parent::buildForm($form, $form_state);
-    return $this->buildFormDialog($form, $form_state);
+    return $this->buildDialogForm($form, $form_state);
   }
 
   /**
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml b/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml
new file mode 100644
index 00000000..452761df
--- /dev/null
+++ b/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml
@@ -0,0 +1,106 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform
+open: null
+close: null
+uid: null
+template: false
+id: test_ajax
+title: 'Test: Ajax'
+description: 'Test Ajax enabled form with preview'
+category: 'Test: Ajax'
+elements: |
+  textfield:
+    '#title': textfield
+    '#type': textfield
+    '#required': true
+css: ''
+javascript: ''
+settings:
+  ajax: true
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_disable_autocomplete: false
+  form_novalidate: true
+  form_unsaved: false
+  form_disable_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  submission_label: ''
+  submission_log: false
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_start_label: ''
+  wizard_complete: true
+  wizard_complete_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  confirmation_type: message
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  limit_total: null
+  limit_total_message: ''
+  limit_user: null
+  limit_user_message: ''
+  purge: none
+  purge_days: null
+  entity_limit_total: null
+  entity_limit_user: null
+  results_disabled: false
+  results_disabled_ignore: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+handlers: {  }
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml b/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml
new file mode 100644
index 00000000..2f1e5ad2
--- /dev/null
+++ b/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml
@@ -0,0 +1,104 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_test
+open: null
+close: null
+uid: null
+template: false
+id: test_ajax_confirmation_inline
+title: 'Test: Ajax: Confirmation: Inline'
+description: 'Test Ajax inline confirmation message.'
+category: 'Test: Ajax'
+elements: |
+  description:
+    '#markup': 'This webform will display the confirmation inline when submitted.'
+css: ''
+javascript: ''
+settings:
+  ajax: true
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_unsaved: false
+  form_disable_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  submission_label: ''
+  submission_log: false
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_start_label: ''
+  wizard_complete: true
+  wizard_complete_label: ''
+  preview: 0
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  confirmation_type: inline
+  confirmation_title: ''
+  confirmation_message: 'This is a custom inline confirmation message.'
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  limit_total: null
+  limit_total_message: ''
+  limit_user: null
+  limit_user_message: ''
+  purge: none
+  purge_days: null
+  entity_limit_total: null
+  entity_limit_user: null
+  results_disabled: true
+  results_disabled_ignore: true
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+handlers: {  }
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml b/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml
new file mode 100644
index 00000000..f4851e48
--- /dev/null
+++ b/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml
@@ -0,0 +1,104 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_test
+open: null
+close: null
+uid: null
+template: false
+id: test_ajax_confirmation_message
+title: 'Test: Ajax: Confirmation: Message'
+description: 'Test Ajax basic confirmation message.'
+category: 'Test: Ajax'
+elements: |
+  description:
+    '#markup': 'This webform will display a confirmation message when submitted.'
+css: ''
+javascript: ''
+settings:
+  ajax: true
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_unsaved: false
+  form_disable_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  submission_label: ''
+  submission_log: false
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_start_label: ''
+  wizard_complete: true
+  wizard_complete_label: ''
+  preview: 0
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  confirmation_type: message
+  confirmation_title: ''
+  confirmation_message: 'This is a <b>custom</b> confirmation message.'
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  limit_total: null
+  limit_total_message: ''
+  limit_user: null
+  limit_user_message: ''
+  purge: none
+  purge_days: null
+  entity_limit_total: null
+  entity_limit_user: null
+  results_disabled: true
+  results_disabled_ignore: true
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+handlers: {  }
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml b/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml
new file mode 100644
index 00000000..36842d6f
--- /dev/null
+++ b/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml
@@ -0,0 +1,104 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_test
+open: null
+close: null
+uid: null
+template: false
+id: test_ajax_confirmation_page
+title: 'Test: Ajax: Confirmation: Page'
+description: 'Test Ajax redirecting to a confirmation page.'
+category: 'Test: Ajax'
+elements: |
+  description:
+    '#markup': 'This webform will redirect to the confirmation page when submitted.'
+css: ''
+javascript: ''
+settings:
+  ajax: true
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_unsaved: false
+  form_disable_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  submission_label: ''
+  submission_log: false
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_start_label: ''
+  wizard_complete: true
+  wizard_complete_label: ''
+  preview: 0
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: 'This is a custom confirmation page.'
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  limit_total: null
+  limit_total_message: ''
+  limit_user: null
+  limit_user_message: ''
+  purge: none
+  purge_days: null
+  entity_limit_total: null
+  entity_limit_user: null
+  results_disabled: true
+  results_disabled_ignore: true
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+handlers: {  }
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml b/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml
new file mode 100644
index 00000000..d0951eee
--- /dev/null
+++ b/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml
@@ -0,0 +1,104 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_test
+open: null
+close: null
+uid: null
+template: false
+id: test_ajax_confirmation_url
+title: 'Test: Ajax: Confirmation: URL'
+description: 'Test redirecting to an internal URL.'
+category: 'Test: Ajax'
+elements: |
+  description:
+    '#markup': 'This webform will redirect to the homepage when submitted.'
+css: ''
+javascript: ''
+settings:
+  ajax: true
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_unsaved: false
+  form_disable_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  submission_label: ''
+  submission_log: false
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_start_label: ''
+  wizard_complete: true
+  wizard_complete_label: ''
+  preview: 0
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  confirmation_type: url
+  confirmation_title: ''
+  confirmation_message: 'This is a custom confirmation message.'
+  confirmation_url: '<front>'
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  limit_total: null
+  limit_total_message: ''
+  limit_user: null
+  limit_user_message: ''
+  purge: none
+  purge_days: null
+  entity_limit_total: null
+  entity_limit_user: null
+  results_disabled: true
+  results_disabled_ignore: true
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+handlers: {  }
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml b/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml
new file mode 100644
index 00000000..39c10cf8
--- /dev/null
+++ b/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml
@@ -0,0 +1,104 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_test
+open: null
+close: null
+uid: null
+template: false
+id: test_ajax_confirmation_url_msg
+title: 'Test: Ajax: Confirmation: URL with message'
+description: 'Test Ajax redirecting to an internal URL with a confirmation message.'
+category: 'Test: Ajax'
+elements: |
+  description:
+    '#markup': 'This webform will redirect to the homepage when submitted an display a custom confirmation message.'
+css: ''
+javascript: ''
+settings:
+  ajax: true
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_unsaved: false
+  form_disable_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  submission_label: ''
+  submission_log: false
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_start_label: ''
+  wizard_complete: true
+  wizard_complete_label: ''
+  preview: 0
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  confirmation_type: url_message
+  confirmation_title: ''
+  confirmation_message: 'This is a custom confirmation message.'
+  confirmation_url: '<front>'
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  limit_total: null
+  limit_total_message: ''
+  limit_user: null
+  limit_user_message: ''
+  purge: none
+  purge_days: null
+  entity_limit_total: null
+  entity_limit_user: null
+  results_disabled: true
+  results_disabled_ignore: true
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+handlers: {  }
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml
index 244e0625..6862f7d2 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml
index e140d33a..7b710859 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml
index 6477a053..dafe65a4 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml
index 7dc3e67d..f959aea2 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml
index 6a144ae3..df26af92 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml
index 8cbb85bf..3fdfaa5c 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element.yml b/tests/modules/webform_test/config/install/webform.webform.test_element.yml
index d9194bd5..2544f2c9 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element.yml
@@ -234,6 +234,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml
index 7acb6af3..cf144b1e 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml
@@ -82,6 +82,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml
index e53fdb13..030ed4b8 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml
@@ -113,6 +113,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml
index f874b067..c828ef4e 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml
@@ -55,6 +55,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml
index 6a3acba9..d152a118 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml
@@ -20,6 +20,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml
index c132fc9a..76f0c21e 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml
@@ -33,6 +33,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml
index d90d7dfd..a9121bd0 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml
@@ -38,6 +38,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml
index 08a8c46a..ab9c1169 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml
@@ -38,6 +38,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml
index 7c1a9fda..c592d521 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml
@@ -92,6 +92,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml
index 4540b940..32efbb62 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml
@@ -70,6 +70,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml
index 6fb08d52..c8695fbe 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml
@@ -87,6 +87,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml
index 06486c7e..4c50c7fa 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml
@@ -57,6 +57,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml
index b1612066..c550a7bd 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml
@@ -47,6 +47,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml
index 3938d659..7be50678 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml
@@ -66,6 +66,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml
index bc7943f6..08483a34 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml
@@ -350,6 +350,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_email.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_email.yml
index 16ae2ea3..2b5fde4a 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_email.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_email.yml
@@ -53,6 +53,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml
index 642b2c0d..c074e241 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml
@@ -117,6 +117,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml
index 34c1dee9..3837d672 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml
@@ -943,6 +943,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml
index 28f36652..0f923021 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml
@@ -806,6 +806,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml
index f690c868..d56d7844 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml
@@ -1113,6 +1113,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_format_composite.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_format_composite.yml
index 46c462bd..a79960b4 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_format_composite.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_format_composite.yml
@@ -445,6 +445,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_format_multi_comp.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_format_multi_comp.yml
index 284f52ca..c110264c 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_format_multi_comp.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_format_multi_comp.yml
@@ -25,22 +25,19 @@ elements: |
         '#title': 'Address (Ordered list)'
         '#multiple': true
         '#default_value':
-          -
-            address: '10 Main Street'
+          - address: '10 Main Street'
             address_2: '10 Main Street'
             city: Springfield
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            address: '10 Main Street'
+          - address: '10 Main Street'
             address_2: '10 Main Street'
             city: Springfield
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            address: '10 Main Street'
+          - address: '10 Main Street'
             address_2: '10 Main Street'
             city: Springfield
             state_province: Alabama
@@ -52,22 +49,19 @@ elements: |
         '#title': 'Address (Unordered list)'
         '#multiple': true
         '#default_value':
-          -
-            address: '10 Main Street'
+          - address: '10 Main Street'
             address_2: '10 Main Street'
             city: Springfield
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            address: '10 Main Street'
+          - address: '10 Main Street'
             address_2: '10 Main Street'
             city: Springfield
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            address: '10 Main Street'
+          - address: '10 Main Street'
             address_2: '10 Main Street'
             city: Springfield
             state_province: Alabama
@@ -79,22 +73,19 @@ elements: |
         '#title': 'Address (Horizontal rule)'
         '#multiple': true
         '#default_value':
-          -
-            address: '10 Main Street'
+          - address: '10 Main Street'
             address_2: '10 Main Street'
             city: Springfield
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            address: '10 Main Street'
+          - address: '10 Main Street'
             address_2: '10 Main Street'
             city: Springfield
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            address: '10 Main Street'
+          - address: '10 Main Street'
             address_2: '10 Main Street'
             city: Springfield
             state_province: Alabama
@@ -109,8 +100,7 @@ elements: |
         '#title': 'Contact (Ordered list)'
         '#multiple': true
         '#default_value':
-          -
-            name: Loremipsum
+          - name: Loremipsum
             company: Loremipsum
             email: example@example.com
             phone: 123-456-7890
@@ -120,8 +110,7 @@ elements: |
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            name: Loremipsum
+          - name: Loremipsum
             company: Loremipsum
             email: example@example.com
             phone: 123-456-7890
@@ -131,8 +120,7 @@ elements: |
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            name: Loremipsum
+          - name: Loremipsum
             company: Loremipsum
             email: example@example.com
             phone: 123-456-7890
@@ -148,8 +136,7 @@ elements: |
         '#title': 'Contact (Unordered list)'
         '#multiple': true
         '#default_value':
-          -
-            name: Loremipsum
+          - name: Loremipsum
             company: Loremipsum
             email: example@example.com
             phone: 123-456-7890
@@ -159,8 +146,7 @@ elements: |
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            name: Loremipsum
+          - name: Loremipsum
             company: Loremipsum
             email: example@example.com
             phone: 123-456-7890
@@ -170,8 +156,7 @@ elements: |
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            name: Loremipsum
+          - name: Loremipsum
             company: Loremipsum
             email: example@example.com
             phone: 123-456-7890
@@ -187,8 +172,7 @@ elements: |
         '#title': 'Contact (Horizontal rule)'
         '#multiple': true
         '#default_value':
-          -
-            name: Loremipsum
+          - name: Loremipsum
             company: Loremipsum
             email: example@example.com
             phone: 123-456-7890
@@ -198,8 +182,7 @@ elements: |
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            name: Loremipsum
+          - name: Loremipsum
             company: Loremipsum
             email: example@example.com
             phone: 123-456-7890
@@ -209,8 +192,7 @@ elements: |
             state_province: Alabama
             postal_code: Loremipsum
             country: Afghanistan
-          -
-            name: Loremipsum
+          - name: Loremipsum
             company: Loremipsum
             email: example@example.com
             phone: 123-456-7890
@@ -229,14 +211,11 @@ elements: |
         '#title': 'Link (Ordered list)'
         '#multiple': true
         '#default_value':
-          -
-            title: Loremipsum
+          - title: Loremipsum
             url: 'http://example.com'
-          -
-            title: Loremipsum
+          - title: Loremipsum
             url: 'http://example.com'
-          -
-            title: Loremipsum
+          - title: Loremipsum
             url: 'http://example.com'
         '#format_items': ol
       webform_link_ul:
@@ -244,14 +223,11 @@ elements: |
         '#title': 'Link (Unordered list)'
         '#multiple': true
         '#default_value':
-          -
-            title: Loremipsum
+          - title: Loremipsum
             url: 'http://example.com'
-          -
-            title: Loremipsum
+          - title: Loremipsum
             url: 'http://example.com'
-          -
-            title: Loremipsum
+          - title: Loremipsum
             url: 'http://example.com'
         '#format_items': ul
       webform_link_hr:
@@ -259,14 +235,11 @@ elements: |
         '#title': 'Link (Horizontal rule)'
         '#multiple': true
         '#default_value':
-          -
-            title: Loremipsum
+          - title: Loremipsum
             url: 'http://example.com'
-          -
-            title: Loremipsum
+          - title: Loremipsum
             url: 'http://example.com'
-          -
-            title: Loremipsum
+          - title: Loremipsum
             url: 'http://example.com'
         '#format_items': hr
     webform_location:
@@ -280,12 +253,9 @@ elements: |
         '#format': map
         '#multiple': true
         '#default_value':
-          -
-            value: 'The White House, 1600 Pennsylvania Ave NW, Washington, DC 20500, USA'
-          -
-            value: 'London SW1A 1AA, United Kingdom'
-          -
-            value: 'Moscow, Russia, 10307'
+          - value: 'The White House, 1600 Pennsylvania Ave NW, Washington, DC 20500, USA'
+          - value: 'London SW1A 1AA, United Kingdom'
+          - value: 'Moscow, Russia, 10307'
         '#format_items': ol
       webform_location_ul:
         '#type': webform_location
@@ -295,12 +265,9 @@ elements: |
         '#format': map
         '#multiple': true
         '#default_value':
-          -
-            value: 'The White House, 1600 Pennsylvania Ave NW, Washington, DC 20500, USA'
-          -
-            value: 'London SW1A 1AA, United Kingdom'
-          -
-            value: 'Moscow, Russia, 10307'
+          - value: 'The White House, 1600 Pennsylvania Ave NW, Washington, DC 20500, USA'
+          - value: 'London SW1A 1AA, United Kingdom'
+          - value: 'Moscow, Russia, 10307'
         '#format_items': ul
       webform_location_hr:
         '#type': webform_location
@@ -310,12 +277,9 @@ elements: |
         '#format': map
         '#multiple': true
         '#default_value':
-          -
-            value: 'The White House, 1600 Pennsylvania Ave NW, Washington, DC 20500, USA'
-          -
-            value: 'London SW1A 1AA, United Kingdom'
-          -
-            value: 'Moscow, Russia, 10307'
+          - value: 'The White House, 1600 Pennsylvania Ave NW, Washington, DC 20500, USA'
+          - value: 'London SW1A 1AA, United Kingdom'
+          - value: 'Moscow, Russia, 10307'
         '#format_items': hr
     webform_name:
       '#type': details
@@ -325,22 +289,19 @@ elements: |
         '#title': 'Name (Ordered list)'
         '#multiple': true
         '#default_value':
-          -
-            title: Miss
+          - title: Miss
             first: Loremipsum
             middle: Loremipsum
             last: Loremipsum
             suffix: Loremipsum
             degree: Loremipsum
-          -
-            title: Miss
+          - title: Miss
             first: Loremipsum
             middle: Loremipsum
             last: Loremipsum
             suffix: Loremipsum
             degree: Loremipsum
-          -
-            title: Miss
+          - title: Miss
             first: Loremipsum
             middle: Loremipsum
             last: Loremipsum
@@ -352,22 +313,19 @@ elements: |
         '#title': 'Name (Unordered list)'
         '#multiple': true
         '#default_value':
-          -
-            title: Miss
+          - title: Miss
             first: Loremipsum
             middle: Loremipsum
             last: Loremipsum
             suffix: Loremipsum
             degree: Loremipsum
-          -
-            title: Miss
+          - title: Miss
             first: Loremipsum
             middle: Loremipsum
             last: Loremipsum
             suffix: Loremipsum
             degree: Loremipsum
-          -
-            title: Miss
+          - title: Miss
             first: Loremipsum
             middle: Loremipsum
             last: Loremipsum
@@ -379,22 +337,19 @@ elements: |
         '#title': 'Name (Horizontal rule)'
         '#multiple': true
         '#default_value':
-          -
-            title: Miss
+          - title: Miss
             first: Loremipsum
             middle: Loremipsum
             last: Loremipsum
             suffix: Loremipsum
             degree: Loremipsum
-          -
-            title: Miss
+          - title: Miss
             first: Loremipsum
             middle: Loremipsum
             last: Loremipsum
             suffix: Loremipsum
             degree: Loremipsum
-          -
-            title: Miss
+          - title: Miss
             first: Loremipsum
             middle: Loremipsum
             last: Loremipsum
@@ -409,16 +364,13 @@ elements: |
         '#title': 'Telephone advanced (Ordered list)'
         '#multiple': true
         '#default_value':
-          -
-            type: Home
+          - type: Home
             phone: '+1 212-333-4444'
             ext: 0
-          -
-            type: Home
+          - type: Home
             phone: '+1 212-333-4444'
             ext: 0
-          -
-            type: Home
+          - type: Home
             phone: '+1 212-333-4444'
             ext: 0
         '#format_items': ol
@@ -427,16 +379,13 @@ elements: |
         '#title': 'Telephone advanced (Unordered list)'
         '#multiple': true
         '#default_value':
-          -
-            type: Home
+          - type: Home
             phone: '+1 212-333-4444'
             ext: 0
-          -
-            type: Home
+          - type: Home
             phone: '+1 212-333-4444'
             ext: 0
-          -
-            type: Home
+          - type: Home
             phone: '+1 212-333-4444'
             ext: 0
         '#format_items': ul
@@ -445,22 +394,20 @@ elements: |
         '#title': 'Telephone advanced (Horizontal rule)'
         '#multiple': true
         '#default_value':
-          -
-            type: Home
+          - type: Home
             phone: '+1 212-333-4444'
             ext: 0
-          -
-            type: Home
+          - type: Home
             phone: '+1 212-333-4444'
             ext: 0
-          -
-            type: Home
+          - type: Home
             phone: '+1 212-333-4444'
             ext: 0
         '#format_items': hr
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml
index ea246eca..3974839f 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml
@@ -1578,6 +1578,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml
index 531fba20..b35c53c1 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml
@@ -27,6 +27,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml
index a5657bec..b4a3c1fa 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml
@@ -20,6 +20,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml
index 920418cf..38a3b1d8 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml
@@ -524,6 +524,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml
index ff71353e..826efd59 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml
@@ -524,6 +524,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_icheck.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_icheck.yml
index ee97c9bf..87d8c93d 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_icheck.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_icheck.yml
@@ -98,6 +98,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_icheck_styles.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_icheck_styles.yml
index 82ad5e5f..5a7ccd61 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_icheck_styles.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_icheck_styles.yml
@@ -688,6 +688,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml
index 8d2e9df5..a0953e49 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml
@@ -30,6 +30,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_image_select.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_image_select.yml
index 572a7c5f..6e7e798d 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_image_select.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_image_select.yml
@@ -126,6 +126,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml
index 064d198b..fcda1f1e 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml
@@ -19,6 +19,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml
index 0ccbface..205fdfff 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml
@@ -46,6 +46,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_location.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_location.yml
index 53fb1f32..ddc47aa9 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_location.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_location.yml
@@ -92,6 +92,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml
index 36f42a62..5e8b6e6f 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml
@@ -25,6 +25,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml
index d88bda7f..9764c4f0 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml
@@ -108,6 +108,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml
index 30d22849..d5b36c12 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml
@@ -30,6 +30,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml
index 338e25dd..d6f42ff8 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml
@@ -67,6 +67,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml
index 51a910cc..ee80b744 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml
@@ -85,6 +85,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml
index bffb677b..8181a4b0 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml
@@ -163,6 +163,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml
index 2dcdd3df..6dc6c1c4 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml
@@ -40,6 +40,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml
index e996e951..3fd29df8 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml
@@ -36,6 +36,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml
index fe3e3646..bd0d3a57 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml
@@ -81,6 +81,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml
index 2aa5b1c8..be57ac20 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml
@@ -58,6 +58,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml
index bb8c42e2..373fcc1e 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml
@@ -139,6 +139,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml
index e49a9895..2e8b54b5 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml
@@ -24,6 +24,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml
index 42222879..0e4a1aba 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml
@@ -57,6 +57,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml
index f4821115..10d3fe4e 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml
@@ -30,6 +30,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml
index 813f38d7..0b5bc078 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml
@@ -23,6 +23,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml
index 51d0e6d3..a6cb19c3 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml
@@ -80,6 +80,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml
index deabec48..07abff35 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml
@@ -179,6 +179,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml
index 4623c44e..9ebb9fcf 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml
@@ -23,6 +23,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml
index ae382b9d..9b3bf1c4 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml
@@ -97,6 +97,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_text.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_text.yml
index 5a338eec..4a1396c3 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_text.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_text.yml
@@ -48,6 +48,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml
index 6878337f..f1ed78c4 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml
@@ -21,6 +21,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml
index 48feb3a6..8354a755 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml
@@ -63,6 +63,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_toggle.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_toggle.yml
index c4e5bec8..2fadb077 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_toggle.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_toggle.yml
@@ -50,6 +50,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml
index cc822044..aba05ac5 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml
@@ -33,6 +33,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml
index 8ec3a9cc..be604f87 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml
@@ -21,6 +21,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml
index 27bcf784..f3c1095d 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml
@@ -79,6 +79,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml
index 5d5c120c..d3f68472 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml
@@ -30,6 +30,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml b/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml
index f3ab9e99..643b3f9b 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml
@@ -40,6 +40,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml
index 25067bc7..1eee9a3c 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml
@@ -119,6 +119,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml
index d7d18224..de74e828 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml
@@ -29,6 +29,7 @@ javascript: |
     });
   })(jQuery);
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml
index ef53195c..a8d11049 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml
@@ -19,6 +19,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml
index bf188e0a..94d3ebb2 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml
index a628ea7d..105b52b2 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml
@@ -19,6 +19,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml
index 524701ca..4b6804f8 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml
@@ -26,6 +26,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml
index 0841083b..a9d90cab 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml
@@ -21,6 +21,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml
index 320241e5..1643ce7d 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml
@@ -346,6 +346,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml
index 72e3caa5..94a2785e 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml
@@ -23,6 +23,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml
index 6e2ce47c..21437fa4 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml
@@ -23,6 +23,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml
index c7ffd906..e858b725 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml
@@ -23,6 +23,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml
index 2f5b5c8d..299a19f9 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml
@@ -19,6 +19,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml
index b21a4fe7..d609dc63 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml
@@ -316,6 +316,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml
index 7600bcb2..f084eb5a 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml
@@ -616,6 +616,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml
index 538d5fbd..4ceda9d9 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml
@@ -916,6 +916,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml
index d6ee665e..08073b7b 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml
@@ -23,6 +23,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml
index 4ec92fe2..7089826a 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml
index 9585bf0b..5cfea452 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml
@@ -28,6 +28,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml
index 6a554337..906f2e0a 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml
@@ -19,6 +19,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml
index c11e411e..4723cb4e 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml
@@ -31,6 +31,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml
index 5e79aa3e..07711dc7 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_states.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_states.yml
index 95d8fe13..931ac850 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_states.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_states.yml
@@ -2559,6 +2559,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_states_triggers.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_states_triggers.yml
index 87397447..7b1ca5c5 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_states_triggers.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_states_triggers.yml
@@ -131,6 +131,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml
index fe6239df..21bc35cb 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml
@@ -27,6 +27,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml
index a086e915..59e26338 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml
@@ -20,6 +20,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml
index add549ef..e008e5d2 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml
index f67732ca..a490688b 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml
@@ -20,6 +20,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml
index e646a074..4064eaf8 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml
@@ -19,6 +19,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml
index 3b3622ae..e4027a80 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml
@@ -61,6 +61,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml
index 71e10e53..3af3a177 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml
@@ -30,6 +30,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml
index 593f03e4..c46281f5 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml
@@ -62,6 +62,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml
index e2777c49..43f14379 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml
@@ -346,6 +346,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml
index e480d99c..0d8e19e2 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml
@@ -676,6 +676,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml
index 1ba8e58c..72d8fb1e 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml
@@ -1006,6 +1006,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml b/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml
index 69046cd7..8adc1ce9 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml
@@ -41,6 +41,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml b/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml
index 183c0997..517bb296 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml
@@ -45,6 +45,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml b/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml
index d94d8b4e..167b9c71 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml
@@ -31,6 +31,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml b/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml
index 98f7fe01..165fe305 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml
@@ -23,6 +23,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml b/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml
index 4a894adc..f40cd87a 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml
@@ -18,6 +18,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml b/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml
index 374fe4ce..5faf33dd 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml
@@ -94,6 +94,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_results.yml b/tests/modules/webform_test/config/install/webform.webform.test_results.yml
index c3e17f11..dea43085 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_results.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_results.yml
@@ -59,6 +59,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml b/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml
index 73ce2d11..c266f6b9 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml
@@ -1,6 +1,9 @@
 langcode: en
 status: open
-dependencies: {  }
+dependencies:
+  enforced:
+    module:
+      - webform_test
 open: null
 close: null
 uid: 1
@@ -17,6 +20,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml b/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml
index bc335c82..b4cc7fd3 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml
@@ -19,6 +19,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_token.yml b/tests/modules/webform_test/config/install/webform.webform.test_token.yml
index fd774da0..10c26392 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_token.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_token.yml
@@ -124,6 +124,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml b/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml
index f5ed74f8..f09e0fca 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml
@@ -92,6 +92,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
@@ -145,7 +146,7 @@ settings:
     <tr><th width="50%">webform_submission:values:emails:2:html</th><td width="50%">[webform_submission:values:emails:2:html]</td></tr>
     <tr><th width="50%">webform_submission:values:emails:99:html</th><td width="50%">[webform_submission:values:emails:99]</td></tr>
     </table>
-
+    
     <h3>users</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:user</th><td width="50%">[webform_submission:values:user]</td></tr>
@@ -154,7 +155,7 @@ settings:
     <tr><th width="50%">webform_submission:values:users:0:entity:account-name</th><td width="50%">[webform_submission:values:users:0:entity:account-name]</td></tr>
     <tr><th width="50%">webform_submission:values:users:99:entity:account-name</th><td width="50%">[webform_submission:values:users:99:entity:account-name]</td></tr>
     </table>
-
+    
     <h3>names</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:name</th><td width="50%">[webform_submission:values:name]</td></tr>
@@ -163,7 +164,7 @@ settings:
     <tr><th width="50%">webform_submission:values:names:1</th><td width="50%">[webform_submission:values:names:1]</td></tr>
     <tr><th width="50%">webform_submission:values:names:99</th><td width="50%">[webform_submission:values:names:99]</td></tr>
     </table>
-
+    
     <h3>contacts</h3>
     <table class="table">
     <tr><th width="50%">webform_submission:values:contact</th><td width="50%">[webform_submission:values:contact]</td></tr>
diff --git a/tests/modules/webform_test/config/install/webform.webform.test_token_update.yml b/tests/modules/webform_test/config/install/webform.webform.test_token_update.yml
index be88ce26..3ac53e53 100644
--- a/tests/modules/webform_test/config/install/webform.webform.test_token_update.yml
+++ b/tests/modules/webform_test/config/install/webform.webform.test_token_update.yml
@@ -19,6 +19,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite.yml b/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_custom.yml
similarity index 93%
rename from tests/modules/webform_test_element/config/install/webform.webform.test_element_composite.yml
rename to tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_custom.yml
index 087f5da1..43a26af6 100644
--- a/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite.yml
+++ b/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_custom.yml
@@ -8,9 +8,9 @@ open: null
 close: null
 uid: null
 template: false
-id: test_element_composite
-title: 'Test: Element: Composite'
-description: 'Test the webform composite element.'
+id: test_element_composite_custom
+title: 'Test: Element: Composite custom'
+description: 'Test custom webform composite element.'
 category: 'Test: Element'
 elements: |
   webform_test_composite:
@@ -23,6 +23,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
@@ -42,6 +43,7 @@ settings:
   form_disable_back: false
   form_autofocus: false
   form_details_toggle: false
+  submission_label: ''
   submission_log: false
   wizard_progress_bar: true
   wizard_progress_pages: false
diff --git a/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml b/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml
index d47b3eda..1d6b3e3b 100644
--- a/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml
+++ b/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml
@@ -23,6 +23,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_remote_post.yml b/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_remote_post.yml
index 25c03dc8..bc378016 100644
--- a/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_remote_post.yml
+++ b/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_remote_post.yml
@@ -41,6 +41,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml b/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml
index 1666faf6..38effb5e 100644
--- a/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml
+++ b/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml
@@ -22,6 +22,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml b/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml
index 540c71a0..a01f0ca0 100644
--- a/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml
+++ b/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml
@@ -224,6 +224,7 @@ elements: |
 css: ''
 javascript: ''
 settings:
+  ajax: false
   page: true
   page_submit_path: ''
   page_confirm_path: ''
diff --git a/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml b/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml
index 81f5cf61..38fe5ebb 100644
--- a/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml
+++ b/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml
@@ -1,16 +1,17 @@
 langcode: en
 status: open
-open: null
-close: null
 dependencies:
   enforced:
     module:
       - webform_test_translation
+open: null
+close: null
 uid: null
 template: false
 id: test_translation
 title: 'Test: Translations'
 description: 'Test translating a webform.'
+category: null
 elements: |
   textfield:
     '#type': textfield
@@ -124,3 +125,11 @@ handlers:
       html: true
       attachments: false
       debug: false
+      states:
+        - completed
+      to_options: {  }
+      cc_options: {  }
+      bcc_options: {  }
+      from_options: {  }
+      reply_to: ''
+      return_path: ''
diff --git a/tests/modules/webform_test_translation/config/install/webform.webform_options.test_translation.yml b/tests/modules/webform_test_translation/config/install/webform.webform_options.test_translation.yml
index c477727b..c3d5232d 100644
--- a/tests/modules/webform_test_translation/config/install/webform.webform_options.test_translation.yml
+++ b/tests/modules/webform_test_translation/config/install/webform.webform_options.test_translation.yml
@@ -7,6 +7,7 @@ dependencies:
       - webform_test_translation
 id: test_translation
 label: 'Test: Translation'
+category: null
 options: |
   1: One
   2: Two
diff --git a/tests/modules/webform_test_translation/webform_test_translation.features.yml b/tests/modules/webform_test_translation/webform_test_translation.features.yml
index 27ba77dd..f32a5804 100644
--- a/tests/modules/webform_test_translation/webform_test_translation.features.yml
+++ b/tests/modules/webform_test_translation/webform_test_translation.features.yml
@@ -1 +1 @@
-true
+true
\ No newline at end of file
diff --git a/tests/src/FunctionalJavascript/WebformAjaxJavaScriptTest.php b/tests/src/FunctionalJavascript/WebformAjaxJavaScriptTest.php
new file mode 100644
index 00000000..f72b3a49
--- /dev/null
+++ b/tests/src/FunctionalJavascript/WebformAjaxJavaScriptTest.php
@@ -0,0 +1,156 @@
+<?php
+
+namespace Drupal\Tests\webform\FunctionalJavascript;
+
+use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
+use Drupal\webform\Entity\Webform;
+use Drupal\webform\Tests\WebformTestTrait;
+
+/**
+ * Tests webform JavasScript.
+ *
+ * @group webform_javascript
+ */
+class WebformAjaxJavaScriptTest extends JavascriptTestBase {
+
+  use WebformTestTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = ['webform'];
+
+  /**
+   * Webforms to load.
+   *
+   * @var array
+   */
+  protected static $testWebforms = [
+    'test_ajax',
+    'test_ajax_confirmation_inline',
+    'test_ajax_confirmation_message',
+    'test_ajax_confirmation_page',
+    'test_ajax_confirmation_url',
+    'test_ajax_confirmation_url_msg',
+  ];
+
+  /**
+   * Tests Ajax.
+   */
+  public function testAjax() {
+
+    /**************************************************************************/
+    // Test Ajax. (test_ajax)
+    /**************************************************************************/
+
+    $webform_ajax = Webform::load('test_ajax');
+
+    $assert_session = $this->assertSession();
+
+    // Validate form.
+    $this->drupalPostForm($webform_ajax->toUrl(), ['textfield' => ''], t('Submit'));
+    $assert_session->waitForElement('css', '.messages--error');
+
+    // Check validation message.
+    $assert_session->responseContains('textfield field is required.');
+
+    // Preview form.
+    $this->drupalPostForm($webform_ajax->toUrl(), ['textfield' => 'test value'], t('Preview'));
+    $assert_session->waitForElement('css', '.messages--warning');
+
+    // Check preview message.
+    $assert_session->responseContains('Please review your submission. Your submission is not complete until you press the "Submit" button!');
+
+    // Submit form.
+    $this->drupalPostForm($webform_ajax->toUrl(), ['textfield' => 'test value'], t('Submit'));
+    $assert_session->waitForElement('css', '.messages--status');
+
+    // Check submit message.
+    $assert_session->responseContains('New submission added to Test: Ajax.');
+
+    // Check that submission was created.
+    $sid = $this->getLastSubmissionId($webform_ajax);
+    $this->assertEquals($sid, 1);
+
+    // Check that text field is blank.
+    $assert_session->fieldValueEquals('textfield', '');
+
+    /**************************************************************************/
+    // Test Ajax confirmation inline. (test_ajax_confirmation_inline)
+    /**************************************************************************/
+
+    $webform_ajax_confirmation_inline = Webform::load('test_ajax_confirmation_inline');
+
+    // Submit form.
+    $this->drupalPostForm($webform_ajax_confirmation_inline->toUrl(), [], t('Submit'));
+    $assert_session->waitForElement('css', '.messages--status');
+
+    // Check submit message.
+    $assert_session->responseContains('This is a custom inline confirmation message.');
+
+    // Click back to form.
+    $this->clickLink('Back to form');
+    $assert_session->waitForButton('Submit');
+
+    // Check submit message.
+    $assert_session->responseNotContains('This is a custom inline confirmation message.');
+    $assert_session->responseContains('This webform will display the confirmation inline when submitted.');
+
+    /**************************************************************************/
+    // Test Ajax confirmation message. (test_ajax_confirmation_message)
+    /**************************************************************************/
+
+    $webform_ajax_confirmation_message = Webform::load('test_ajax_confirmation_message');
+
+    // Submit form.
+    $this->drupalPostForm($webform_ajax_confirmation_message->toUrl(), [], t('Submit'));
+    $assert_session->waitForElement('css', '.messages--status');
+
+    // Check confirmation message.
+    $assert_session->responseContains('This is a <b>custom</b> confirmation message.');
+    $assert_session->responseContains('This webform will display a confirmation message when submitted.');
+
+    /**************************************************************************/
+    // Test Ajax confirmation page. (test_ajax_confirmation_page)
+    /**************************************************************************/
+
+    $webform_ajax_confirmation_page = Webform::load('test_ajax_confirmation_page');
+
+    // Submit form.
+    $this->drupalPostForm($webform_ajax_confirmation_page->toUrl(), [], t('Submit'));
+    $assert_session->waitForLink('Back to form');
+
+    // Check confirmation page message.
+    $assert_session->responseContains('This is a custom confirmation page.');
+
+    /**************************************************************************/
+    // Test Ajax confirmation url. (test_ajax_confirmation_url)
+    /**************************************************************************/
+
+    $webform_ajax_confirmation_url  = Webform::load('test_ajax_confirmation_url');
+
+    // Submit form.
+    $this->drupalPostForm($webform_ajax_confirmation_url->toUrl(), [], t('Submit'));
+    $assert_session->waitForElement('css', '.path-front');
+
+    // Check current page is <front>.
+    $this->assertSession()->addressEquals('/');
+
+    /**************************************************************************/
+    // Test Ajax confirmation url with message. (test_ajax_confirmation_url_msg)
+    /**************************************************************************/
+
+    $webform_ajax_confirmation_url_msg  = Webform::load('test_ajax_confirmation_url_msg');
+
+    // Submit form.
+    $this->drupalPostForm($webform_ajax_confirmation_url_msg->toUrl(), [], t('Submit'));
+    $assert_session->waitForElement('css', '.path-front');
+
+    // Check current page is <front>.
+    $this->assertSession()->addressEquals('/');
+
+    // Check confirmation message.
+    $assert_session->responseContains('This is a custom confirmation message.');
+  }
+
+}
diff --git a/tests/src/FunctionalJavascript/WebformJavaScriptTest.php b/tests/src/FunctionalJavascript/WebformJavaScriptTest.php
deleted file mode 100644
index 80a5ceb8..00000000
--- a/tests/src/FunctionalJavascript/WebformJavaScriptTest.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-
-namespace Drupal\Tests\webform\FunctionalJavascript;
-
-use Drupal\FunctionalJavascriptTests\JavascriptTestBase;
-
-/**
- * Tests webform JavasScript.
- *
- * @group webform
- */
-class WebformJavaScriptTest extends JavascriptTestBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public static $modules = ['webform'];
-
-  /**
-   * Tests JavaScript.
-   */
-  public function testJavaScript() {
-    $this->drupalGet('webform/contact');
-    $this->assertSession()->responseContains('Send message');
-  }
-
-}
diff --git a/webform.install b/webform.install
index 4a527cee..90ddabd4 100644
--- a/webform.install
+++ b/webform.install
@@ -735,3 +735,10 @@ function webform_update_8051() {
   _webform_update_admin_settings();
   _webform_update_webform_settings();
 }
+
+/**
+ * Issue #2757491: Allow Webforms to be submitted using AJAX.
+ */
+function webform_update_8052() {
+  _webform_update_webform_settings();
+}
