From 4d3b998a0eb52f0cd6db4f5fecdb7bd4ec784d17 Mon Sep 17 00:00:00 2001
From: Brian Canini <canini.16@osu.edu>
Date: Thu, 9 Jul 2020 09:51:03 -0400
Subject: [PATCH] Updating drupal/webform (5.12.0 => 5.18.0)

---
 composer.json                                 |    4 +-
 composer.lock                                 |   41 +-
 vendor/composer/installed.json                |   41 +-
 web/modules/webform/.gitignore                |    1 +
 web/modules/webform/composer.json             |   28 +-
 web/modules/webform/composer.libraries.json   |   24 +-
 .../config/install/webform.settings.yml       |    9 +-
 .../install/webform.webform.contact.yml       |   15 +-
 .../views.view.webform_submissions.yml        |   19 +-
 .../schema/webform.entity.webform.schema.yml  |   39 +-
 .../config/schema/webform.settings.schema.yml |   15 +
 web/modules/webform/css/webform.addons.css    |    2 +-
 web/modules/webform/css/webform.admin.css     |    2 +-
 .../webform/css/webform.admin.settings.css    |    2 +-
 web/modules/webform/css/webform.ajax.css      |    2 +-
 web/modules/webform/css/webform.composite.css |    2 +-
 .../css/webform.composite.telephone.css       |    2 +-
 .../webform/css/webform.element.choices.css   |    2 +-
 .../css/webform.element.codemirror.css        |    2 +-
 .../webform/css/webform.element.color.css     |    2 +-
 .../webform/css/webform.element.composite.css |    2 +-
 .../webform/css/webform.element.computed.css  |    2 +-
 .../webform/css/webform.element.counter.css   |    2 +-
 .../webform/css/webform.element.date.css      |    2 +-
 .../webform/css/webform.element.datelist.css  |    2 +-
 .../css/webform.element.details.toggle.css    |    2 +-
 .../css/webform.element.file.button.css       |    2 +-
 .../webform/css/webform.element.flexbox.css   |    2 +-
 .../webform/css/webform.element.help.css      |    2 +-
 .../css/webform.element.horizontal_rule.css   |    2 +-
 .../css/webform.element.html_editor.css       |    2 +-
 .../css/webform.element.image_file.css        |    2 +-
 .../css/webform.element.managed_file.css      |    2 +-
 .../webform/css/webform.element.mapping.css   |    2 +-
 .../webform/css/webform.element.message.css   |    2 +-
 .../webform/css/webform.element.more.css      |    2 +-
 .../webform/css/webform.element.options.css   |   22 +-
 .../webform/css/webform.element.range.css     |    2 +-
 .../webform/css/webform.element.rating.css    |   14 +-
 .../webform/css/webform.element.scale.css     |    2 +-
 .../webform/css/webform.element.select2.css   |    2 +-
 .../css/webform.element.text_format.css       |    2 +-
 .../css/webform.element.video_file.css        |    2 +-
 web/modules/webform/css/webform.filter.css    |    3 +-
 web/modules/webform/css/webform.form.css      |    2 +-
 .../webform/css/webform.progress.tracker.css  |   41 +-
 .../webform/css/webform.theme.claro.css       |   17 +-
 web/modules/webform/css/webform.token.css     |    2 +-
 .../webform/css/webform.wizard.pages.css      |   17 -
 .../webform/docs/DEVELOPMENT-CHEATSHEET.md    |   25 +-
 web/modules/webform/docs/RELEASE-NOTES.md     |    2 +
 web/modules/webform/drupalci.yml              |   54 +-
 .../webform/includes/webform.form_alter.inc   |   10 +-
 .../webform/includes/webform.install.inc      |   30 +-
 .../includes/webform.install.requirements.inc |    4 +-
 .../includes/webform.install.update.inc       |   76 +-
 .../webform/includes/webform.libraries.inc    |   15 +-
 .../webform/includes/webform.options.inc      |   12 +-
 .../webform/includes/webform.theme.inc        |  115 +-
 .../includes/webform.theme.template.inc       |   86 +-
 .../webform/includes/webform.translation.inc  |   57 +-
 web/modules/webform/js/webform.admin.js       |    2 +-
 web/modules/webform/js/webform.ajax.js        |   15 +-
 web/modules/webform/js/webform.dialog.js      |   17 +
 .../webform/js/webform.element.checkboxes.js  |   84 +
 .../webform/js/webform.element.counter.js     |    1 +
 .../webform/js/webform.element.signature.js   |    9 +-
 .../webform/js/webform.form.unsaved.js        |   11 +-
 .../webform/js/webform.wizard.pages.js        |   10 +-
 .../src/Access/WebformAccessGroupAccess.php   |    2 +-
 .../src/Entity/WebformAccessGroup.php         |    8 +-
 .../src/WebformAccessGroupForm.php            |    2 +-
 .../src/WebformAccessGroupListBuilder.php     |   10 +-
 .../src/WebformAccessTypeListBuilder.php      |    2 +-
 .../WebformAccessBrowserTestBase.php          |    2 +-
 .../WebformAccessSubmissionViewsTest.php      |    2 +-
 .../src/Functional/WebformAccessTest.php      |   14 +-
 .../Functional/WebformAccessTokensTest.php    |    2 +-
 .../webform_access/webform_access.info.yml    |    8 +-
 .../webform_access/webform_access.module      |    8 +-
 .../webform_access/webform_access.tokens.inc  |    2 +-
 .../WebformAttachmentController.php           |    2 +-
 .../WebformElement/WebformAttachmentBase.php  |    2 +-
 ...webform.webform.test_attachment_access.yml |   15 +-
 .../webform.webform.test_attachment_email.yml |   17 +-
 ...bform.webform.test_attachment_sanitize.yml |   15 +-
 ...webform.webform.test_attachment_states.yml |   15 +-
 .../webform.webform.test_attachment_token.yml |   15 +-
 .../webform.webform.test_attachment_twig.yml  |   15 +-
 .../webform.webform.test_attachment_url.yml   |   15 +-
 .../webform_attachment_test.info.yml          |   14 +-
 .../src/Functional/WebformAttachmentTest.php  |    2 +-
 .../webform_attachment.info.yml               |   12 +-
 .../src/WebformBootstrapRenderCallbacks.php   |   34 +
 .../webform_bootstrap_test_module.info.yml    |   12 +-
 .../webform_bootstrap_test_theme.info.yml     |   12 +-
 .../webform_bootstrap.info.yml                |    8 +-
 .../webform_bootstrap.module                  |   18 +-
 .../webform_cards/css/webform_cards.admin.css |   25 +
 .../webform_cards/css/webform_cards.css       |   78 +
 .../webform_cards/js/webform_cards.admin.js   |   40 +
 .../modules/webform_cards/js/webform_cards.js |  641 +++
 .../webform_cards/src/Element/WebformCard.php |   59 +
 .../src/Form/WebformCardsConvertForm.php      |   73 +
 .../src/Plugin/WebformElement/WebformCard.php |  142 +
 .../Routing/WebformCardsRouteSubscriber.php   |   40 +
 .../webform_cards/src/WebformCardsManager.php |  130 +
 .../src/WebformCardsManagerInterface.php      |   55 +
 .../templates/webform-card.html.twig          |   52 +
 .../webform.webform.test_cards_access.yml     |  239 ++
 .../webform.webform.test_cards_ajax.yml       |  208 +
 ...ebform.webform.test_cards_auto_forward.yml |  270 ++
 .../webform.webform.test_cards_draft.yml      |  208 +
 .../webform.webform.test_cards_long_100.yml   |  794 ++++
 .../webform.webform.test_cards_progress.yml   |  208 +
 ...orm.webform.test_cards_progress_custom.yml |  297 ++
 ...form.webform.test_cards_progress_links.yml |  208 +
 .../webform.webform.test_cards_states.yml     |  297 ++
 .../webform.webform.test_cards_titles.yml     |  211 +
 .../webform.webform.test_cards_toggle.yml     |  208 +
 ...m.webform.test_cards_validation_errors.yml |  216 +
 ...ress--test-cards-progress-custom.html.twig |   97 +
 .../webform_cards_test.info.yml               |   12 +
 .../webform_cards_test.module                 |   32 +
 .../WebformCardsAjaxJavaScriptTest.php        |   58 +
 .../WebformCardsAutoForwardJavaScriptTest.php |   71 +
 .../WebformCardsDraftJavaScriptTest.php       |   56 +
 .../WebformCardsProgressJavaScriptTest.php    |  207 +
 .../WebformCardsStatesJavaScriptTest.php      |   81 +
 .../WebformCardsToggleJavaScriptTest.php      |   68 +
 .../WebformCardsUiJavaScriptTest.php          |   54 +
 .../WebformCardsValidationJavaScriptTest.php  |   46 +
 .../webform_cards/webform_cards.info.yml      |   15 +
 .../webform_cards/webform_cards.libraries.yml |   22 +
 .../webform_cards.links.action.yml            |   10 +
 .../webform_cards/webform_cards.module        |  497 +++
 .../webform_cards/webform_cards.routing.yml   |   16 +
 .../webform_cards/webform_cards.services.yml  |    9 +
 .../css/webform_clientside_validation.ife.css |    8 +
 .../js/webform_clientside_validation.ife.js   |   28 +
 ...ebform_clientside_validation.novalidate.js |   25 +
 ...orm.webform.test_clientside_validation.yml |  344 ++
 ...ebform_clientside_validation_test.info.yml |   12 +
 .../webform_clientside_validation.info.yml    |   14 +
 .../webform_clientside_validation.install     |   16 +
 ...ebform_clientside_validation.libraries.yml |   16 +
 .../webform_clientside_validation.module      |   49 +
 .../webform.webform.demo_application.yml      |   15 +-
 ...rm.webform.demo_application_evaluation.yml |   19 +-
 ...bform_demo_application_evaluation.info.yml |    8 +-
 ...webform_demo_application_evaluation.module |   12 +-
 ...ebform.webform.demo_event_registration.yml |   15 +-
 .../webform_demo_event_registration.info.yml  |   11 +-
 .../webform.webform.webform_group_contact.yml |   15 +-
 .../webform_demo_group.info.yml               |    8 +-
 .../webform_demo_group.install                |    3 +-
 .../webform.webform.demo_region_contact.yml   |   15 +-
 .../webform_demo_region_contact.info.yml      |    8 +-
 .../src/Commands/WebformDevelCommands.php     |    4 +-
 .../WebformDevelEntityFormApiBaseForm.php     |    4 +-
 .../WebformDevelEntityFormApiExportForm.php   |    6 +-
 .../WebformDevelEntityFormApiTestForm.php     |    2 +-
 .../src/Form/WebformDevelEntitySchemaForm.php |    2 +-
 .../Form/WebformDevelSubmissionApiForm.php    |    8 +-
 .../webform_devel/src/WebformDevelSchema.php  |    4 +-
 .../webform_devel/webform_devel.info.yml      |    8 +-
 .../webform_devel/webform_devel.module        |    5 +-
 .../Controller/WebformEditorialController.php |    2 +-
 .../webform_editorial.info.yml                |    8 +-
 .../WebformEntityPrintRequestSubscriber.php   |    2 +-
 .../webform.webform.test_entity_print.yml     |   15 +-
 ...bform.webform.test_entity_print_custom.yml |   15 +-
 .../webform_entity_print_test.info.yml        |   12 +-
 .../WebformEntityPrintFunctionalTest.php      |    6 +-
 .../WebformEntityPrintFunctionalTestBase.php  |    6 +-
 .../webform_entity_print.info.yml             |    8 +-
 .../webform_entity_print.module               |    2 +-
 ...m.webform.test_entity_print_attachment.yml |   15 +-
 ...form_entity_print_attachment_test.info.yml |   12 +-
 .../webform_entity_print_attachment.info.yml  |    8 +-
 ...form.webform.webform_example_composite.yml |   15 +-
 .../webform-example-composite.html.twig       |    2 -
 .../WebformExampleCompositeTest.php           |    2 +-
 .../webform_example_composite.info.yml        |    8 +-
 ...rm.webform.webform_example_custom_form.yml |   15 +-
 .../WebformExampleCustomFormSettingsForm.php  |    2 +-
 .../webform_example_custom_form.info.yml      |    8 +-
 ...ebform.webform.webform_example_element.yml |   15 +-
 .../Functional/WebformExampleElementTest.php  |    2 +-
 .../webform_example_element.info.yml          |    8 +-
 .../WebformExampleElementPropertiesTest.php   |    6 +-
 ...ebform_example_element_properties.info.yml |    8 +-
 ...ebform.webform.webform_example_handler.yml |   15 +-
 .../webform_example_handler.info.yml          |    8 +-
 .../webform.webform.example_remote_post.yml   |   25 +-
 .../webform_example_remote_post.info.yml      |    8 +-
 ...ebform.webform_example_variant_ab_test.yml |   17 +-
 ...bform.webform_example_variant_segments.yml |   15 +-
 .../webform_example_variant.info.yml          |    8 +-
 ...form.webform.example_computed_elements.yml |   15 +-
 ...webform.example_computed_elements_ajax.yml |   17 +-
 ...webform.webform.example_element_states.yml |   15 +-
 ...webform.webform.example_flexbox_layout.yml |   15 +-
 .../webform.webform.example_input_masks.yml   |   15 +-
 .../webform.webform.example_style_guide.yml   |   13 +-
 .../webform.webform.example_wizard.yml        |   26 +-
 .../webform.webform.example_cards.yml         |  261 ++
 .../webform_examples.info.yml                 |    8 +-
 ...webform.example_accessibility_advanced.yml |   15 +-
 ...rm.webform.example_accessibility_basic.yml |   15 +-
 ...bform.example_accessibility_containers.yml |   15 +-
 ...m.webform.example_accessibility_labels.yml |   15 +-
 ...m.webform.example_accessibility_wizard.yml |   15 +-
 .../webform_examples_accessibility.info.yml   |    8 +-
 .../webform_examples_accessibility.module     |   12 +-
 .../webform_group/src/WebformGroupManager.php |    1 -
 ...bform.webform.test_element_group_roles.yml |   15 +-
 ...form.webform.test_group_element_access.yml |   15 +-
 .../webform_group_test.info.yml               |   12 +-
 .../WebformGroupBrowserTestBase.php           |    2 +-
 .../src/Functional/WebformGroupTokensTest.php |    2 -
 .../WebformGroupUserInterfaceTest.php         |    4 +-
 .../webform_group/webform_group.info.yml      |   10 +-
 .../webform_group/webform_group.module        |   16 +-
 .../webform.webform.test_element_icheck.yml   |   15 +-
 ...orm.webform.test_element_icheck_styles.yml |   15 +-
 .../webform_icheck_test.info.yml              |   14 +-
 .../Functional/WebformIcheckElementTest.php   |    2 +-
 .../webform_icheck/webform_icheck.info.yml    |    8 +-
 .../webform_icheck/webform_icheck.module      |    2 +-
 .../WebformImageSelectElementImages.php       |    4 +-
 .../src/Entity/WebformImageSelectImages.php   |    6 +-
 .../WebformElement/WebformImageSelect.php     |    2 +-
 .../src/WebformImageSelectImagesForm.php      |    2 +-
 .../WebformImageSelectImagesListBuilder.php   |    2 +-
 ...form.webform.test_element_image_select.yml |   15 +-
 .../webform.webform.test_element_images.yml   |   15 +-
 .../webform_image_select_test.info.yml        |   14 +-
 .../WebformImageSelectElementImagesTest.php   |    6 +-
 .../WebformImageSelectElementTest.php         |    4 +-
 .../WebformImageSelectImagesTest.php          |    6 +-
 .../webform_image_select.info.yml             |    8 +-
 .../webform_image_select.libraries.yml        |    4 +-
 .../webform_image_select.module               |    6 +-
 .../webform.webform.test_element_buttons.yml  |   15 +-
 .../webform_jqueryui_buttons_test.info.yml    |   14 +-
 .../Functional/WebformElementButtonsTest.php  |   12 +-
 .../webform_jqueryui_buttons.info.yml         |    8 +-
 .../webform_jqueryui_buttons.libraries.yml    |    1 +
 .../webform_jqueryui_buttons.module           |   20 +-
 .../WebformLocationGeocomplete.php            |    2 +-
 ...m.webform.test_element_loc_geocomplete.yml |   15 +-
 ...webform_location_geocomplete_test.info.yml |   14 +-
 .../WebformLocationGeocompleteTest.php        |    2 +-
 .../webform_location_geocomplete.info.yml     |    8 +-
 ...webform_location_geocomplete.libraries.yml |    1 +
 .../src/Access/WebformNodeAccess.php          |    2 +-
 .../WebformNodeReferencesListController.php   |   20 +-
 .../src/WebformNodeUninstallValidator.php     |    2 +-
 ...m.webform.webform_node_test_multiple_a.yml |   15 +-
 ...m.webform.webform_node_test_multiple_b.yml |   15 +-
 .../webform_node_test_multiple.info.yml       |   14 +-
 ....webform.webform_node_test_translation.yml |   17 +-
 .../webform_node_test_translation.info.yml    |   14 +-
 .../WebformNodeAccessPermissionsTest.php      |    2 +-
 .../Access/WebformNodeAccessRulesTest.php     |    2 +-
 .../WebformNodeBrowserTestBaseTest.php        |    2 +-
 .../WebformNodeEntityReferenceTest.php        |    2 +-
 .../Functional/WebformNodeReferencesTest.php  |    4 +-
 .../src/Functional/WebformNodeResultsTest.php |   10 +-
 .../tests/src/Functional/WebformNodeTest.php  |    6 +-
 .../Functional/WebformNodeTranslationTest.php |    2 +-
 .../src/Functional/WebformNodeVariantTest.php |    2 +-
 .../WebformNodeUninstallValidatorTest.php     |    2 +-
 .../webform_node/webform_node.info.yml        |    8 +-
 .../modules/webform_node/webform_node.install |    3 +-
 .../modules/webform_node/webform_node.module  |   18 +
 .../webform_node/webform_node.tokens.inc      |    2 +-
 ...webform.webform.example_options_custom.yml |   15 +-
 .../js/webform_options_custom.element.js      |    4 +-
 .../src/Entity/WebformOptionsCustom.php       |    4 +-
 .../src/WebformOptionsCustomDeleteForm.php    |    2 +-
 .../src/WebformOptionsCustomForm.php          |    2 +-
 .../src/WebformOptionsCustomListBuilder.php   |    2 +-
 ...ebform.test_element_options_custom_ent.yml |   15 +-
 ...ebform_options_custom_entity_test.info.yml |   14 +-
 ...bform.test_element_options_custom_html.yml |   15 +-
 ...bform.test_element_options_custom_imap.yml |   15 +-
 ...ebform.test_element_options_custom_svg.yml |   15 +-
 ...bform.test_element_options_custom_twig.yml |   15 +-
 ....webform_options_custom.test_image_map.yml |   12 +-
 .../webform_options_custom_test.info.yml      |   14 +-
 .../webform_options_custom_test.module        |    2 +-
 .../WebformOptionsCustomEntityTest.php        |    2 +-
 .../Functional/WebformOptionsCustomTest.php   |    2 +-
 .../webform_options_custom.info.yml           |   11 +-
 .../WebformOptionsLimitController.php         |    2 +-
 .../OptionsLimitWebformHandler.php            |  132 +-
 .../WebformOptionsLimitHandlerInterface.php   |   60 +
 ...orm.webform.test_handler_boolean_limit.yml |   15 +-
 ...orm.webform.test_handler_options_limit.yml |   18 +-
 ...webform.test_handler_options_limit_ent.yml |   13 +-
 ...ebform.test_handler_options_limit_user.yml |   13 +-
 .../webform_options_limit_test.info.yml       |   14 +-
 .../WebformOptionsLimitAccessTest.php         |    2 +-
 .../WebformOptionsLimitBooleanTest.php        |    2 +-
 ...WebformOptionsLimitEntityReferenceTest.php |    2 +-
 .../WebformOptionsLimitSourceEntityTest.php   |    2 +-
 .../Functional/WebformOptionsLimitTest.php    |    2 +-
 .../WebformOptionsLimitUserTest.php           |    2 +-
 .../webform_options_limit.info.yml            |   11 +-
 .../webform_options_limit.module              |    2 +-
 .../ScheduleEmailWebformHandler.php           |    2 +-
 .../src/WebformScheduledEmailManager.php      |  118 +-
 .../WebformScheduledEmailManagerInterface.php |   10 +-
 ...-handler-scheduled-email-summary.html.twig |    1 -
 ...m.webform.test_handler_scheduled_email.yml |   15 +-
 .../webform_scheduled_email_test.info.yml     |   14 +-
 ...bform.test_handler_scheduled_translate.yml |   15 +-
 ..._scheduled_email_test_translation.info.yml |   14 +-
 .../Functional/WebformScheduledEmailTest.php  |    4 +-
 .../WebformScheduledEmailTranslationTest.php  |    6 +-
 .../webform_scheduled_email.info.yml          |   10 +-
 .../webform_scheduled_email.module            |    6 +-
 .../webform_share/css/webform_share.admin.css |   18 +
 .../webform_share/css/webform_share.page.css  |   33 +
 .../webform_share/js/webform_share.admin.js   |   36 +
 .../src/Access/WebformShareAccess.php         |   71 +
 .../src/Controller/WebformShareController.php |  231 +
 .../src/Element/WebformShareIframe.php        |  126 +
 .../src/Element/WebformShareScript.php        |   67 +
 .../WebformShareEventSubscriber.php           |   56 +
 .../src/Form/WebformShareEmbedForm.php        |  159 +
 .../Routing/WebformShareRouteSubscriber.php   |   42 +
 .../src/Theme/WebformShareThemeNegotiator.php |   52 +
 .../webform_share/src/WebformShareHelper.php  |   23 +
 .../src/WebformSharePreRender.php             |   34 +
 .../templates/html--webform-share.html.twig   |   20 +
 .../templates/page--webform-share.html.twig   |    7 +
 .../templates/webform-share-iframe.html.twig  |   25 +
 .../templates/webform-share-script.html.twig  |   12 +
 .../src/Functional/WebformShareNodeTest.php   |   96 +
 .../tests/src/Functional/WebformShareTest.php |  161 +
 .../Functional/WebformShareVariantTest.php    |   71 +
 .../webform_share/webform_share.info.yml      |   13 +
 .../webform_share/webform_share.libraries.yml |   42 +
 .../webform_share.links.task.yml              |   46 +
 .../webform_share/webform_share.module        |  325 ++
 .../webform_share/webform_share.routing.yml   |  129 +
 .../webform_share/webform_share.services.yml  |   16 +
 .../WebformShortcutsFunctionalTest.php        |    6 +-
 .../webform_shortcuts.info.yml                |    8 +-
 .../webform_shortcuts.module                  |    5 +-
 ...ebformSubmissionExportImportController.php |    2 +-
 ...ebformSubmissionExportImportUploadForm.php |    6 +-
 .../WebformSubmissionExportImportImporter.php |    8 +-
 ....webform.test_submission_export_import.yml |   15 +-
 ...orm_submission_export_import_test.info.yml |   14 +-
 ...bform_submission_export_import_test.module |    2 +-
 ...rmSubmissionImportExportFunctionalTest.php |   20 +-
 .../webform_submission_export_import.info.yml |   11 +-
 .../webform_submission_export_import.module   |   19 +-
 .../WebformSubmissionLogController.php        |    2 +-
 .../src/WebformSubmissionLogManager.php       |   15 +-
 .../WebformSubmissionLogManagerInterface.php  |    5 +
 .../WebformSubmissionLogNodeTest.php          |    2 +-
 .../Functional/WebformSubmissionLogTest.php   |   12 +-
 .../webform_submission_log.info.yml           |    8 +-
 .../webform.webform.template_contact.yml      |   15 +-
 ...m.webform.template_employee_evaluation.yml |   15 +-
 .../webform.webform.template_feedback.yml     |   15 +-
 .../webform.webform.template_issue.yml        |   15 +-
 ...bform.webform.template_job_application.yml |   15 +-
 ...rm.webform.template_job_seeker_profile.yml |   17 +-
 ...m.webform.template_medical_appointment.yml |   15 +-
 .../webform.webform.template_registration.yml |   15 +-
 ...rm.webform.template_session_evaluation.yml |   15 +-
 .../webform.webform.template_subscribe.yml    |   15 +-
 .../webform.webform.template_user_profile.yml |   15 +-
 .../src/Functional/WebformTemplatesTest.php   |    2 +-
 .../webform_templates.info.yml                |    8 +-
 .../webform_templates.module                  |    2 +-
 .../webform.webform.test_element_toggles.yml  |   15 +-
 .../webform_toggles_test.info.yml             |   14 +-
 .../Functional/WebformTogglesElementTest.php  |    2 +-
 .../webform_toggles/webform_toggles.info.yml  |   10 +-
 .../webform_toggles.libraries.yml             |    1 +
 .../webform_ui/css/webform_ui.module.css      |    4 +
 .../src/Form/WebformUiElementDeleteForm.php   |    4 +-
 .../src/Form/WebformUiElementFormBase.php     |   10 +-
 .../src/Form/WebformUiElementTypeFormBase.php |    2 +-
 .../Form/WebformUiElementTypeSelectForm.php   |    6 -
 .../src/WebformUiEntityElementsForm.php       |   11 +-
 .../WebformUiElementActionsTest.php           |    6 +-
 .../WebformUiElementDefaultValueTest.php      |   18 +-
 .../WebformUiElementPropertiesTest.php        |    6 +-
 .../src/Functional/WebformUiElementTest.php   |   32 +-
 .../WebformUiElementJavaScriptTest.php        |    2 +-
 .../modules/webform_ui/webform_ui.info.yml    |    8 +-
 .../webform_ui/webform_ui.links.action.yml    |    5 +
 .../modules/webform_ui/webform_ui.module      |    8 +-
 .../text/example_accessibility_wizard.txt     |   44 +-
 .../src/Access/WebformSubmissionAccess.php    |    8 +-
 .../Breadcrumb/WebformBreadcrumbBuilder.php   |   22 +-
 .../src/Commands/WebformCliService.php        |   18 +-
 .../Controller/WebformElementController.php   |    6 +-
 .../Controller/WebformEntityController.php    |    2 +-
 .../WebformPluginElementController.php        |    2 +-
 .../WebformPluginHandlerController.php        |    4 +-
 .../WebformPluginVariantController.php        |    2 +-
 .../WebformResultsExportController.php        |    4 +-
 .../WebformSubmissionController.php           |    2 +-
 .../WebformSubmissionViewController.php       |    2 +-
 .../src/Controller/WebformTestController.php  |    2 +-
 .../webform/src/Element/WebformActions.php    |    2 +-
 .../webform/src/Element/WebformCodeMirror.php |    8 +-
 .../WebformCompositeFormElementTrait.php      |    2 +-
 .../src/Element/WebformComputedBase.php       |   27 +-
 .../src/Element/WebformComputedInterface.php  |   21 +
 .../src/Element/WebformComputedToken.php      |    2 +-
 .../src/Element/WebformComputedTwig.php       |    2 +-
 .../src/Element/WebformElementMultiple.php    |   14 +-
 .../src/Element/WebformElementOptions.php     |    6 +-
 .../src/Element/WebformElementStates.php      |   14 +-
 .../src/Element/WebformEmailConfirm.php       |   14 +-
 .../src/Element/WebformEntityTrait.php        |    6 +-
 .../src/Element/WebformImageResolution.php    |   20 +-
 .../webform/src/Element/WebformLikert.php     |    4 +-
 .../src/Element/WebformLocationBase.php       |    2 +-
 .../src/Element/WebformManagedFileBase.php    |    2 +-
 .../webform/src/Element/WebformMapping.php    |    8 +-
 .../webform/src/Element/WebformMessage.php    |   22 +-
 .../webform/src/Element/WebformMultiple.php   |   18 +-
 .../webform/src/Element/WebformOtherBase.php  |   17 +-
 .../src/Element/WebformSelectOther.php        |    2 +
 .../webform/src/Element/WebformSignature.php  |    4 +-
 .../src/Element/WebformTermCheckboxes.php     |    2 +-
 .../src/Element/WebformTermReferenceTrait.php |    2 +-
 .../webform/src/Element/WebformTime.php       |    6 +-
 web/modules/webform/src/Entity/Webform.php    |  146 +-
 .../webform/src/Entity/Webform.php.orig       | 3056 --------------
 .../webform/src/Entity/WebformOptions.php     |    6 +-
 .../webform/src/Entity/WebformSubmission.php  |   29 +-
 .../WebformEntitySettingsAccessForm.php       |    2 +-
 .../WebformEntitySettingsBaseForm.php         |    9 +-
 .../WebformEntitySettingsFormForm.php         |   60 +-
 .../WebformEntitySettingsGeneralForm.php      |   97 +-
 .../WebformEntitySettingsSubmissionsForm.php  |    2 +-
 .../WebformDefaultExceptionHtmlSubscriber.php |  325 ++
 .../WebformExceptionHtmlSubscriber.php        |    2 +-
 .../WebformAdminConfigAdvancedForm.php        |    6 +-
 .../WebformAdminConfigElementsForm.php        |    4 +-
 .../WebformAdminConfigExportersForm.php       |    4 +-
 .../WebformAdminConfigFormsForm.php           |   66 +-
 .../WebformAdminConfigLibrariesForm.php       |    2 +-
 .../WebformConfigEntityDeleteFormBase.php     |    8 +-
 .../src/Form/WebformHandlerFormBase.php       |    2 +-
 .../src/Form/WebformResultsCustomForm.php     |    4 +-
 .../src/Form/WebformSubmissionDeleteForm.php  |    4 +-
 .../src/Form/WebformSubmissionResendForm.php  |    2 +-
 .../Form/WebformSubmissionsDeleteFormBase.php |    4 +-
 .../src/Form/WebformVariantFormBase.php       |    4 +-
 .../src/Form/WebformVariantViewForm.php       |   31 +-
 .../Block/WebformSubmissionLimitBlock.php     |   18 +-
 .../webform/src/Plugin/Condition/Webform.php  |    2 +-
 .../WebformSubmissionDevelGenerate.php        |   14 +-
 .../WebformEntityReferenceLinkFormatter.php   |    8 +-
 .../WebformEntityReferenceUrlFormatter.php    |    8 +-
 .../FieldType/WebformEntityReferenceItem.php  |   14 +-
 .../WebformEntityReferenceWidgetTrait.php     |    4 +-
 .../src/Plugin/WebformElement/BooleanBase.php |    2 +-
 .../src/Plugin/WebformElement/Checkboxes.php  |  105 +-
 .../Plugin/WebformElement/ContainerBase.php   |   12 +-
 .../src/Plugin/WebformElement/DateBase.php    |    2 +-
 .../src/Plugin/WebformElement/DateTime.php    |   15 -
 .../src/Plugin/WebformElement/OptionsBase.php |   37 +-
 .../WebformElement/OptionsBase.php.orig       | 1073 -----
 .../Plugin/WebformElement/ProcessedText.php   |    4 +-
 .../src/Plugin/WebformElement/Radios.php      |    2 +-
 .../src/Plugin/WebformElement/Select.php      |    1 +
 .../src/Plugin/WebformElement/Telephone.php   |    4 +-
 .../src/Plugin/WebformElement/TextBase.php    |    8 +-
 .../Plugin/WebformElement/TextBase.php.orig   |  438 --
 .../src/Plugin/WebformElement/TextFormat.php  |    7 +
 .../src/Plugin/WebformElement/View.php        |    7 +-
 .../Plugin/WebformElement/WebformActions.php  |    4 +-
 .../WebformElement/WebformCheckboxesOther.php |   16 +
 .../WebformElement/WebformCompositeBase.php   |   52 +-
 .../WebformElement/WebformComputedBase.php    |    4 +-
 .../WebformElement/WebformDisplayOnTrait.php  |   17 +-
 .../WebformEntityOptionsTrait.php             |   24 +-
 .../WebformEntityReferenceTrait.php           |   23 +-
 .../Plugin/WebformElement/WebformFlexbox.php  |    2 +-
 .../WebformElement/WebformHorizontalRule.php  |    8 +-
 .../WebformElement/WebformImageFile.php       |    4 +-
 .../Plugin/WebformElement/WebformLikert.php   |    6 +-
 .../WebformElement/WebformLocationBase.php    |    6 +-
 .../WebformElement/WebformManagedFileBase.php |   26 +-
 .../Plugin/WebformElement/WebformMapping.php  |    2 +-
 .../WebformElement/WebformMarkupBase.php      |    8 +-
 .../src/Plugin/WebformElement/WebformMore.php |    3 +-
 .../src/Plugin/WebformElement/WebformSame.php |    1 -
 .../Plugin/WebformElement/WebformSection.php  |    1 +
 .../WebformElement/WebformSignature.php       |    2 +-
 .../WebformElement/WebformTermSelect.php      |    3 +-
 .../src/Plugin/WebformElement/WebformTime.php |    4 +-
 .../Plugin/WebformElement/WebformVariant.php  |   16 +-
 .../WebformElement/WebformWizardPage.php      |   12 +-
 .../webform/src/Plugin/WebformElementBase.php |   72 +-
 .../src/Plugin/WebformElementBase.php.orig    | 3700 -----------------
 .../DelimitedWebformExporter.php              |    2 +-
 .../TabularBaseWebformExporter.php            |    4 +-
 .../src/Plugin/WebformExporterBase.php        |   16 +-
 .../src/Plugin/WebformExporterInterface.php   |    2 +-
 .../src/Plugin/WebformExporterManager.php     |    4 +-
 .../WebformHandler/EmailWebformHandler.php    |   52 +-
 .../RemotePostWebformHandler.php              |  176 +-
 .../webform/src/Plugin/WebformHandlerBase.php |    6 +-
 .../src/Plugin/WebformHandlerManager.php      |    4 +-
 .../Plugin/WebformHandlerPluginCollection.php |    2 +-
 .../QueryStringWebformSourceEntity.php        |   25 +
 .../WebformVariant/OverrideWebformVariant.php |   21 +-
 .../src/Plugin/WebformVariantManager.php      |    4 +-
 .../Plugin/WebformVariantPluginCollection.php |    2 +-
 .../src/Routing/WebformRouteSubscriber.php    |   23 +
 .../src/Theme/WebformThemeNegotiator.php      |   55 +-
 .../webform/src/Twig/WebformTwigExtension.php |    2 +-
 .../src/Utility/WebformArrayHelper.php        |    6 +-
 .../src/Utility/WebformElementHelper.php      |   39 +-
 .../webform/src/Utility/WebformFormHelper.php |   24 +
 .../src/Utility/WebformOptionsHelper.php      |    2 +-
 .../src/Utility/WebformReflectionHelper.php   |    4 +-
 .../webform/src/Utility/WebformYaml.php       |    2 +-
 .../webform/src/WebformAddonsManager.php      |   21 +-
 .../src/WebformEntityAccessControlHandler.php |    6 +-
 .../webform/src/WebformEntityAddForm.php      |    4 +-
 .../webform/src/WebformEntityElementsForm.php |   11 +-
 .../src/WebformEntityElementsValidator.php    |   35 +-
 .../webform/src/WebformEntityHandlersForm.php |    2 +-
 .../webform/src/WebformEntityListBuilder.php  |   27 +-
 .../src/WebformEntityReferenceManager.php     |    7 +-
 .../webform/src/WebformEntityStorage.php      |   28 +-
 .../webform/src/WebformEntityVariantsForm.php |   30 +-
 .../webform/src/WebformHelpManager.php        |   23 +-
 web/modules/webform/src/WebformInterface.php  |   19 +-
 .../webform/src/WebformLibrariesManager.php   |   24 +-
 .../webform/src/WebformMessageManager.php     |    6 +-
 .../webform/src/WebformOptionsDeleteForm.php  |    2 +-
 .../webform/src/WebformOptionsForm.php        |    2 +-
 .../webform/src/WebformOptionsListBuilder.php |    2 +-
 web/modules/webform/src/WebformRequest.php    |    5 +-
 .../webform/src/WebformServiceProvider.php    |   11 +
 .../WebformSubmissionConditionsValidator.php  |    6 +-
 ...SubmissionConditionsValidatorInterface.php |    2 +-
 .../webform/src/WebformSubmissionExporter.php |   45 +-
 .../webform/src/WebformSubmissionForm.php     |  120 +-
 .../src/WebformSubmissionInterface.php        |   18 +
 .../src/WebformSubmissionListBuilder.php      |   40 +-
 .../src/WebformSubmissionNotesForm.php        |    2 +-
 .../webform/src/WebformSubmissionStorage.php  |   34 +-
 .../src/WebformSubmissionViewBuilder.php      |    2 +-
 .../webform/src/WebformThemeManager.php       |    5 +-
 .../webform/src/WebformTranslationManager.php |    4 +-
 .../webform-element-audio-file.html.twig      |    2 +-
 .../templates/webform-element-more.html.twig  |    8 +-
 .../webform-element-video-file.html.twig      |    2 +-
 .../webform-handler-action-summary.html.twig  |    1 -
 .../webform-handler-debug-summary.html.twig   |    1 -
 .../webform-handler-email-summary.html.twig   |    1 +
 ...form-handler-remote-post-summary.html.twig |    3 +-
 ...webform-handler-settings-summary.html.twig |    1 -
 .../webform-horizontal-rule.html.twig         |    6 +-
 .../templates/webform-message.html.twig       |    2 +-
 .../templates/webform-progress-bar.html.twig  |   27 +-
 .../webform-progress-tracker.html.twig        |   19 +-
 .../templates/webform-progress.html.twig      |    6 +-
 .../webform-submission-data.html.twig         |   10 +-
 .../webform-submission-information.html.twig  |    1 -
 .../templates/webform-submission.html.twig    |   12 +-
 ...webform-variant-override-summary.html.twig |    1 -
 .../install/webform.webform.test_ajax.yml     |   15 +-
 ....webform.test_ajax_confirmation_inline.yml |   15 +-
 ...webform.test_ajax_confirmation_message.yml |   15 +-
 ...m.webform.test_ajax_confirmation_modal.yml |   15 +-
 ...rm.webform.test_ajax_confirmation_page.yml |   15 +-
 ...orm.webform.test_ajax_confirmation_url.yml |   15 +-
 ...webform.test_ajax_confirmation_url_msg.yml |   15 +-
 .../webform.webform.test_composite.yml        |   15 +-
 .../webform.webform.test_composite_custom.yml |   15 +-
 ...orm.webform.test_composite_custom_file.yml |   56 +-
 .../webform.webform.test_composite_format.yml |   15 +-
 ...webform.test_composite_format_multiple.yml |   15 +-
 ...bform.webform.test_confirmation_inline.yml |   15 +-
 ...form.webform.test_confirmation_message.yml |   15 +-
 ...ebform.webform.test_confirmation_modal.yml |   15 +-
 ...webform.webform.test_confirmation_none.yml |   15 +-
 ...webform.webform.test_confirmation_page.yml |   15 +-
 ....webform.test_confirmation_page_custom.yml |   15 +-
 .../webform.webform.test_confirmation_url.yml |   15 +-
 ....webform.test_confirmation_url_message.yml |   15 +-
 .../install/webform.webform.test_element.yml  |   17 +-
 .../webform.webform.test_element_access.yml   |   15 +-
 .../webform.webform.test_element_actions.yml  |   17 +-
 ...m.webform.test_element_actions_buttons.yml |   15 +-
 .../webform.webform.test_element_address.yml  |   15 +-
 ...form.webform.test_element_allowed_tags.yml |   15 +-
 ...ebform.webform.test_element_attributes.yml |   17 +-
 ...form.webform.test_element_autocomplete.yml |   15 +-
 .../webform.webform.test_element_captcha.yml  |   15 +-
 .../webform.webform.test_element_checkbox.yml |   15 +-
 ...rm.webform.test_element_checkbox_value.yml |   15 +-
 ...ebform.webform.test_element_checkboxes.yml |   29 +-
 ...bform.test_element_checkboxes_all_none.yml |  254 ++
 ...ebform.webform.test_element_codemirror.yml |   13 +-
 ...webform.webform.test_element_composite.yml |   15 +-
 ...webform.test_element_composite_wrapper.yml |   15 +-
 ...orm.webform.test_element_computed_ajax.yml |   21 +-
 ...rm.webform.test_element_computed_debug.yml |   15 +-
 ...rm.webform.test_element_computed_token.yml |   23 +-
 ...orm.webform.test_element_computed_twig.yml |   25 +-
 ...webform.webform.test_element_container.yml |   15 +-
 .../webform.webform.test_element_counter.yml  |   15 +-
 .../webform.webform.test_element_date.yml     |   15 +-
 .../webform.webform.test_element_datelist.yml |   15 +-
 .../webform.webform.test_element_datetime.yml |   17 +-
 ...bform.test_element_description_tooltip.yml |   15 +-
 .../webform.webform.test_element_details.yml  |   15 +-
 .../webform.webform.test_element_disabled.yml |   15 +-
 ...orm.webform.test_element_email_confirm.yml |   15 +-
 ...rm.webform.test_element_email_multiple.yml |   15 +-
 ...bform.test_element_entity_autocomplete.yml |   15 +-
 ....webform.test_element_entity_reference.yml |   15 +-
 ....webform.test_element_excluded_columns.yml |   15 +-
 ...webform.test_element_excluded_elements.yml |   15 +-
 .../webform.webform.test_element_fieldset.yml |   15 +-
 .../webform.webform.test_element_flexbox.yml  |   15 +-
 ...form.webform.test_element_flexbox_flex.yml |   15 +-
 .../webform.webform.test_element_format.yml   |   15 +-
 ...orm.webform.test_element_format_custom.yml |   59 +-
 ...m.webform.test_element_format_multiple.yml |   13 +-
 ...form.webform.test_element_format_token.yml |   31 +-
 .../webform.webform.test_element_help.yml     |   15 +-
 ...form.webform.test_element_help_display.yml |   15 +-
 ...m.webform.test_element_horizontal_rule.yml |   15 +-
 ...bform.webform.test_element_html_editor.yml |   15 +-
 ...bform.webform.test_element_html_escape.yml |   15 +-
 ...bform.webform.test_element_html_markup.yml |   15 +-
 ...ebform.test_element_ignored_properties.yml |   13 +-
 ...ebform.webform.test_element_image_file.yml |   15 +-
 ...webform.test_element_image_file_attach.yml |   15 +-
 ....webform.test_element_image_resolution.yml |   15 +-
 ...ebform.webform.test_element_input_mask.yml |   15 +-
 .../webform.webform.test_element_invalid.yml  |   13 +-
 .../webform.webform.test_element_likert.yml   |   15 +-
 ...ebform.webform.test_element_loc_places.yml |   15 +-
 ...form.webform.test_element_managed_file.yml |   19 +-
 ....webform.test_element_managed_file_dis.yml |   15 +-
 ...webform.test_element_managed_file_help.yml |   15 +-
 ...ebform.test_element_managed_file_limit.yml |   14 +-
 ...webform.test_element_managed_file_name.yml |   15 +-
 ...webform.test_element_managed_file_prev.yml |   15 +-
 .../webform.webform.test_element_mapping.yml  |   15 +-
 .../webform.webform.test_element_markup.yml   |   15 +-
 ...ebform.webform.test_element_media_file.yml |   15 +-
 .../webform.webform.test_element_message.yml  |   15 +-
 .../webform.webform.test_element_more.yml     |   15 +-
 .../webform.webform.test_element_multiple.yml |   15 +-
 ...orm.webform.test_element_multiple_date.yml |   15 +-
 ...webform.test_element_multiple_property.yml |   15 +-
 ...orm.webform.test_element_multiple_text.yml |   15 +-
 .../webform.webform.test_element_options.yml  |   15 +-
 .../webform.webform.test_element_other.yml    |   16 +-
 ...bform.webform.test_element_prepopulate.yml |   14 +-
 .../webform.webform.test_element_private.yml  |   15 +-
 .../webform.webform.test_element_radios.yml   |   29 +-
 .../webform.webform.test_element_range.yml    |   15 +-
 .../webform.webform.test_element_rating.yml   |   15 +-
 .../webform.webform.test_element_readonly.yml |   15 +-
 .../webform.webform.test_element_same.yml     |   15 +-
 .../webform.webform.test_element_scale.yml    |   14 +-
 .../webform.webform.test_element_section.yml  |   15 +-
 .../webform.webform.test_element_select.yml   |   17 +-
 ...webform.webform.test_element_signature.yml |   15 +-
 .../webform.webform.test_element_states.yml   |   15 +-
 ....webform.test_element_submission_views.yml |   15 +-
 ...ebform.test_element_submission_views_r.yml |   15 +-
 ...m.webform.test_element_submitted_value.yml |   15 +-
 .../webform.webform.test_element_table.yml    |   13 +-
 ...webform.test_element_table_select_sort.yml |   15 +-
 ...webform.webform.test_element_telephone.yml |   15 +-
 ...rm.webform.test_element_term_reference.yml |   15 +-
 ....webform.test_element_terms_of_service.yml |   15 +-
 ...bform.webform.test_element_text_format.yml |   15 +-
 .../webform.webform.test_element_time.yml     |   15 +-
 ...orm.webform.test_element_title_display.yml |   15 +-
 ...bform.webform.test_element_users_roles.yml |   15 +-
 ...ebform.test_element_validate_minlength.yml |   15 +-
 ...webform.test_element_validate_multiple.yml |   15 +-
 ....webform.test_element_validate_pattern.yml |   15 +-
 ...webform.test_element_validate_required.yml |   15 +-
 ...m.webform.test_element_validate_unique.yml |   15 +-
 .../webform.webform.test_element_view.yml     |   15 +-
 .../webform.webform.test_example_elements.yml |   15 +-
 ...ebform.test_example_elements_composite.yml |   15 +-
 ...webform.test_exporter_entity_reference.yml |   15 +-
 .../webform.webform.test_exporter_options.yml |   15 +-
 ...ebform.webform.test_form_access_denied.yml |   15 +-
 .../install/webform.webform.test_form_api.yml |   15 +-
 .../webform.webform.test_form_archived.yml    |   15 +-
 .../webform.webform.test_form_assets.yml      |   19 +-
 .../webform.webform.test_form_autofill.yml    |   15 +-
 .../webform.webform.test_form_autofocus.yml   |   15 +-
 .../webform.webform.test_form_closed.yml      |   15 +-
 ...webform.webform.test_form_confidential.yml |   15 +-
 ...bform.webform.test_form_details_toggle.yml |   15 +-
 ...webform.test_form_disable_autocomplete.yml |   15 +-
 ...webform.webform.test_form_disable_back.yml |   15 +-
 ...ebform.test_form_disable_inline_errors.yml |   15 +-
 ...form.webform.test_form_draft_anonymous.yml |   15 +-
 ....webform.test_form_draft_authenticated.yml |   15 +-
 ...bform.webform.test_form_draft_multiple.yml |   15 +-
 ...ebform.webform.test_form_inline_errors.yml |   15 +-
 .../webform.webform.test_form_limit.yml       |   15 +-
 ...m.webform.test_form_limit_total_unique.yml |   15 +-
 ...rm.webform.test_form_limit_user_unique.yml |   15 +-
 .../webform.webform.test_form_limit_wait.yml  |   19 +-
 .../webform.webform.test_form_long_100.yml    |   15 +-
 .../webform.webform.test_form_long_200.yml    |   15 +-
 .../webform.webform.test_form_long_300.yml    |   15 +-
 .../webform.webform.test_form_novalidate.yml  |   15 +-
 .../webform.webform.test_form_opening.yml     |   15 +-
 .../webform.webform.test_form_prepopulate.yml |   15 +-
 .../webform.webform.test_form_preview.yml     |   17 +-
 .../webform.webform.test_form_properties.yml  |   15 +-
 .../webform.webform.test_form_remote_addr.yml |   15 +-
 .../webform.webform.test_form_required.yml    |   15 +-
 .../webform.webform.test_form_reset.yml       |   15 +-
 ...orm.webform.test_form_results_disabled.yml |   15 +-
 .../webform.webform.test_form_submit_back.yml |   15 +-
 .../webform.webform.test_form_submit_once.yml |   15 +-
 .../webform.webform.test_form_submit_text.yml |   15 +-
 .../webform.webform.test_form_template.yml    |   15 +-
 .../webform.webform.test_form_unsaved.yml     |   15 +-
 ...bform.webform.test_form_unsaved_wizard.yml |   15 +-
 .../webform.webform.test_form_validate.yml    |   15 +-
 ...ebform.webform.test_form_wizard_access.yml |   15 +-
 ...form.webform.test_form_wizard_advanced.yml |   15 +-
 ...webform.webform.test_form_wizard_basic.yml |   15 +-
 ...m.webform.test_form_wizard_conditional.yml |   15 +-
 ...ebform.webform.test_form_wizard_custom.yml |   15 +-
 ...webform.webform.test_form_wizard_links.yml |   15 +-
 ...form.webform.test_form_wizard_long_100.yml |   15 +-
 ...form.webform.test_form_wizard_long_200.yml |   15 +-
 ...form.webform.test_form_wizard_long_300.yml |   15 +-
 ...form.webform.test_form_wizard_validate.yml |   15 +-
 ...webform.test_form_wizard_validate_comp.yml |   15 +-
 .../webform.webform.test_handler_action.yml   |   17 +-
 .../webform.webform.test_handler_email.yml    |   15 +-
 ...rm.webform.test_handler_email_advanced.yml |   17 +-
 ...orm.webform.test_handler_email_mapping.yml |   15 +-
 ...bform.webform.test_handler_email_roles.yml |   15 +-
 ...form.webform.test_handler_email_states.yml |   15 +-
 ...ebform.webform.test_handler_email_twig.yml |   17 +-
 .../webform.webform.test_handler_settings.yml |   15 +-
 ...ebform.webform.test_libraries_optional.yml |   17 +-
 .../webform.webform.test_rendering.yml        |   15 +-
 .../install/webform.webform.test_states.yml   |   15 +-
 ...bform.webform.test_states_autocomplete.yml |   15 +-
 .../webform.webform.test_states_crosspage.yml |   15 +-
 .../webform.webform.test_states_disabled.yml  |   15 +-
 ...bform.webform.test_states_server_clear.yml |   15 +-
 ...ebform.webform.test_states_server_comp.yml |   15 +-
 ....webform.test_states_server_containers.yml |   15 +-
 ...form.webform.test_states_server_custom.yml |   15 +-
 ...form.webform.test_states_server_hidden.yml |   15 +-
 ...form.webform.test_states_server_likert.yml |   15 +-
 ...rm.webform.test_states_server_multiple.yml |   15 +-
 ...form.webform.test_states_server_nested.yml |   15 +-
 ...orm.webform.test_states_server_preview.yml |   15 +-
 ...rm.webform.test_states_server_required.yml |   17 +-
 ...ebform.webform.test_states_server_save.yml |   15 +-
 ...form.webform.test_states_server_wizard.yml |   15 +-
 .../webform.webform.test_states_triggers.yml  |   15 +-
 .../webform.webform.test_submission_label.yml |   17 +-
 .../webform.webform.test_submission_log.yml   |   15 +-
 .../webform.webform.test_submission_views.yml |   17 +-
 .../install/webform.webform.test_token.yml    |   21 +-
 ...rm.webform.test_token_submission_value.yml |   13 +-
 ...webform.webform.test_token_view_update.yml |   19 +-
 .../webform.webform.test_variant_multiple.yml |   25 +-
 .../webform.webform.test_variant_override.yml |   33 +-
 ...webform.webform.test_variant_randomize.yml |   19 +-
 .../includes/webform_test.test_cards_long.inc |   33 +
 ...ebform_test.test_element_title_display.inc |    3 +
 .../webform_test.test_example_elements.inc    |    2 +-
 .../webform_test.test_form_states.inc         |    2 +-
 .../webform_test.test_form_wizard_long.inc    |    4 +-
 .../includes/webform_test.test_options.inc    |    4 +-
 .../webform_test/webform_test.info.yml        |   14 +-
 .../modules/webform_test/webform_test.module  |   10 +-
 .../src/Plugin/Block/WebformTestAjaxBlock.php |   16 +-
 .../webform_test_ajax.info.yml                |   14 +-
 .../webform_test_alter_hooks.info.yml         |   14 +-
 .../webform_test_block_context.info.yml       |   14 +-
 .../webform_test_block_custom.info.yml        |   14 +-
 ...bform_test_block_submission_limit.info.yml |   14 +-
 .../webform_test_config_performance.info.yml  |   14 +-
 ....webform.test_element_comp_file_plugin.yml |   15 +-
 ....webform.test_element_composite_plugin.yml |   15 +-
 .../webform.webform.test_element_plugin.yml   |   17 +-
 .../WebformElement/WebformTestElement.php     |    2 +-
 .../webform_test_element.info.yml             |   14 +-
 .../webform_test_element_input_masks.info.yml |   14 +-
 ...bform.test_element_entity_reference_vs.yml |   51 +-
 ...bform_test_entity_reference_views.info.yml |   14 +-
 .../webform_test_exporter.info.yml            |   14 +-
 ...ebform.webform.test_handler_conditions.yml |   15 +-
 .../webform.webform.test_handler_test.yml     |   15 +-
 .../WebformHandler/TestWebformHandler.php     |    2 +-
 .../webform_test_handler.info.yml             |   14 +-
 ...webform_test_handler_invoke_alter.info.yml |   14 +-
 ...ebform.webform.test_handler_remote_get.yml |   33 +-
 ...bform.webform.test_handler_remote_post.yml |   39 +-
 ....webform.test_handler_remote_post_cast.yml |   23 +-
 ....webform.test_handler_remote_post_file.yml |   17 +-
 ...ebform.webform.test_handler_remote_put.yml |   33 +-
 .../WebformTestHandlerRemotePostClient.php    |   18 +-
 .../webform_test_handler_remote_post.info.yml |   14 +-
 .../webform_test_markup.info.yml              |   14 +-
 .../webform_test_markup.module                |    2 +-
 .../webform_test_message_custom.info.yml      |   14 +-
 .../install/webform.webform.test_options.yml  |   15 +-
 .../webform_test_options.info.yml             |   14 +-
 .../webform_test_options.module               |    2 +-
 .../webform_test_paragraphs.info.yml          |   14 +-
 .../webform_test_rest.info.yml                |   14 +-
 .../webform.webform.test_submissions.yml      |   17 +-
 .../webform_test_submissions.info.yml         |   14 +-
 ...webform_test_third_party_settings.info.yml |   14 +-
 .../webform.webform.test_translation.yml      |   15 +-
 .../webform_test_translation.info.yml         |   14 +-
 .../webform_test_translation.install          |    2 +-
 ...webform_test_translation_lingotek.info.yml |   14 +-
 .../webform_test_validate.info.yml            |   14 +-
 .../webform_test_variant.info.yml             |   14 +-
 .../webform_test_views.info.yml               |   14 +-
 .../webform_test_wizard_custom.info.yml       |   14 +-
 .../Access/WebformAccessEntityJsonApiTest.php |    2 +-
 .../WebformAccessEntityPermissionsTest.php    |    6 +-
 .../Access/WebformAccessEntityRestTest.php    |    2 +-
 .../Access/WebformAccessEntityRulesTest.php   |    4 +-
 ...WebformAccessSubmissionPermissionsTest.php |    3 +-
 .../Block/WebformBlockContextTest.php         |    4 +-
 .../src/Functional/Block/WebformBlockTest.php |    8 +-
 .../WebformCompositeCustomFileTest.php        |   12 +-
 .../Composite/WebformCompositeCustomTest.php  |    4 +-
 .../Composite/WebformCompositeFormatTest.php  |   10 +-
 .../WebformCompositePluginFileTest.php        |   10 +-
 .../Composite/WebformCompositePluginTest.php  |    4 +-
 .../Composite/WebformCompositeTest.php        |    8 +-
 .../Element/WebformElementAccessTest.php      |    2 +-
 .../Element/WebformElementActionsTest.php     |   22 +-
 .../Element/WebformElementAddressTest.php     |   11 +-
 .../Element/WebformElementAllowsTagsTest.php  |    2 +-
 .../Element/WebformElementAttributesTest.php  |    4 +-
 .../WebformElementAutocompleteTest.php        |   14 +-
 .../Element/WebformElementCaptchaTest.php     |    2 +-
 .../Element/WebformElementCheckboxTest.php    |    2 +-
 .../WebformElementCheckboxValueTest.php       |    2 +-
 .../Element/WebformElementCheckboxesTest.php  |   12 +-
 .../Element/WebformElementCodeMirrorTest.php  |   16 +-
 .../Element/WebformElementCompositeTest.php   |    9 +-
 .../Element/WebformElementComputedTest.php    |   10 +-
 .../Element/WebformElementCounterTest.php     |    6 +-
 .../Element/WebformElementDateListTest.php    |   14 +-
 .../Element/WebformElementDateTest.php        |   12 +-
 .../Element/WebformElementDateTimeTest.php    |   25 +-
 .../Element/WebformElementDetailsTest.php     |    2 +-
 .../WebformElementEmailConfirmTest.php        |   14 +-
 .../WebformElementEmailMultipleTest.php       |   10 +-
 .../WebformElementEntityAutocompleteTest.php  |    2 +-
 .../WebformElementEntityReferenceTest.php     |    2 +-
 .../WebformElementExcludedColumnsTest.php     |    2 +-
 .../WebformElementExcludedElementsTest.php    |    2 +-
 .../Element/WebformElementFieldsetTest.php    |   16 +-
 .../WebformElementFormatCustomTest.php        |    2 +-
 .../Element/WebformElementFormatTest.php      |   24 +-
 .../Element/WebformElementHelpTest.php        |    2 +-
 .../WebformElementHorizontalRuleTest.php      |    2 +-
 .../Element/WebformElementHtmlEditorTest.php  |   25 +-
 .../WebformElementIgnoredPropertiesTest.php   |    7 +-
 .../WebformElementImageResolutionTest.php     |    6 +-
 .../Element/WebformElementInputMaskTest.php   |    2 +-
 .../Element/WebformElementLikertTest.php      |    6 +-
 .../WebformElementLocationPlacesTest.php      |    2 +-
 .../WebformElementManagedFileImageTest.php    |    2 +-
 .../WebformElementManagedFileLimitTest.php    |    6 +-
 .../WebformElementManagedFilePreviewTest.php  |    2 +-
 .../WebformElementManagedFilePrivateTest.php  |    4 +-
 .../WebformElementManagedFilePublicTest.php   |    6 +-
 .../Element/WebformElementManagedFileTest.php |   42 +-
 .../WebformElementManagedFileTestBase.php     |    2 +-
 .../Element/WebformElementMappingTest.php     |    8 +-
 .../Element/WebformElementMarkupTest.php      |    4 +-
 .../Element/WebformElementMediaFileTest.php   |   28 +-
 .../Element/WebformElementMessageTest.php     |    2 +-
 .../Element/WebformElementMoreTest.php        |    9 +-
 .../WebformElementMultiplePropertyTest.php    |    4 +-
 .../Element/WebformElementMultipleTest.php    |    6 +-
 .../Element/WebformElementOptionsTest.php     |    8 +-
 .../Element/WebformElementOtherTest.php       |   58 +-
 .../WebformElementPluginDefinitionsTest.php   |  178 +-
 .../WebformElementPluginPropertiesTest.php    |  774 ++--
 .../Element/WebformElementPluginTest.php      |    6 +-
 .../Element/WebformElementPrepopulateTest.php |   14 +-
 .../Element/WebformElementPrivateTest.php     |    2 +-
 .../Element/WebformElementRadiosTest.php      |   10 +-
 .../Element/WebformElementRangeTest.php       |    4 +-
 .../Element/WebformElementRatingTest.php      |    6 +-
 .../Element/WebformElementReadonlyTest.php    |    2 +-
 .../Element/WebformElementSameTest.php        |    2 +-
 .../Element/WebformElementScaleTest.php       |    4 +-
 .../Element/WebformElementSectionTest.php     |    2 +-
 .../Element/WebformElementSelectTest.php      |    2 +-
 .../Element/WebformElementSignatureTest.php   |   20 +-
 .../WebformElementStatesSelectorsTest.php     |    6 +-
 .../Element/WebformElementStatesTest.php      |    8 +-
 ...bformElementSubmissionViewsReplaceTest.php |    6 +-
 .../WebformElementSubmissionViewsTest.php     |   16 +-
 .../WebformElementSubmittedValueTest.php      |    2 +-
 .../WebformElementTableSelectSortTest.php     |    6 +-
 .../Element/WebformElementTableTest.php       |   10 +-
 .../Element/WebformElementTelephoneTest.php   |   20 +-
 .../WebformElementTermReferenceTest.php       |    8 +-
 .../WebformElementTermsOfServiceTest.php      |    6 +-
 .../Functional/Element/WebformElementTest.php |    4 +-
 .../Element/WebformElementTextFormatTest.php  |   18 +-
 .../Element/WebformElementTimeTest.php        |   16 +-
 .../WebformElementValidateMinlengthTest.php   |    2 +-
 .../WebformElementValidateMultipleTest.php    |    4 +-
 .../WebformElementValidatePatternTest.php     |    6 +-
 .../WebformElementValidateRequiredTest.php    |    4 +-
 .../WebformElementValidateUniqueTest.php      |    6 +-
 .../Element/WebformElementViewTest.php        |   10 +-
 .../Exporter/WebformExporterExcludedTest.php  |    2 +-
 .../Exporter/WebformExporterOptionsTest.php   |    2 +-
 .../Form/WebformFormPropertiesTest.php        |    4 +-
 .../Form/WebformFormValidateTest.php          |    2 +-
 .../Handler/WebformHandlerActionTest.php      |   16 +-
 .../Handler/WebformHandlerConditionsTest.php  |    2 +-
 .../WebformHandlerEmailAdvancedTest.php       |   44 +-
 .../Handler/WebformHandlerEmailBasicTest.php  |   38 +-
 .../WebformHandlerEmailMappingTest.php        |    2 +-
 .../WebformHandlerEmailRenderingTest.php      |   30 +-
 .../Handler/WebformHandlerEmailRolesTest.php  |    2 +-
 .../Handler/WebformHandlerEmailStatesTest.php |   12 +-
 .../Handler/WebformHandlerEmailTwigTest.php   |    2 +-
 .../Handler/WebformHandlerExcludedTest.php    |    4 +-
 .../WebformHandlerInvokeAlterHookTest.php     |    2 +-
 .../Handler/WebformHandlerPluginTest.php      |    2 +-
 .../Handler/WebformHandlerRemotePostTest.php  |   57 +-
 .../Handler/WebformHandlerSettingsTest.php    |   14 +-
 .../Functional/Handler/WebformHandlerTest.php |   30 +-
 .../WebformSettingsAccessDeniedTest.php       |    4 +-
 .../Settings/WebformSettingsAdminTest.php     |   14 +-
 .../Settings/WebformSettingsAjaxTest.php      |    2 +-
 .../Settings/WebformSettingsArchivedTest.php  |    2 +-
 .../Settings/WebformSettingsAssetsTest.php    |    2 +-
 .../Settings/WebformSettingsAutofillTest.php  |    2 +-
 .../Settings/WebformSettingsBehaviorsTest.php |   28 +-
 .../WebformSettingsConfidentialTest.php       |    6 +-
 .../WebformSettingsConfirmationTest.php       |   16 +-
 .../Settings/WebformSettingsDraftTest.php     |   34 +-
 .../Settings/WebformSettingsFormTitleTest.php |    2 +-
 .../WebformSettingsLimitUniqueTest.php        |    2 +-
 .../Settings/WebformSettingsLimitsTest.php    |    6 +-
 .../Settings/WebformSettingsPathTest.php      |   32 +-
 .../WebformSettingsPrepopulateTest.php        |   12 +-
 .../Settings/WebformSettingsPreviewTest.php   |   18 +-
 .../Settings/WebformSettingsPreviousTest.php  |    2 +-
 .../WebformSettingsRemoteAddrTest.php         |   10 +-
 .../Settings/WebformSettingsScheduleTest.php  |    2 +-
 .../Settings/WebformSettingsSerialTest.php    |    6 +-
 .../Settings/WebformSettingsStatusTest.php    |    2 +-
 .../States/WebformStatesHiddenTest.php        |    6 +-
 .../States/WebformStatesPreviewTest.php       |   12 +-
 .../States/WebformStatesServerTest.php        |   14 +-
 .../States/WebformStatesWizardTest.php        |   10 +-
 .../Token/WebformTokenSubmissionValueTest.php |    4 +-
 .../Token/WebformTokenSuffixesTest.php        |    2 +-
 .../Token/WebformTokenValidateTest.php        |    6 +-
 .../Variant/WebformVariantApplyTest.php       |   10 +-
 .../Variant/WebformVariantElementTest.php     |    6 +-
 .../Variant/WebformVariantExcludedTest.php    |    2 +-
 .../Variant/WebformVariantOperationsTest.php  |    2 +-
 .../Variant/WebformVariantOverrideTest.php    |    6 +-
 .../Variant/WebformVariantPluginTest.php      |    2 +-
 .../Variant/WebformVariantRandomizeTest.php   |    2 +-
 .../Views/WebformViewsBulkFormTest.php        |   12 +-
 .../src/Functional/WebformAlterHooksTest.php  |    2 +-
 .../src/Functional/WebformBlockCacheTest.php  |    5 +-
 .../src/Functional/WebformBrowserTestBase.php |   12 +-
 .../Functional/WebformBrowserTestBaseTest.php |    2 +-
 .../src/Functional/WebformEditorTest.php      |   24 +-
 .../Functional/WebformEmailProviderTest.php   |    4 +-
 ...bformEntityReferenceItemNormalizerTest.php |    2 +-
 .../Functional/WebformEntityStorageTest.php   |    4 +-
 .../src/Functional/WebformEntityTest.php      |    8 +-
 .../WebformEntityTranslationTest.php          |   16 +-
 .../WebformExampleFunctionalTest.php          |    4 +-
 .../tests/src/Functional/WebformHelpTest.php  |    6 +-
 .../src/Functional/WebformLibrariesTest.php   |   70 +-
 .../src/Functional/WebformListBuilderTest.php |    6 +-
 .../tests/src/Functional/WebformMailTest.php  |    4 +-
 .../src/Functional/WebformOptionsTest.php     |    4 +-
 .../src/Functional/WebformRenderingTest.php   |   28 +-
 .../Functional/WebformResultsDisabledTest.php |    4 +-
 .../WebformResultsExportDownloadTest.php      |   16 +-
 .../WebformResultsExportOptionsTest.php       |   16 +-
 .../Functional/WebformSubmissionApiTest.php   |    4 +-
 .../WebformSubmissionGenerateTest.php         |    2 +-
 ...formSubmissionListBuilderCustomizeTest.php |   16 +-
 .../WebformSubmissionListBuilderTest.php      |   10 +-
 .../WebformSubmissionStorageTest.php          |    6 +-
 .../src/Functional/WebformSubmissionTest.php  |    6 +-
 .../WebformSubmissionTokenUpdateTest.php      |    2 +-
 .../Functional/WebformSubmissionViewTest.php  |    4 +-
 .../WebformSubmissionViewsAccessTest.php      |    3 +-
 .../Functional/WebformSubmissionViewsTest.php |    6 +-
 .../WebformThirdPartySettingsTest.php         |   35 +-
 .../Wizard/WebformWizardAccessTest.php        |   12 +-
 .../Wizard/WebformWizardAdvancedTest.php      |   73 +-
 .../Wizard/WebformWizardBasicTest.php         |   22 +-
 .../Wizard/WebformWizardConditionalTest.php   |   27 +-
 .../Wizard/WebformWizardCustomTest.php        |   14 +-
 .../Wizard/WebformWizardLinksTest.php         |   18 +-
 .../Wizard/WebformWizardTestBase.php          |    4 +-
 .../Wizard/WebformWizardValidateTest.php      |   22 +-
 ...WebformElementCheckboxesJavaScriptTest.php |   84 +
 .../WebformSettingsAjaxJavaScriptTest.php     |   20 +-
 .../WebformStatesCustomJavaScriptTest.php     |    2 +-
 .../WebformWebDriverTestBase.php              |   12 +-
 .../WebformWizardBasicJavaScriptTest.php      |    4 +-
 .../WebformBreadcrumbBuilderTest.php          |   27 +-
 .../src/Kernel/Entity/WebformEntityTest.php   |   53 +-
 .../Entity/WebformSubmissionEntityTest.php    |    2 +-
 .../tests/src/Kernel/WebformConditionTest.php |    2 +-
 .../WebformEntityElementsValidationTest.php   |   11 +
 .../Kernel/WebformSubmissionStorageTest.php   |   11 +-
 .../src/Traits/WebformAssertLegacyTrait.php   |    4 +-
 .../src/Traits/WebformBrowserTestTrait.php    |   30 +-
 .../Access/WebformSubmissionAccessTest.php    |    4 +-
 .../Unit/Utility/WebformElementHelperTest.php |   24 +-
 .../src/Unit/Utility/WebformYamlTest.php      |   62 +
 .../src/Unit/WebformMessageManagerTest.php    |    2 +-
 .../webform_test_bartik.info.yml              |   14 +-
 .../third_party_settings/webform.antibot.inc  |    5 +-
 .../third_party_settings/webform.honeypot.inc |   30 +-
 .../third_party_settings/webform.maillog.inc  |    2 +-
 web/modules/webform/webform.info.yml          |    8 +-
 web/modules/webform/webform.libraries.yml     |   22 +-
 web/modules/webform/webform.module            |   77 +-
 web/modules/webform/webform.routing.yml       |   11 +
 web/modules/webform/webform.services.yml      |    1 +
 web/modules/webform/webform.tokens.inc        |   14 +-
 1065 files changed, 18857 insertions(+), 12529 deletions(-)
 create mode 100644 web/modules/webform/modules/webform_bootstrap/src/WebformBootstrapRenderCallbacks.php
 create mode 100644 web/modules/webform/modules/webform_cards/css/webform_cards.admin.css
 create mode 100644 web/modules/webform/modules/webform_cards/css/webform_cards.css
 create mode 100644 web/modules/webform/modules/webform_cards/js/webform_cards.admin.js
 create mode 100644 web/modules/webform/modules/webform_cards/js/webform_cards.js
 create mode 100644 web/modules/webform/modules/webform_cards/src/Element/WebformCard.php
 create mode 100644 web/modules/webform/modules/webform_cards/src/Form/WebformCardsConvertForm.php
 create mode 100644 web/modules/webform/modules/webform_cards/src/Plugin/WebformElement/WebformCard.php
 create mode 100644 web/modules/webform/modules/webform_cards/src/Routing/WebformCardsRouteSubscriber.php
 create mode 100644 web/modules/webform/modules/webform_cards/src/WebformCardsManager.php
 create mode 100644 web/modules/webform/modules/webform_cards/src/WebformCardsManagerInterface.php
 create mode 100644 web/modules/webform/modules/webform_cards/templates/webform-card.html.twig
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_access.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_ajax.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_auto_forward.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_draft.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_long_100.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress_custom.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress_links.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_states.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_titles.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_toggle.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_validation_errors.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/templates/webform-progress--test-cards-progress-custom.html.twig
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/webform_cards_test.info.yml
 create mode 100644 web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/webform_cards_test.module
 create mode 100644 web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsAjaxJavaScriptTest.php
 create mode 100644 web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsAutoForwardJavaScriptTest.php
 create mode 100644 web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsDraftJavaScriptTest.php
 create mode 100644 web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsProgressJavaScriptTest.php
 create mode 100644 web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsStatesJavaScriptTest.php
 create mode 100644 web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsToggleJavaScriptTest.php
 create mode 100644 web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsUiJavaScriptTest.php
 create mode 100644 web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsValidationJavaScriptTest.php
 create mode 100644 web/modules/webform/modules/webform_cards/webform_cards.info.yml
 create mode 100644 web/modules/webform/modules/webform_cards/webform_cards.libraries.yml
 create mode 100644 web/modules/webform/modules/webform_cards/webform_cards.links.action.yml
 create mode 100644 web/modules/webform/modules/webform_cards/webform_cards.module
 create mode 100644 web/modules/webform/modules/webform_cards/webform_cards.routing.yml
 create mode 100644 web/modules/webform/modules/webform_cards/webform_cards.services.yml
 create mode 100644 web/modules/webform/modules/webform_clientside_validation/css/webform_clientside_validation.ife.css
 create mode 100644 web/modules/webform/modules/webform_clientside_validation/js/webform_clientside_validation.ife.js
 create mode 100644 web/modules/webform/modules/webform_clientside_validation/js/webform_clientside_validation.novalidate.js
 create mode 100644 web/modules/webform/modules/webform_clientside_validation/tests/modules/webform_clientside_validation_test/config/install/webform.webform.test_clientside_validation.yml
 create mode 100644 web/modules/webform/modules/webform_clientside_validation/tests/modules/webform_clientside_validation_test/webform_clientside_validation_test.info.yml
 create mode 100644 web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.info.yml
 create mode 100644 web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.install
 create mode 100644 web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.libraries.yml
 create mode 100644 web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.module
 create mode 100644 web/modules/webform/modules/webform_examples/config/optional/webform.webform.example_cards.yml
 create mode 100644 web/modules/webform/modules/webform_share/css/webform_share.admin.css
 create mode 100644 web/modules/webform/modules/webform_share/css/webform_share.page.css
 create mode 100644 web/modules/webform/modules/webform_share/js/webform_share.admin.js
 create mode 100644 web/modules/webform/modules/webform_share/src/Access/WebformShareAccess.php
 create mode 100644 web/modules/webform/modules/webform_share/src/Controller/WebformShareController.php
 create mode 100644 web/modules/webform/modules/webform_share/src/Element/WebformShareIframe.php
 create mode 100644 web/modules/webform/modules/webform_share/src/Element/WebformShareScript.php
 create mode 100644 web/modules/webform/modules/webform_share/src/EventSubscriber/WebformShareEventSubscriber.php
 create mode 100644 web/modules/webform/modules/webform_share/src/Form/WebformShareEmbedForm.php
 create mode 100644 web/modules/webform/modules/webform_share/src/Routing/WebformShareRouteSubscriber.php
 create mode 100644 web/modules/webform/modules/webform_share/src/Theme/WebformShareThemeNegotiator.php
 create mode 100644 web/modules/webform/modules/webform_share/src/WebformShareHelper.php
 create mode 100644 web/modules/webform/modules/webform_share/src/WebformSharePreRender.php
 create mode 100644 web/modules/webform/modules/webform_share/templates/html--webform-share.html.twig
 create mode 100644 web/modules/webform/modules/webform_share/templates/page--webform-share.html.twig
 create mode 100644 web/modules/webform/modules/webform_share/templates/webform-share-iframe.html.twig
 create mode 100644 web/modules/webform/modules/webform_share/templates/webform-share-script.html.twig
 create mode 100644 web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareNodeTest.php
 create mode 100644 web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareTest.php
 create mode 100644 web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareVariantTest.php
 create mode 100644 web/modules/webform/modules/webform_share/webform_share.info.yml
 create mode 100644 web/modules/webform/modules/webform_share/webform_share.libraries.yml
 create mode 100644 web/modules/webform/modules/webform_share/webform_share.links.task.yml
 create mode 100644 web/modules/webform/modules/webform_share/webform_share.module
 create mode 100644 web/modules/webform/modules/webform_share/webform_share.routing.yml
 create mode 100644 web/modules/webform/modules/webform_share/webform_share.services.yml
 delete mode 100644 web/modules/webform/src/Entity/Webform.php.orig
 create mode 100644 web/modules/webform/src/EventSubscriber/WebformDefaultExceptionHtmlSubscriber.php
 delete mode 100644 web/modules/webform/src/Plugin/WebformElement/OptionsBase.php.orig
 delete mode 100644 web/modules/webform/src/Plugin/WebformElement/TextBase.php.orig
 delete mode 100644 web/modules/webform/src/Plugin/WebformElementBase.php.orig
 create mode 100644 web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes_all_none.yml
 create mode 100644 web/modules/webform/tests/modules/webform_test/includes/webform_test.test_cards_long.inc
 create mode 100644 web/modules/webform/tests/src/FunctionalJavascript/Element/WebformElementCheckboxesJavaScriptTest.php

diff --git a/composer.json b/composer.json
index 1dd54db9eb..a5471669fa 100644
--- a/composer.json
+++ b/composer.json
@@ -182,7 +182,7 @@
         "drupal/views_fieldsets": "3.3",
         "drupal/views_infinite_scroll": "1.7",
         "drupal/views_slideshow": "4.4",
-        "drupal/webform": "5.12",
+        "drupal/webform": "5.18",
         "drupal/webform_views": "5.0-alpha2",
         "drush-ops/behat-drush-endpoint": "0.0.5",
         "drush/drush": "9.7.1",
@@ -308,4 +308,4 @@
             "php": "7.3"
         }
     }
-}
\ No newline at end of file
+}
diff --git a/composer.lock b/composer.lock
index 9aff2845f4..3da4ffbf94 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "4061d56ed0fe7f80e7e5e4a47a2ae8c5",
+    "content-hash": "0290f48585651afd49810fed60842ffe",
     "packages": [
         {
             "name": "alchemy/zippy",
@@ -8470,50 +8470,57 @@
         },
         {
             "name": "drupal/webform",
-            "version": "5.12.0",
+            "version": "5.18.0",
             "source": {
                 "type": "git",
                 "url": "https://git.drupalcode.org/project/webform.git",
-                "reference": "8.x-5.12"
+                "reference": "8.x-5.18"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://ftp.drupal.org/files/projects/webform-8.x-5.12.zip",
-                "reference": "8.x-5.12",
-                "shasum": "5ad813c6c622993f24078db9c47e81e598c954ba"
+                "url": "https://ftp.drupal.org/files/projects/webform-8.x-5.18.zip",
+                "reference": "8.x-5.18",
+                "shasum": "539d0ba5bacc402cf6ea2a3419ae164703a09aa0"
             },
             "require": {
-                "drupal/core": "^8.7.7 || ^9"
+                "drupal/core": "^8.8"
             },
             "require-dev": {
-                "drupal/address": "~1.4",
+                "drupal/address": "~1.0",
                 "drupal/bootstrap": "~3.0",
                 "drupal/captcha": "~1.0",
-                "drupal/chosen": "~2.6",
-                "drupal/devel": "*",
-                "drupal/entity_print": "^2.1",
+                "drupal/chosen": "~2.0",
+                "drupal/clientside_validation": "~3.0",
+                "drupal/clientside_validation_jquery": "*",
+                "drupal/devel": "~3.0",
+                "drupal/entity_print": "~2.0",
                 "drupal/gnode": "*",
                 "drupal/group": "~1.0",
-                "drupal/mailsystem": "~4.1",
-                "drupal/select2": "~1.1",
+                "drupal/lingotek": "~3.0",
+                "drupal/mailsystem": "~4.0",
+                "drupal/paragraphs": "~1.0",
+                "drupal/select2": "~1.0",
                 "drupal/smtp": "~1.0",
-                "drupal/telephone_validation": "^2.2",
-                "drupal/token": "~1.3",
+                "drupal/styleguide": "~1.0",
+                "drupal/telephone_validation": "~2.0",
+                "drupal/token": "~1.0",
                 "drupal/webform_access": "*",
                 "drupal/webform_attachment": "*",
+                "drupal/webform_clientside_validation": "*",
                 "drupal/webform_devel": "*",
                 "drupal/webform_entity_print": "*",
                 "drupal/webform_group": "*",
                 "drupal/webform_node": "*",
                 "drupal/webform_options_limit": "*",
                 "drupal/webform_scheduled_email": "*",
+                "drupal/webform_share": "*",
                 "drupal/webform_ui": "*"
             },
             "type": "drupal-module",
             "extra": {
                 "drupal": {
-                    "version": "8.x-5.12",
-                    "datestamp": "1589389825",
+                    "version": "8.x-5.18",
+                    "datestamp": "1593034084",
                     "security-coverage": {
                         "status": "covered",
                         "message": "Covered by Drupal's security advisory policy"
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index 34351e0277..3f00c38653 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -8735,51 +8735,58 @@
     },
     {
         "name": "drupal/webform",
-        "version": "5.12.0",
-        "version_normalized": "5.12.0.0",
+        "version": "5.18.0",
+        "version_normalized": "5.18.0.0",
         "source": {
             "type": "git",
             "url": "https://git.drupalcode.org/project/webform.git",
-            "reference": "8.x-5.12"
+            "reference": "8.x-5.18"
         },
         "dist": {
             "type": "zip",
-            "url": "https://ftp.drupal.org/files/projects/webform-8.x-5.12.zip",
-            "reference": "8.x-5.12",
-            "shasum": "5ad813c6c622993f24078db9c47e81e598c954ba"
+            "url": "https://ftp.drupal.org/files/projects/webform-8.x-5.18.zip",
+            "reference": "8.x-5.18",
+            "shasum": "539d0ba5bacc402cf6ea2a3419ae164703a09aa0"
         },
         "require": {
-            "drupal/core": "^8.7.7 || ^9"
+            "drupal/core": "^8.8"
         },
         "require-dev": {
-            "drupal/address": "~1.4",
+            "drupal/address": "~1.0",
             "drupal/bootstrap": "~3.0",
             "drupal/captcha": "~1.0",
-            "drupal/chosen": "~2.6",
-            "drupal/devel": "*",
-            "drupal/entity_print": "^2.1",
+            "drupal/chosen": "~2.0",
+            "drupal/clientside_validation": "~3.0",
+            "drupal/clientside_validation_jquery": "*",
+            "drupal/devel": "~3.0",
+            "drupal/entity_print": "~2.0",
             "drupal/gnode": "*",
             "drupal/group": "~1.0",
-            "drupal/mailsystem": "~4.1",
-            "drupal/select2": "~1.1",
+            "drupal/lingotek": "~3.0",
+            "drupal/mailsystem": "~4.0",
+            "drupal/paragraphs": "~1.0",
+            "drupal/select2": "~1.0",
             "drupal/smtp": "~1.0",
-            "drupal/telephone_validation": "^2.2",
-            "drupal/token": "~1.3",
+            "drupal/styleguide": "~1.0",
+            "drupal/telephone_validation": "~2.0",
+            "drupal/token": "~1.0",
             "drupal/webform_access": "*",
             "drupal/webform_attachment": "*",
+            "drupal/webform_clientside_validation": "*",
             "drupal/webform_devel": "*",
             "drupal/webform_entity_print": "*",
             "drupal/webform_group": "*",
             "drupal/webform_node": "*",
             "drupal/webform_options_limit": "*",
             "drupal/webform_scheduled_email": "*",
+            "drupal/webform_share": "*",
             "drupal/webform_ui": "*"
         },
         "type": "drupal-module",
         "extra": {
             "drupal": {
-                "version": "8.x-5.12",
-                "datestamp": "1589389825",
+                "version": "8.x-5.18",
+                "datestamp": "1593034084",
                 "security-coverage": {
                     "status": "covered",
                     "message": "Covered by Drupal's security advisory policy"
diff --git a/web/modules/webform/.gitignore b/web/modules/webform/.gitignore
index 15e10416dd..b8f0401a70 100644
--- a/web/modules/webform/.gitignore
+++ b/web/modules/webform/.gitignore
@@ -1,6 +1,7 @@
 *.patch
 interdiff-*.txt
 
+
 # Ignore the HTML and reports directory used for generate Webform documentation.
 /html
 /reports/accessiblity/html
diff --git a/web/modules/webform/composer.json b/web/modules/webform/composer.json
index 1b7cef09ee..4182ce3c85 100644
--- a/web/modules/webform/composer.json
+++ b/web/modules/webform/composer.json
@@ -17,9 +17,9 @@
       "role": "Co-maintainer"
     },
     {
-        "name": "Contributors",
-        "homepage": "https://www.drupal.org/node/7404/committers",
-        "role": "Contributor"
+      "name": "Contributors",
+      "homepage": "https://www.drupal.org/node/7404/committers",
+      "role": "Contributor"
     }
   ],
   "support": {
@@ -35,17 +35,25 @@
       }
     }
   },
+  "require": {
+    "drupal/core": "^8.8"
+  },
   "require-dev": {
-    "drupal/address": "~1.4",
+    "drupal/address": "~1.0",
     "drupal/bootstrap": "~3.0",
     "drupal/captcha": "~1.0",
-    "drupal/chosen": "~2.6",
-    "drupal/entity_print": "^2.1",
+    "drupal/chosen": "~2.0",
+    "drupal/clientside_validation": "~3.0",
+    "drupal/devel": "~3.0",
+    "drupal/entity_print": "~2.0",
     "drupal/group": "~1.0",
-    "drupal/mailsystem": "~4.1",
-    "drupal/select2": "~1.1",
+    "drupal/lingotek": "~3.0",
+    "drupal/mailsystem": "~4.0",
+    "drupal/paragraphs": "~1.0",
+    "drupal/select2": "~1.0",
     "drupal/smtp": "~1.0",
-    "drupal/telephone_validation": "^2.2",
-    "drupal/token": "~1.3"
+    "drupal/styleguide": "~1.0",
+    "drupal/telephone_validation": "~2.0",
+    "drupal/token": "~1.0"
   }
 }
diff --git a/web/modules/webform/composer.libraries.json b/web/modules/webform/composer.libraries.json
index 48cbc97ef7..0f2d2d2e01 100644
--- a/web/modules/webform/composer.libraries.json
+++ b/web/modules/webform/composer.libraries.json
@@ -33,13 +33,13 @@
             "type": "package",
             "package": {
                 "name": "algolia/places",
-                "version": "1.17.1",
+                "version": "1.18.2",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "algolia.places"
                 },
                 "dist": {
-                    "url": "https://registry.npmjs.org/places.js/-/places.js-1.17.1.tgz",
+                    "url": "https://registry.npmjs.org/places.js/-/places.js-1.18.2.tgz",
                     "type": "tar"
                 },
                 "require": {
@@ -159,13 +159,13 @@
             "type": "package",
             "package": {
                 "name": "codemirror/codemirror",
-                "version": "5.51.0",
+                "version": "5.53.2",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "codemirror"
                 },
                 "dist": {
-                    "url": "https://github.com/components/codemirror/archive/5.51.0.zip",
+                    "url": "https://github.com/components/codemirror/archive/5.53.2.zip",
                     "type": "zip"
                 },
                 "require": {
@@ -249,13 +249,13 @@
             "type": "package",
             "package": {
                 "name": "jquery/image-picker",
-                "version": "0.3.0",
+                "version": "0.3.1",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "jquery.image-picker"
                 },
                 "dist": {
-                    "url": "https://github.com/rvera/image-picker/archive/0.3.0.zip",
+                    "url": "https://github.com/rvera/image-picker/archive/0.3.1.zip",
                     "type": "zip"
                 },
                 "require": {
@@ -321,13 +321,13 @@
             "type": "package",
             "package": {
                 "name": "jquery/select2",
-                "version": "4.0.12",
+                "version": "4.0.13",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "jquery.select2"
                 },
                 "dist": {
-                    "url": "https://github.com/select2/select2/archive/4.0.12.zip",
+                    "url": "https://github.com/select2/select2/archive/4.0.13.zip",
                     "type": "zip"
                 },
                 "require": {
@@ -339,13 +339,13 @@
             "type": "package",
             "package": {
                 "name": "jquery/textcounter",
-                "version": "0.8.0",
+                "version": "0.9.0",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "jquery.textcounter"
                 },
                 "dist": {
-                    "url": "https://github.com/ractoon/jQuery-Text-Counter/archive/0.8.0.zip",
+                    "url": "https://github.com/ractoon/jQuery-Text-Counter/archive/0.9.0.zip",
                     "type": "zip"
                 },
                 "require": {
@@ -357,13 +357,13 @@
             "type": "package",
             "package": {
                 "name": "jquery/timepicker",
-                "version": "1.13.0",
+                "version": "1.13.10",
                 "type": "drupal-library",
                 "extra": {
                     "installer-name": "jquery.timepicker"
                 },
                 "dist": {
-                    "url": "https://github.com/jonthornton/jquery-timepicker/archive/1.13.0.zip",
+                    "url": "https://github.com/jonthornton/jquery-timepicker/archive/1.13.10.zip",
                     "type": "zip"
                 },
                 "require": {
diff --git a/web/modules/webform/config/install/webform.settings.yml b/web/modules/webform/config/install/webform.settings.yml
index e7cb9d3610..3099bf59a4 100644
--- a/web/modules/webform/config/install/webform.settings.yml
+++ b/web/modules/webform/config/install/webform.settings.yml
@@ -30,10 +30,12 @@ settings:
     messages messages--status
 
   button_classes: ''
-  default_wizard_prev_button_label: '< Previous Page'
-  default_wizard_next_button_label: 'Next Page >'
+  default_wizard_prev_button_label: '< Previous'
+  default_wizard_next_button_label: 'Next >'
   default_wizard_start_label: Start
   default_wizard_confirmation_label: Complete
+  default_wizard_toggle_show_label: 'Show all'
+  default_wizard_toggle_hide_label: 'Hide all'
   default_preview_next_button_label: Preview
   default_preview_prev_button_label: '< Previous'
   default_preview_label: Preview
@@ -83,6 +85,9 @@ settings:
 
   default_limit_total_message: 'No more submissions are permitted.'
   default_limit_user_message: 'No more submissions are permitted.'
+  default_share: false
+  default_share_node: false
+  default_share_theme_name: ''
   dialog: false
   dialog_options:
     narrow:
diff --git a/web/modules/webform/config/install/webform.webform.contact.yml b/web/modules/webform/config/install/webform.webform.contact.yml
index c580c0bbe3..1937fa7376 100644
--- a/web/modules/webform/config/install/webform.webform.contact.yml
+++ b/web/modules/webform/config/install/webform.webform.contact.yml
@@ -39,7 +39,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send message'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -51,7 +51,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -81,6 +81,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -106,11 +111,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/config/optional/views.view.webform_submissions.yml b/web/modules/webform/config/optional/views.view.webform_submissions.yml
index 27283e5b57..74c8331a8c 100644
--- a/web/modules/webform/config/optional/views.view.webform_submissions.yml
+++ b/web/modules/webform/config/optional/views.view.webform_submissions.yml
@@ -14,7 +14,6 @@ description: 'Default webform submissions views.'
 tag: ''
 base_table: webform_submission
 base_field: sid
-core: 8.x
 display:
   default:
     display_plugin: default
@@ -1395,6 +1394,8 @@ display:
               authenticated: authenticated
               anonymous: '0'
               administrator: '0'
+            operator_limit_selection: false
+            operator_list: {  }
           is_grouped: false
           group_info:
             label: ''
@@ -1435,6 +1436,8 @@ display:
               authenticated: authenticated
               anonymous: '0'
               administrator: '0'
+            operator_limit_selection: false
+            operator_list: {  }
           is_grouped: false
           group_info:
             label: ''
@@ -1476,6 +1479,8 @@ display:
               anonymous: '0'
               administrator: '0'
               demo_region: '0'
+            operator_limit_selection: false
+            operator_list: {  }
           is_grouped: false
           group_info:
             label: ''
@@ -2280,6 +2285,8 @@ display:
               authenticated: authenticated
               anonymous: '0'
               administrator: '0'
+            operator_limit_selection: false
+            operator_list: {  }
           is_grouped: false
           group_info:
             label: ''
@@ -2320,6 +2327,8 @@ display:
               authenticated: authenticated
               anonymous: '0'
               administrator: '0'
+            operator_limit_selection: false
+            operator_list: {  }
           is_grouped: false
           group_info:
             label: ''
@@ -2361,6 +2370,8 @@ display:
               anonymous: '0'
               administrator: '0'
               demo_region: '0'
+            operator_limit_selection: false
+            operator_list: {  }
           is_grouped: false
           group_info:
             label: ''
@@ -3055,6 +3066,8 @@ display:
               authenticated: authenticated
               anonymous: '0'
               administrator: '0'
+            operator_limit_selection: false
+            operator_list: {  }
           is_grouped: false
           group_info:
             label: ''
@@ -3095,6 +3108,8 @@ display:
               authenticated: authenticated
               anonymous: '0'
               administrator: '0'
+            operator_limit_selection: false
+            operator_list: {  }
           is_grouped: false
           group_info:
             label: ''
@@ -3136,6 +3151,8 @@ display:
               anonymous: '0'
               administrator: '0'
               demo_region: '0'
+            operator_limit_selection: false
+            operator_list: {  }
           is_grouped: false
           group_info:
             label: ''
diff --git a/web/modules/webform/config/schema/webform.entity.webform.schema.yml b/web/modules/webform/config/schema/webform.entity.webform.schema.yml
index e0a5a701ba..8636b747a4 100644
--- a/web/modules/webform/config/schema/webform.entity.webform.schema.yml
+++ b/web/modules/webform/config/schema/webform.entity.webform.schema.yml
@@ -72,9 +72,9 @@
         page_confirm_path:
           type: string
           label: 'Page confirm URL alias'
-        page_admin_theme:
-          type: boolean
-          label: 'Use admin theme for page'
+        page_theme_name:
+          type: string
+          label: 'Page theme'
         form_title:
           type: string
           label: 'Form title display'
@@ -162,6 +162,21 @@
         form_file_limit:
           type: string
           label: 'Form file upload limit'
+        share:
+          type: boolean
+          label: 'Enable form sharing'
+        share_node:
+          type: boolean
+          label: 'Enable form sharing for webform nodes'
+        share_theme_name:
+          type: string
+          label: 'Shared form theme'
+        share_title:
+          type: boolean
+          label: 'Display shared form title'
+        share_page_body_attributes:
+          type: ignore
+          label: 'Shared form page attributes'
         submission_label:
           type: label
           label: 'Default submission label'
@@ -302,9 +317,27 @@
         wizard_confirmation_label:
           type: label
           label: 'Wizard confirmation label'
+        wizard_auto_forward:
+          type: boolean
+          label: 'Auto-forward to next page when the page is completed'
         wizard_track:
           type: text
           label: 'Track wizard progress in the URL'
+        wizard_prev_button_label:
+          type: label
+          label: 'Wizard previous page button label'
+        wizard_next_button_label:
+          type: label
+          label: 'Wizard next page button label'
+        wizard_toggle:
+          type: boolean
+          label: 'Display show/hide all elements link'
+        wizard_toggle_show_label:
+          type: label
+          label: 'Default wizard show all elements label'
+        wizard_toggle_hide_label:
+          type: label
+          label: 'Default wizard hide all elements label'
         preview:
           type: integer
           label: 'Enable preview page'
diff --git a/web/modules/webform/config/schema/webform.settings.schema.yml b/web/modules/webform/config/schema/webform.settings.schema.yml
index 95495ba7fa..75fd5aa691 100644
--- a/web/modules/webform/config/schema/webform.settings.schema.yml
+++ b/web/modules/webform/config/schema/webform.settings.schema.yml
@@ -87,6 +87,12 @@ webform.settings:
         default_wizard_confirmation_label:
           type: label
           label: 'Default wizard confirmation label'
+        default_wizard_toggle_show_label:
+          type: label
+          label: 'Default wizard show all elements label'
+        default_wizard_toggle_hide_label:
+          type: label
+          label: 'Default wizard hide all elements label'
         default_preview_next_button_label:
           type: label
           label: 'Default preview button label'
@@ -224,6 +230,15 @@ webform.settings:
         confirmation_back_classes:
           type: string
           label: 'Confirmation back link CSS classes'
+        default_share:
+          type: boolean
+          label: 'Enable form sharing'
+        default_share_node:
+          type: boolean
+          label: 'Enable form sharing for webform nodes'
+        default_share_theme_name:
+          type: string
+          label: 'Default shared form theme'
         dialog:
           type: boolean
           label: 'Enable webform dialog support'
diff --git a/web/modules/webform/css/webform.addons.css b/web/modules/webform/css/webform.addons.css
index 36b3ece186..3f236ee006 100644
--- a/web/modules/webform/css/webform.addons.css
+++ b/web/modules/webform/css/webform.addons.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Addons styles
+ * Addons styles.
  */
 
 .webform-addons-summary {
diff --git a/web/modules/webform/css/webform.admin.css b/web/modules/webform/css/webform.admin.css
index 6e7bf701ea..be4c63fba2 100644
--- a/web/modules/webform/css/webform.admin.css
+++ b/web/modules/webform/css/webform.admin.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Admin styles
+ * Admin styles.
  */
 
 /**
diff --git a/web/modules/webform/css/webform.admin.settings.css b/web/modules/webform/css/webform.admin.settings.css
index 4af9a04066..6437e8a727 100644
--- a/web/modules/webform/css/webform.admin.settings.css
+++ b/web/modules/webform/css/webform.admin.settings.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Admin settings styles
+ * Admin settings styles.
  */
 
 /**
diff --git a/web/modules/webform/css/webform.ajax.css b/web/modules/webform/css/webform.ajax.css
index 88413c4513..539398806c 100644
--- a/web/modules/webform/css/webform.ajax.css
+++ b/web/modules/webform/css/webform.ajax.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Ajax styles
+ * Ajax styles.
  */
 
 /**
diff --git a/web/modules/webform/css/webform.composite.css b/web/modules/webform/css/webform.composite.css
index 550c2d5594..23c385a6f0 100644
--- a/web/modules/webform/css/webform.composite.css
+++ b/web/modules/webform/css/webform.composite.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Composite element styles.
+ * Composite styles.
  */
 
 /**
diff --git a/web/modules/webform/css/webform.composite.telephone.css b/web/modules/webform/css/webform.composite.telephone.css
index 7e69dae775..7ca5c33ad6 100644
--- a/web/modules/webform/css/webform.composite.telephone.css
+++ b/web/modules/webform/css/webform.composite.telephone.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Composite telephone element styles.
+ * Telephone composite styles.
  */
 
 .form-type-webform-telephone:after {
diff --git a/web/modules/webform/css/webform.element.choices.css b/web/modules/webform/css/webform.element.choices.css
index fac8b80bfe..bda7e7366e 100644
--- a/web/modules/webform/css/webform.element.choices.css
+++ b/web/modules/webform/css/webform.element.choices.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Choices styles.
+ * Choices element styles.
  */
 
 .choices {
diff --git a/web/modules/webform/css/webform.element.codemirror.css b/web/modules/webform/css/webform.element.codemirror.css
index dbf36f39e7..8b4c0b29c5 100644
--- a/web/modules/webform/css/webform.element.codemirror.css
+++ b/web/modules/webform/css/webform.element.codemirror.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * CodeMirror styles.
+ * CodeMirror element styles.
  *
  * @see /webform/test_element_codemirror/test
  */
diff --git a/web/modules/webform/css/webform.element.color.css b/web/modules/webform/css/webform.element.color.css
index f5b85eea23..a279ecd3ad 100644
--- a/web/modules/webform/css/webform.element.color.css
+++ b/web/modules/webform/css/webform.element.color.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element color styles
+ * Color element styles.
  *
  * @see \Drupal\webform\Plugin\WebformElement\Color
  * @see webform-element-color-value-swatch.html.twig
diff --git a/web/modules/webform/css/webform.element.composite.css b/web/modules/webform/css/webform.element.composite.css
index d1147f9f6b..23c76eae9e 100644
--- a/web/modules/webform/css/webform.element.composite.css
+++ b/web/modules/webform/css/webform.element.composite.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element composite (builder) styles.
+ * Composite (builder) element styles.
  */
 
 .form-type-webform-element-composite table tr .form-item {
diff --git a/web/modules/webform/css/webform.element.computed.css b/web/modules/webform/css/webform.element.computed.css
index 92a37b4d74..a2402f60a8 100644
--- a/web/modules/webform/css/webform.element.computed.css
+++ b/web/modules/webform/css/webform.element.computed.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element computed styles.
+ * Computed element styles.
  */
 
 .webform-computed-loading {
diff --git a/web/modules/webform/css/webform.element.counter.css b/web/modules/webform/css/webform.element.counter.css
index 684e64d654..87026b5948 100644
--- a/web/modules/webform/css/webform.element.counter.css
+++ b/web/modules/webform/css/webform.element.counter.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element counter styles.
+ * Counter element styles.
  */
 
 input.webform-counter-warning,
diff --git a/web/modules/webform/css/webform.element.date.css b/web/modules/webform/css/webform.element.date.css
index c0b7031dae..0e9dad28ca 100644
--- a/web/modules/webform/css/webform.element.date.css
+++ b/web/modules/webform/css/webform.element.date.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element date styles.
+ * Date element styles.
  */
 
 .ui-datepicker-trigger {
diff --git a/web/modules/webform/css/webform.element.datelist.css b/web/modules/webform/css/webform.element.datelist.css
index 8381b151a5..b14aeeb9c9 100644
--- a/web/modules/webform/css/webform.element.datelist.css
+++ b/web/modules/webform/css/webform.element.datelist.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element datelist styles.
+ * Datelist element styles.
  */
 
 .form-type-datelist input[type="text"] {
diff --git a/web/modules/webform/css/webform.element.details.toggle.css b/web/modules/webform/css/webform.element.details.toggle.css
index 87a030a29e..891230979b 100644
--- a/web/modules/webform/css/webform.element.details.toggle.css
+++ b/web/modules/webform/css/webform.element.details.toggle.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element details toggle all styles.
+ * Details toggle element styles.
  *
  * @see /webform/test_form_details_toggle
  */
diff --git a/web/modules/webform/css/webform.element.file.button.css b/web/modules/webform/css/webform.element.file.button.css
index f04958751a..b0337d3bb5 100644
--- a/web/modules/webform/css/webform.element.file.button.css
+++ b/web/modules/webform/css/webform.element.file.button.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * File upload button styles.
+ * File upload button element styles.
  *
  * @see https://stackoverflow.com/questions/21842274/cross-browser-custom-styling-for-file-upload-button
  */
diff --git a/web/modules/webform/css/webform.element.flexbox.css b/web/modules/webform/css/webform.element.flexbox.css
index 4024ae3602..74dee04dfe 100644
--- a/web/modules/webform/css/webform.element.flexbox.css
+++ b/web/modules/webform/css/webform.element.flexbox.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Flexbox styles.
+ * Flexbox element styles.
  *
  * @see /webform/example_layout_flexbox
  * @see /webform/test_element_flexbox_flex
diff --git a/web/modules/webform/css/webform.element.help.css b/web/modules/webform/css/webform.element.help.css
index 91fb0a62ed..02b00f4890 100644
--- a/web/modules/webform/css/webform.element.help.css
+++ b/web/modules/webform/css/webform.element.help.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element help styles.
+ * Help element styles.
  */
 
 .webform-element-help {
diff --git a/web/modules/webform/css/webform.element.horizontal_rule.css b/web/modules/webform/css/webform.element.horizontal_rule.css
index 24aea2a8f0..f892eb86bc 100644
--- a/web/modules/webform/css/webform.element.horizontal_rule.css
+++ b/web/modules/webform/css/webform.element.horizontal_rule.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element horizontal rule styles.
+ * Horizontal rule element styles.
  *
  * @see https://css-tricks.com/examples/hrs/
  */
diff --git a/web/modules/webform/css/webform.element.html_editor.css b/web/modules/webform/css/webform.element.html_editor.css
index 8f2ec95583..82aeb8e3b9 100644
--- a/web/modules/webform/css/webform.element.html_editor.css
+++ b/web/modules/webform/css/webform.element.html_editor.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * HTML editor styles.
+ * HTML editor element styles.
  *
  * @see /webform/test_element_html_editor
  */
diff --git a/web/modules/webform/css/webform.element.image_file.css b/web/modules/webform/css/webform.element.image_file.css
index fcbe0d2f0e..e23b7db21a 100644
--- a/web/modules/webform/css/webform.element.image_file.css
+++ b/web/modules/webform/css/webform.element.image_file.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Image file styles.
+ * Image file element styles.
  *
  * @see /webform/test_element_media_file
  */
diff --git a/web/modules/webform/css/webform.element.managed_file.css b/web/modules/webform/css/webform.element.managed_file.css
index 58bbf10696..c85793b089 100644
--- a/web/modules/webform/css/webform.element.managed_file.css
+++ b/web/modules/webform/css/webform.element.managed_file.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Managed file styles.
+ * Managed file element styles.
  */
 
 .webform-managed-file-preview-wrapper + input[type="submit"],
diff --git a/web/modules/webform/css/webform.element.mapping.css b/web/modules/webform/css/webform.element.mapping.css
index 71f60b6958..6b105fa5b1 100644
--- a/web/modules/webform/css/webform.element.mapping.css
+++ b/web/modules/webform/css/webform.element.mapping.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element mapping styles.
+ * Mapping element styles.
  */
 
 .webform-mapping-table th {
diff --git a/web/modules/webform/css/webform.element.message.css b/web/modules/webform/css/webform.element.message.css
index 59af43edd3..05205dd31d 100644
--- a/web/modules/webform/css/webform.element.message.css
+++ b/web/modules/webform/css/webform.element.message.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Messages element styles.
+ * Message element styles.
  *
  * @see /webform/test_element_message
  */
diff --git a/web/modules/webform/css/webform.element.more.css b/web/modules/webform/css/webform.element.more.css
index 42d59d2bb5..6eac1d6c4e 100644
--- a/web/modules/webform/css/webform.element.more.css
+++ b/web/modules/webform/css/webform.element.more.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element more styles.
+ * More element styles.
  */
 
 .webform-element-more--link {
diff --git a/web/modules/webform/css/webform.element.options.css b/web/modules/webform/css/webform.element.options.css
index 3a6278ae87..da0f535174 100644
--- a/web/modules/webform/css/webform.element.options.css
+++ b/web/modules/webform/css/webform.element.options.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element options display styles.
+ * Options element styles.
  *
  * @see /webform/example_layout_basic
  */
@@ -102,6 +102,26 @@
   border-color: #ccc;
 }
 
+/**
+ * Horizontal.
+ */
+.webform-options-display-buttons-horizontal .webform-options-display-buttons-wrapper {
+  flex: none;
+}
+
+/**
+ * Vertical.
+ */
+.webform-options-display-buttons-vertical,
+.form-composite.webform-fieldset--title-inline .fieldset-wrapper > div.webform-options-display-buttons-vertical {
+  flex-direction: column;
+}
+
+.webform-options-display-buttons-vertical .webform-options-display-buttons-wrapper {
+  flex: 1;
+  margin: 0 5px 0 5px;
+}
+
 /**
  * Mobile support to webform options buttons on mobile devices.
  */
diff --git a/web/modules/webform/css/webform.element.range.css b/web/modules/webform/css/webform.element.range.css
index f354b483b1..a44aa6fd7e 100644
--- a/web/modules/webform/css/webform.element.range.css
+++ b/web/modules/webform/css/webform.element.range.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element range styles.
+ * Range element styles.
  *
  * @see http://thenewcode.com/754/input-Antipode-The-HTML5-output-Element
  */
diff --git a/web/modules/webform/css/webform.element.rating.css b/web/modules/webform/css/webform.element.rating.css
index c34277c230..49720d0b95 100644
--- a/web/modules/webform/css/webform.element.rating.css
+++ b/web/modules/webform/css/webform.element.rating.css
@@ -3,8 +3,18 @@
  * Rating element styles.
  */
 
-html.js .form-webform-rating {
-  display: none;
+/**
+ * Visually hide the rating input.
+ */
+html.js .form-webform-rating,
+html.js .form-webform-rating[style*="display: none"] {
+  display: inline !important;
+  position: absolute !important;
+  overflow: hidden;
+  clip: rect(1px, 1px, 1px, 1px);
+  width: 1px;
+  height: 1px;
+  word-wrap: normal;
 }
 
 div.svg div.rateit-range {
diff --git a/web/modules/webform/css/webform.element.scale.css b/web/modules/webform/css/webform.element.scale.css
index 521401e70e..45f46d344a 100644
--- a/web/modules/webform/css/webform.element.scale.css
+++ b/web/modules/webform/css/webform.element.scale.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Element scale styles.
+ * Scale element styles.
  */
 
 .webform-scale {
diff --git a/web/modules/webform/css/webform.element.select2.css b/web/modules/webform/css/webform.element.select2.css
index e9ec3ec347..c570fae05c 100644
--- a/web/modules/webform/css/webform.element.select2.css
+++ b/web/modules/webform/css/webform.element.select2.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Select2 styles.
+ * Select2 element styles.
  */
 
 /*
diff --git a/web/modules/webform/css/webform.element.text_format.css b/web/modules/webform/css/webform.element.text_format.css
index d6bf3ed3b1..4b270c3b98 100644
--- a/web/modules/webform/css/webform.element.text_format.css
+++ b/web/modules/webform/css/webform.element.text_format.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Text form element styles.
+ * Text format element styles.
  */
 
 /**
diff --git a/web/modules/webform/css/webform.element.video_file.css b/web/modules/webform/css/webform.element.video_file.css
index ea34d87d2e..3c5184205c 100644
--- a/web/modules/webform/css/webform.element.video_file.css
+++ b/web/modules/webform/css/webform.element.video_file.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Video file styles.
+ * Video file element styles.
  *
  * @see /webform/test_element_media_file
  */
diff --git a/web/modules/webform/css/webform.filter.css b/web/modules/webform/css/webform.filter.css
index 67fac6da41..81af640092 100644
--- a/web/modules/webform/css/webform.filter.css
+++ b/web/modules/webform/css/webform.filter.css
@@ -1,6 +1,7 @@
 /**
  * @file
- * Filter styles
+ * Filter styles.
+ *
  * @see /admin/structure/webform
  * @see /admin/structure/webform/templates
  */
diff --git a/web/modules/webform/css/webform.form.css b/web/modules/webform/css/webform.form.css
index b947e96491..10a27400e5 100644
--- a/web/modules/webform/css/webform.form.css
+++ b/web/modules/webform/css/webform.form.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Webform styles.
+ * Webform form styles.
  */
 
 /**
diff --git a/web/modules/webform/css/webform.progress.tracker.css b/web/modules/webform/css/webform.progress.tracker.css
index 41eadcf0f5..35916063c6 100644
--- a/web/modules/webform/css/webform.progress.tracker.css
+++ b/web/modules/webform/css/webform.progress.tracker.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Wizard progress tracker styles.
+ * Progress tracker styles.
  *
  * @see http://nigelotoole.github.io/progress-tracker/
  */
@@ -19,11 +19,11 @@
 .webform-progress-tracker .progress-step .progress-text {
   padding-top: 5px;
   padding-bottom: 0;
-  color: #656565;
+  color: #777;
 }
 
 .webform-progress-tracker .progress-step::after {
-  background-color: #656565;
+  background-color: #777;
 }
 
 .webform-progress-tracker .progress-step.is-active .progress-text {
@@ -38,18 +38,18 @@
   color: #333;
 }
 
-/**
- * Disable hover state because webform wizard progress markers are not clickable.
- */
-.webform-progress-tracker .progress-step:not(.is-active) .progress-marker,
+.webform-progress-tracker .progress-step .progress-marker,
 .webform-progress-tracker .progress-step:hover .progress-marker {
-  background-color: #656565;
+  background-color: #777;
 }
 
-.webform-progress-tracker .progress-step.is-complete:hover .progress-marker {
-  background-color: #1976f2;
+.webform-progress-tracker .progress-step.is-complete .progress-marker,
+.webform-progress-tracker .progress-step.is-complete:hover .progress-marker,
+.webform-progress-tracker .progress-step.is-complete::after {
+  background-color: #333;
 }
 
+.webform-progress-tracker .progress-step.is-active .progress-marker,
 .webform-progress-tracker .progress-step.is-active:hover .progress-marker {
   background-color: #2196f3;
 }
@@ -72,6 +72,27 @@
   }
 }
 
+/**
+  * Progress link styles.
+ */
+.webform-progress-tracker [role="link"] {
+  cursor: pointer;
+}
+
+.webform-progress-tracker .progress-title[role="link"] {
+  color: #1976d2;
+}
+
+.webform-progress-tracker .progress-title[role="link"]:hover,
+.webform-progress-tracker .progress-title[role="link"]:focus {
+  text-decoration: underline;
+  color: #2196f3;
+}
+
+.webform-progress-tracker .progress-step.is-complete:hover .progress-marker[role="link"] {
+  background-color: #1976f2;
+}
+
 /**
  * RTL support.
  *
diff --git a/web/modules/webform/css/webform.theme.claro.css b/web/modules/webform/css/webform.theme.claro.css
index 6a43ac5d32..69f562c7ad 100644
--- a/web/modules/webform/css/webform.theme.claro.css
+++ b/web/modules/webform/css/webform.theme.claro.css
@@ -35,13 +35,6 @@
 /* Messages */
 /*****************************************************************************   */
 
-.messages.messages--webform a.button {
-  margin: 0;
-  text-decoration: none;
-  color: #fff;
-  background-color: #003cc5;
-}
-
 html.js .webform-message--close .webform-message__link {
   opacity: inherit;
   color: #ffd23f;
@@ -56,6 +49,16 @@ html.js .webform-message--close .webform-message__link:active {
   color: #fff;
 }
 
+/**
+ * Fix button link and background color.
+ */
+.webform-message a.button {
+  margin: 0;
+  text-decoration: none;
+  color: #fff;
+  background-color: #003cc5;
+}
+
 /**
  * Fix webform promotion message link color.
  *
diff --git a/web/modules/webform/css/webform.token.css b/web/modules/webform/css/webform.token.css
index 69e2f674cc..02e2c6e767 100644
--- a/web/modules/webform/css/webform.token.css
+++ b/web/modules/webform/css/webform.token.css
@@ -1,6 +1,6 @@
 /**
  * @file
- * Token (admin) styles
+ * Token (admin) styles.
  */
 
 tr[data-tt-id^="token-webform"] td {
diff --git a/web/modules/webform/css/webform.wizard.pages.css b/web/modules/webform/css/webform.wizard.pages.css
index f36409e076..ee6a144e43 100644
--- a/web/modules/webform/css/webform.wizard.pages.css
+++ b/web/modules/webform/css/webform.wizard.pages.css
@@ -7,23 +7,6 @@
   display: none;
 }
 
-/**
-  * Progress link styles.
- */
-.webform-progress [role="link"] {
-  cursor: pointer;
-}
-
-.webform-progress .progress-title[role="link"] {
-  color: #1976d2;
-}
-
-.webform-progress .progress-title[role="link"]:hover,
-.webform-progress .progress-title[role="link"]:focus {
-  text-decoration: underline;
-  color: #2196f3;
-}
-
 /**
   * Preview link styles.
  */
diff --git a/web/modules/webform/docs/DEVELOPMENT-CHEATSHEET.md b/web/modules/webform/docs/DEVELOPMENT-CHEATSHEET.md
index 4d49574dcf..7a1b09a6e5 100644
--- a/web/modules/webform/docs/DEVELOPMENT-CHEATSHEET.md
+++ b/web/modules/webform/docs/DEVELOPMENT-CHEATSHEET.md
@@ -16,7 +16,7 @@ git diff 8.x-5.x > [project_name]-[issue-description]-[issue-number]-00.patch
 curl https://www.drupal.org/files/issues/[project_name]-[issue-description]-[issue-number]-00.patch | git apply -
 
 # Force apply patch
-patch -p1 < 3037968-2.patch	
+patch -p1 < 3037968-2.patch
 
 # Remove patch and untracked files
 git reset --hard; git clean -f -d
@@ -28,6 +28,13 @@ interdiff \
   > interdiff-[issue-number]-[old-comment-number]-[new-comment-number].txt
 cat interdiff-[issue-number]-[old-comment-number]-[new-comment-number].txt
 
+# Commit remove patch
+git checkout 8.x-5.x
+curl https://www.drupal.org/files/issues/[project_name]-[issue-description]-[issue-number]-00.patch | git apply -
+git add .
+git commit -m 'Issue #[issue-number]: [issue-description]'
+git push
+
 # Merge branch with all commits
 git checkout 8.x-5.x
 git merge [issue-number]-[issue-description]
@@ -70,6 +77,10 @@ echo 'true' > webform.features.yml
 echo 'true' > modules/webform_attachment/webform_attachment.features.yml
 echo 'true' > modules/webform_attachment/tests/modules/webform_attachment_test/webform_attachment_test.features.yml
 
+echo 'true' > modules/webform_cards/tests/modules/webform_cards_test/webform_cards_test.features.yml
+
+echo 'true' > modules/webform_clientside_validationtests/modules/webform_clientside_validation_test/webform_clientside_validation_test.features.yml
+
 echo 'true' > modules/webform_entity_print/webform_entity_print.features.yml
 echo 'true' > modules/webform_entity_print/tests/modules/webform_entity_print_test/webform_entity_print_test.features.yml
 echo 'true' > modules/webform_entity_print_attachment/webform_entity_print_attachment.features.yml
@@ -165,7 +176,7 @@ drush en -y webform\
   webform_templates\
   webform_test\
   webform_test_element\
-  webform_test_entity_reference_views\  
+  webform_test_entity_reference_views\
   webform_test_handler\
   webform_test_handler_remote_post\
   webform_test_options\
@@ -175,8 +186,9 @@ drush en -y webform\
   webform_test_translation\
   webform_test_views\
   webform_attachment_test\
-  webform_entity_print_test\  
-  webform_entity_print_attachment_test\  
+  webform_clientside_validation_test\
+  webform_entity_print_test\
+  webform_entity_print_attachment_test\
   webform_icheck_test\
   webform_image_select_test\
   webform_location_geocomplete_test\
@@ -230,6 +242,7 @@ drush features-export -y webform_test_translation
 drush features-export -y webform_test_views
 drush features-export -y webform_test_paragraphs
 drush features-export -y webform_attachment_test
+drush features-export -y webform_clientside_validation_test
 drush features-export -y webform_entity_print_test
 drush features-export -y webform_entity_print_attachment_test
 drush features-export -y webform_icheck_test
@@ -284,6 +297,8 @@ drush webform:tidy -y --dependencies webform_test_submissions
 drush webform:tidy -y --dependencies webform_test_translation
 drush webform:tidy -y --dependencies webform_test_views
 drush webform:tidy -y --dependencies webform_attachment_test
+drush webform:tidy -y --dependencies webform_cards_test
+drush webform:tidy -y --dependencies webform_clientside_validation_test
 drush webform:tidy -y --dependencies webform_entity_print_test
 drush webform:tidy -y --dependencies webform_entity_print_attachment_test
 drush webform:tidy -y --dependencies webform_image_select_test
@@ -335,6 +350,8 @@ drush features-import -y webform_test_submissions
 drush features-import -y webform_test_translation
 drush features-import -y webform_test_views
 drush features-import -y webform_attachment_test
+drush features-import -y webform_cards_test
+drush features-import -y webform_clientside_validation_test
 drush features-import -y webform_entity_print_test
 drush features-import -y webform_entity_print_attachment_test
 drush features-import -y webform_image_select_test
diff --git a/web/modules/webform/docs/RELEASE-NOTES.md b/web/modules/webform/docs/RELEASE-NOTES.md
index 33c48b2ecc..ddcb26a6ca 100644
--- a/web/modules/webform/docs/RELEASE-NOTES.md
+++ b/web/modules/webform/docs/RELEASE-NOTES.md
@@ -205,6 +205,8 @@ References
 
 [Tag a release](https://www.drupal.org/node/1066342)
 
+    git checkout 8.x-5.x
+    git up
     git tag 8.x-5.0-VERSION
     git push --tags
     git push origin tag 8.x-5.0-VERSION
diff --git a/web/modules/webform/drupalci.yml b/web/modules/webform/drupalci.yml
index baf7c31e6c..4ffd949ca4 100644
--- a/web/modules/webform/drupalci.yml
+++ b/web/modules/webform/drupalci.yml
@@ -1,19 +1,57 @@
+# This is the DrupalCI testbot build file for Drupal core.
+# Learn to make one for your own drupal.org project:
+# @see https://www.drupal.org/drupalorg/docs/drupal-ci/customizing-drupalci-testing
+# @see https://git.drupalcode.org/project/drupal/blob/HEAD/core/drupalci.yml
 build:
   assessment:
     validate_codebase:
       phplint:
-      container_composer:
       csslint:
+        halt-on-fail: false
       eslint:
+        # A test must pass eslinting standards check in order to continue processing.
+        halt-on-fail: false
       phpcs:
+        # phpcs will use core's specified version of Coder.
+        sniff-all-files: false
+        halt-on-fail: false
     testing:
-      run_tests.standard:
-        types: 'Simpletest,PHPUnit-Unit,PHPUnit-Kernel,PHPUnit-Functional'
-        # Test for Drupal 9 compatibility
+      # run_tests task is executed several times in order of performance speeds.
+      # halt-on-fail can be set on the run_tests tasks in order to fail fast.
+      # suppress-deprecations is false in order to be alerted to usages of
+      # deprecated code.
+      run_tests.phpunit:
+        types: 'PHPUnit-Unit'
+        testgroups: '--all'
         suppress-deprecations: true
-      run_tests.js:
-        concurrency: 3
+        halt-on-fail: false
+      run_tests.kernel:
+        types: 'PHPUnit-Kernel'
+        testgroups: '--all'
+        suppress-deprecations: true
+        halt-on-fail: false
+      run_tests.simpletest:
+         types: 'Simpletest'
+         testgroups: '--all'
+         suppress-deprecations: true
+         halt-on-fail: false
+      run_tests.build:
+        types: 'PHPUnit-Build'
+        testgroups: '--all'
+        suppress-deprecations: true
+        halt-on-fail: false
+      run_tests.functional:
+        types: 'PHPUnit-Functional'
+        testgroups: '--all'
+        suppress-deprecations: true
+        halt-on-fail: false
+      run_tests.javascript:
+        concurrency: 15
         types: 'PHPUnit-FunctionalJavascript'
-        # Test for Drupal 9 compatibility
+        testgroups: '--all'
         suppress-deprecations: true
-      nightwatchjs:
+        halt-on-fail: false
+      # Run nightwatch testing.
+      # @see https://www.drupal.org/project/drupal/issues/2869825
+      # @see https://www.drupal.org/drupalorg/docs/drupal-ci/customizing-drupalci-testing-for-projects#s-disabling-plugins
+      # nightwatchjs:
diff --git a/web/modules/webform/includes/webform.form_alter.inc b/web/modules/webform/includes/webform.form_alter.inc
index 493549b0eb..ba976dd317 100644
--- a/web/modules/webform/includes/webform.form_alter.inc
+++ b/web/modules/webform/includes/webform.form_alter.inc
@@ -40,7 +40,7 @@ function webform_form_alter(&$form, FormStateInterface $form_state, $form_id) {
 
     // If current webform is translated, load the base (default) webform and apply
     // the translation to the elements.
-    if ($webform->getLangcode() != $language_manager->getCurrentLanguage()->getId()) {
+    if ($webform->getLangcode() !== $language_manager->getCurrentLanguage()->getId()) {
       $original_language = $language_manager->getLanguage($webform->getLangcode());
       $form['langcode_message'] = [
         '#type' => 'webform_message',
@@ -88,7 +88,7 @@ function _webform_form_webform_submission_form_after_build($form, FormStateInter
 /******************************************************************************/
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for update manager update form.
  *
  * Add warnings when attempting to update the Webform module using
  * the 'Update manager'.
@@ -136,7 +136,7 @@ function webform_form_update_manager_update_form_alter(&$form, FormStateInterfac
 /******************************************************************************/
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for views exposed form.
  */
 function webform_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {
   /** @var \Drupal\views\ViewExecutable $view */
@@ -154,7 +154,7 @@ function webform_form_views_exposed_form_alter(&$form, FormStateInterface $form_
 /******************************************************************************/
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for SMTP admin settings form.
  */
 function webform_form_smtp_admin_settings_alter(&$form, FormStateInterface $form_state) {
   $form['#submit'][] = '_webform_form_smtp_admin_settings_submit';
@@ -175,7 +175,7 @@ function _webform_form_smtp_admin_settings_submit(&$form, FormStateInterface $fo
 /******************************************************************************/
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for config single import form.
  */
 function webform_form_config_single_import_form_alter(&$form, FormStateInterface $form_state) {
   $config_type = \Drupal::request()->query->get('config_type');
diff --git a/web/modules/webform/includes/webform.install.inc b/web/modules/webform/includes/webform.install.inc
index 01354f8b38..4a93e2690e 100644
--- a/web/modules/webform/includes/webform.install.inc
+++ b/web/modules/webform/includes/webform.install.inc
@@ -136,7 +136,7 @@ function _webform_update_webform_setting(array $data) {
     $settings[$name] = $value;
   }
   // Set settings.
-  $data['settings'] = $settings;
+  $data['settings'] = _webform_update_webform_setting_settings($settings);
 
   // Set access.
   /** @var \Drupal\webform\WebformAccessRulesManagerInterface $access_rules_manager */
@@ -146,6 +146,30 @@ function _webform_update_webform_setting(array $data) {
   return $data;
 }
 
+/**
+ * Make sure outdated webform settings are up-to-date.
+ *
+ * @param array $settings
+ *   An associative array of webform settings.
+ *
+ * @return array
+ *   Updated webform settings.
+ */
+function _webform_update_webform_setting_settings(array $settings) {
+  // Issue #3153184: Allow a webform displayed as a page to have a custom theme.
+  // Convert 'page_admin_theme' setting to 'page_theme_name' setting.
+  // @see webform_update_8196()
+  if (isset($settings['page_admin_theme'])) {
+    if (empty($settings['page_theme_name'])) {
+      $settings['page_theme_name'] = ($settings['page_admin_theme'])
+        ? \Drupal::configFactory()->get('system.theme')->get('admin')
+        : '';
+    }
+    unset($settings['page_admin_theme']);
+  }
+  return $settings;
+}
+
 /**
  * Update webform handler settings to reflect changes in a handler's default configuration.
  *
@@ -188,7 +212,7 @@ function _webform_update_webform_handler_settings() {
           $settings[$settings_key] = $setting_value;
         }
 
-        if ($handler['settings'] != $settings) {
+        if ($handler['settings'] !== $settings) {
           $has_handler = TRUE;
           $handler['settings'] = $settings;
         }
@@ -247,7 +271,7 @@ function _webform_update_options_settings() {
  * Update or install any new system.actions.* config entities.
  */
 function _webform_update_actions() {
-  $files = file_scan_directory(drupal_get_path('module', 'webform') . '/config', '/^system.action..*\.yml$/');
+  $files = \Drupal::service('file_system')->scanDirectory(drupal_get_path('module', 'webform') . '/config', '/^system.action..*\.yml$/');
   foreach ($files as $path => $file) {
     $action_id = str_replace('system.action.', '', $file->name);
     $action = Action::load($action_id);
diff --git a/web/modules/webform/includes/webform.install.requirements.inc b/web/modules/webform/includes/webform.install.requirements.inc
index f6d9a04211..d0470954d0 100644
--- a/web/modules/webform/includes/webform.install.requirements.inc
+++ b/web/modules/webform/includes/webform.install.requirements.inc
@@ -13,7 +13,7 @@
  * Implements hook_requirements().
  */
 function webform_requirements($phase) {
-  if ($phase != 'runtime') {
+  if ($phase !== 'runtime') {
     return [];
   }
 
@@ -111,7 +111,7 @@ function webform_requirements($phase) {
     $spam_protection = FALSE;
     $themes = \Drupal::service('theme_handler')->listInfo();
     foreach ($themes as $theme) {
-      if ((isset($theme->base_themes) && isset($theme->base_themes['bootstrap'])) || $theme == 'bootstrap') {
+      if ((isset($theme->base_themes) && isset($theme->base_themes['bootstrap'])) || $theme === 'bootstrap') {
         $spam_protection = TRUE;
       }
     }
diff --git a/web/modules/webform/includes/webform.install.update.inc b/web/modules/webform/includes/webform.install.update.inc
index 7b8173fd6c..13ede9a6b7 100644
--- a/web/modules/webform/includes/webform.install.update.inc
+++ b/web/modules/webform/includes/webform.install.update.inc
@@ -5,7 +5,6 @@
  * Archived Webform update hooks.
  */
 
-use Drupal\Core\Path\Entity\PathAlias;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\Component\Uuid\Php as Uuid;
 use Drupal\Core\Cache\Cache;
@@ -61,9 +60,9 @@ function webform_update_8001() {
   foreach ($schema as $item_name => $item) {
     foreach ($item as $table_name => $table_schema) {
       foreach ($table_schema as $schema_key => $schema_data) {
-        if ($schema_key == 'fields') {
+        if ($schema_key === 'fields') {
           foreach ($schema_data as $field_name => $field_data) {
-            if (preg_match('/_target_id$/', $field_name) && $field_data['description'] == 'The ID of the webform entity.' && $schema[$item_name][$table_name]['fields'][$field_name]['length'] === 255) {
+            if (preg_match('/_target_id$/', $field_name) && $field_data['description'] === 'The ID of the webform entity.' && $schema[$item_name][$table_name]['fields'][$field_name]['length'] === 255) {
               $schema[$item_name][$table_name]['fields'][$field_name]['length'] = 32;
               if ($database_schema->tableExists($table_name)) {
                 $database_schema->changeField($table_name, $field_name, $field_name, $schema[$item_name][$table_name]['fields'][$field_name]);
@@ -133,7 +132,7 @@ function webform_update_8006() {
   // Fix key_value.collection which was no updated during the migration.
   $module_handler = \Drupal::moduleHandler();
   $database_type = Database::getConnection('default')->databaseType();
-  if ($module_handler->moduleExists('webform') && !$module_handler->moduleExists('webform') && $database_type == 'mysql') {
+  if ($module_handler->moduleExists('webform') && !$module_handler->moduleExists('webform') && $database_type === 'mysql') {
     $database = \Drupal::database();
 
     $select = $database->select('key_value', 'kv');
@@ -511,10 +510,10 @@ function webform_update_8025() {
   foreach ($schema as $item_name => $item) {
     foreach ($item as $table_name => $table_schema) {
       foreach ($table_schema as $schema_key => $schema_data) {
-        if ($schema_key == 'fields') {
+        if ($schema_key === 'fields') {
           foreach ($schema_data as $field_name => $field_data) {
             $is_webform_field_status = (isset($webform_tables[$table_name]) && $field_name === $webform_tables[$table_name] . '_status');
-            $is_webform_field_integer = ($field_data['type'] == 'int');
+            $is_webform_field_integer = ($field_data['type'] === 'int');
             if ($is_webform_field_status && $is_webform_field_integer) {
               $temp_field_name = $field_name . '_temp';
 
@@ -631,7 +630,7 @@ function webform_update_8030() {
   foreach ($config_factory->listAll('webform.webform.') as $webform_config_name) {
     $webform_config = $config_factory->getEditable($webform_config_name);
     $data = $webform_config->getRawData();
-    $data['settings']['draft'] = ($data['settings']['draft'] == TRUE) ? WebformInterface::DRAFT_AUTHENTICATED : WebformInterface::DRAFT_NONE;
+    $data['settings']['draft'] = ($data['settings']['draft'] === TRUE) ? WebformInterface::DRAFT_AUTHENTICATED : WebformInterface::DRAFT_NONE;
     $webform_config->setData($data)->save();
   }
 }
@@ -759,7 +758,7 @@ function webform_update_8035() {
     $data = $webform_config->getRawData();
     $has_handler = FALSE;
     foreach ($data['handlers'] as &$handler) {
-      if ($handler['id'] == 'email') {
+      if ($handler['id'] === 'email') {
         if (isset($handler['settings']['states']) && is_array($handler['settings']['states'])) {
           $handler['settings']['states'] = array_values(array_filter($handler['settings']['states']));
         }
@@ -830,7 +829,7 @@ function webform_update_8039() {
   foreach ($config_factory->listAll('webform.webform.') as $webform_config_name) {
     $webform_config = $config_factory->getEditable($webform_config_name);
     $data = $webform_config->getRawData();
-    if (isset($data['dependencies']['enforced']['module']) && $data['dependencies']['enforced']['module'] == ['webform_templates']) {
+    if (isset($data['dependencies']['enforced']['module']) && $data['dependencies']['enforced']['module'] === ['webform_templates']) {
       if (!file_exists("$config_install_directory/$webform_config_name.yml")) {
         unset($data['dependencies']['enforced']['module']);
         if (empty($data['dependencies']['enforced'])) {
@@ -1040,7 +1039,7 @@ function _webform_update_8046_convert_data(array $data) {
   $actions_element = [];
   $settings = $data['settings'];
   foreach ($button_names as $button_name) {
-    $settings_prefix = ($button_name == 'submit') ? 'form_' . $button_name : $button_name . '_button';
+    $settings_prefix = ($button_name === 'submit') ? 'form_' . $button_name : $button_name . '_button';
     if (!empty($settings[$settings_prefix . '_label'])) {
       $actions_element['#' . $button_name . '__label'] = $settings[$settings_prefix . '_label'];
     }
@@ -1192,7 +1191,7 @@ function webform_update_8057() {
         $settings = [];
         foreach ($handler['settings'] as $settings_key => $setting_value) {
           $settings[$settings_key] = $setting_value;
-          if ($settings_key == 'excluded_elements') {
+          if ($settings_key === 'excluded_elements') {
             $settings['ignore_access'] = FALSE;
           }
         }
@@ -1334,7 +1333,7 @@ function webform_update_8065() {
         $settings = [];
         foreach ($handler['settings'] as $settings_key => $setting_value) {
           $settings[$settings_key] = $setting_value;
-          if ($settings_key == 'ignore_access') {
+          if ($settings_key === 'ignore_access') {
             $settings['exclude_empty'] = TRUE;
           }
         }
@@ -2002,7 +2001,7 @@ function webform_update_8107() {
 function webform_update_8108() {
   /** @var \Drupal\block\Entity\Block $block */
   foreach (\Drupal::entityTypeManager()->getStorage('block')->loadMultiple() as $block) {
-    if ($block->getPluginId() == 'webform_block') {
+    if ($block->getPluginId() === 'webform_block') {
       $webform_id = $block->getPlugin()->getConfiguration()['webform_id'];
       if (\Drupal::entityTypeManager()->getStorage('webform')->load($webform_id)) {
         $block->save();
@@ -3188,7 +3187,7 @@ function webform_update_8170() {
         unset($settings['draft_custom_data']);
       }
 
-      if ($handler['settings'] != $settings) {
+      if ($handler['settings'] !== $settings) {
         $handler_updated = TRUE;
         $handler['settings'] = $settings;
       }
@@ -3299,7 +3298,7 @@ function webform_update_8177() {
 }
 
 /**
- * Issue #3095275: Allow webform management filter by default category and states to be customized
+ * Issue #3095275: Allow webform management category/state to be customized.
  */
 function webform_update_8178() {
   _webform_update_admin_settings();
@@ -3366,7 +3365,7 @@ function webform_update_8180() {
 }
 
 /**
- * Issue #3103032: Move deprecated location geocomplete element into a sub-module
+ * Issue #3103032: Move deprecated geocomplete element into a sub-module.
  */
 function webform_update_8181() {
   $config_factory = \Drupal::configFactory();
@@ -3666,11 +3665,17 @@ function webform_update_8191() {
 }
 
 /**
-+ * Unsafe HMAC construction.
-+ */
+ * Unsafe HMAC construction.
+ */
 function webform_update_8192() {
+  // Check if the webform directory exists.
+  $webform_uri = 'public://webform';
+  if (!\Drupal::service('file_system')->prepareDirectory($webform_uri)) {
+    return NULL;
+  }
+
   $invalid_signatures = [];
-  $files = file_scan_directory('public://webform/','/signature-/');
+  $files = \Drupal::service('file_system')->scanDirectory('public://webform/', '/signature-/');
   foreach ($files as $file) {
     $value = file_get_contents($file->uri);
     $value = 'data:image/png;base64,' . base64_encode($value);
@@ -3684,7 +3689,7 @@ function webform_update_8192() {
     }
 
     // Delete invalid invalid signature file.
-    file_unmanaged_delete($file->uri);
+    \Drupal::service('file_system')->delete($file->uri);
   }
 
   // Exit if all signatures are valid.
@@ -3702,7 +3707,7 @@ function webform_update_8192() {
   if (PHP_SAPI === 'cli') {
     $text = t('Invalid signature file detected and deleted. (@see @url)', ['@url' => 'https://www.drupal.org/security/psa']) . PHP_EOL;
     foreach ($webform_submissions as $webform_submission) {
-      $text .= '- ' . $webform_submission->label() . ' (' .  $webform_submission->toUrl()->setAbsolute()->toString() . ')' . PHP_EOL;
+      $text .= '- ' . $webform_submission->label() . ' (' . $webform_submission->toUrl()->setAbsolute()->toString() . ')' . PHP_EOL;
     }
     return $text;
   }
@@ -3725,3 +3730,32 @@ function webform_update_8192() {
     return \Drupal::service('renderer')->renderPlain($build);
   }
 }
+
+/**
+ * Issue #3137964: Make it easier to embed/share a webform.
+ */
+function webform_update_8193() {
+  _webform_update_admin_settings();
+  _webform_update_webform_settings();
+}
+
+/**
+ * Issue #3144962: Webform cards.
+ */
+function webform_update_8195() {
+  _webform_update_webform_settings();
+}
+
+/**
+ * Issue #3153184: Allow a webform displayed as a page to have a custom theme.
+ */
+function webform_update_8196() {
+  _webform_update_webform_settings();
+}
+
+/**
+ * Issue #3144962: Webform cards.
+ */
+function webform_update_8197() {
+  _webform_update_admin_settings();
+}
diff --git a/web/modules/webform/includes/webform.libraries.inc b/web/modules/webform/includes/webform.libraries.inc
index e403547d43..bb385cedee 100644
--- a/web/modules/webform/includes/webform.libraries.inc
+++ b/web/modules/webform/includes/webform.libraries.inc
@@ -82,19 +82,6 @@ function webform_library_info_alter(&$libraries, $extension) {
     }
   }
 
-  // Remove dependency issue fixed in Drupal 8.8.x for webform.element.buttons.
-  //
-  // @see https://www.drupal.org/project/drupal/issues/2933980
-  // @see https://www.drupal.org/project/drupal/issues/2926155
-  if (isset($libraries['webform.element.buttons'])
-    && (floatval(\Drupal::VERSION) >= 8.8)) {
-    unset(
-      $libraries['webform.element.buttons']['js']['/core/assets/vendor/jquery.ui/ui/form-reset-mixin-min.js'],
-      $libraries['webform.element.buttons']['js']['/core/assets/vendor/jquery.ui/ui/escape-selector-min.js'],
-      $libraries['webform.element.buttons']['js']['/core/assets/vendor/jquery.ui/ui/widgets/checkboxradio-min.js']
-    );
-  }
-
   /** @var \Drupal\webform\WebformLibrariesManagerInterface $libraries_manager */
   $libraries_manager = \Drupal::service('webform.libraries_manager');
 
@@ -153,7 +140,7 @@ function _webform_library_info_alter_recursive(array &$library, array $cdn) {
     }
 
     // Ignore the CDN's associative array.
-    if ($key == 'cdn') {
+    if ($key === 'cdn') {
       continue;
     }
 
diff --git a/web/modules/webform/includes/webform.options.inc b/web/modules/webform/includes/webform.options.inc
index f5b1f1da86..fc4150e88c 100644
--- a/web/modules/webform/includes/webform.options.inc
+++ b/web/modules/webform/includes/webform.options.inc
@@ -10,7 +10,7 @@
 use Drupal\Core\Language\LanguageManager;
 
 /**
- * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter().
+ * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter() for range options.
  *
  * @see config/install/webform.webform.example_options.yml
  */
@@ -33,7 +33,7 @@ function webform_webform_options_range_alter(array &$options, array $element = [
 }
 
 /**
- * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter().
+ * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter() for time zones options.
  */
 function webform_webform_options_time_zones_alter(array &$options, array $element = []) {
   if (empty($options)) {
@@ -42,7 +42,7 @@ function webform_webform_options_time_zones_alter(array &$options, array $elemen
 }
 
 /**
- * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter().
+ * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter() for country codes options.
  */
 function webform_webform_options_country_codes_alter(array &$options, array $element = []) {
   if (empty($options)) {
@@ -51,7 +51,7 @@ function webform_webform_options_country_codes_alter(array &$options, array $ele
 }
 
 /**
- * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter().
+ * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter() for country names options.
  */
 function webform_webform_options_country_names_alter(array &$options, array $element = []) {
   if (empty($options)) {
@@ -61,7 +61,7 @@ function webform_webform_options_country_names_alter(array &$options, array $ele
 }
 
 /**
- * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter().
+ * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter() for languages options.
  */
 function webform_webform_options_languages_alter(array &$options, array $element = []) {
   if (empty($options)) {
@@ -75,7 +75,7 @@ function webform_webform_options_languages_alter(array &$options, array $element
 }
 
 /**
- * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter().
+ * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter() for translations options.
  */
 function webform_webform_options_translations_alter(array &$options, array $element = []) {
   if (empty($options)) {
diff --git a/web/modules/webform/includes/webform.theme.inc b/web/modules/webform/includes/webform.theme.inc
index 980c1d4f03..49d83a9785 100644
--- a/web/modules/webform/includes/webform.theme.inc
+++ b/web/modules/webform/includes/webform.theme.inc
@@ -9,6 +9,8 @@
 use Drupal\Component\Utility\Html;
 use Drupal\Component\Utility\NestedArray;
 use Drupal\Core\Template\Attribute;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\webform\Element\WebformSelectOther;
 use Drupal\webform\Utility\WebformAccessibilityHelper;
 use Drupal\webform\Utility\WebformElementHelper;
 
@@ -171,6 +173,7 @@ function webform_theme() {
         'webform_submission' => NULL,
         'current_page' => NULL,
         'operation' => NULL,
+        'pages' => [],
       ],
     ],
 
@@ -181,6 +184,7 @@ function webform_theme() {
         'current_page' => NULL,
         'operation' => NULL,
         'max_pages' => 10,
+        'pages' => [],
       ],
     ],
 
@@ -191,6 +195,7 @@ function webform_theme() {
         'current_page' => NULL,
         'operation' => NULL,
         'max_pages' => 10,
+        'pages' => [],
       ],
     ],
   ];
@@ -221,7 +226,7 @@ function webform_theme_registry_alter(&$theme_registry) {
 /******************************************************************************/
 
 /**
- * Prepares variables for single local action link templates.
+ * Implements preprocess_menu_local_action() for single local action link templates.
  *
  * Applies custom link attributes to local actions.
  * Custom attributes are used to open Webform UI modals.
@@ -255,7 +260,7 @@ function webform_preprocess_menu_local_action(&$variables) {
 }
 
 /**
- * Prepares variables for checkboxes templates.
+ * Implements hook_preprocess_checkboxes() for checkboxes templates.
  *
  * @see \Drupal\webform\Plugin\WebformElement\OptionsBase
  */
@@ -268,7 +273,7 @@ function webform_preprocess_checkboxes(&$variables) {
 }
 
 /**
- * Prepares variables for radios templates.
+ * Implements hook_preprocess_radios() for radios templates.
  *
  * @see \Drupal\webform\Plugin\WebformElement\OptionsBase
  */
@@ -280,6 +285,33 @@ function webform_preprocess_radios(&$variables) {
   _webform_preprocess_options($variables);
 }
 
+/**
+ * Implements hook_preprocess_select() for select templates.
+ */
+function webform_preprocess_select(&$variables) {
+  if (!WebformElementHelper::isWebformElement($variables['element'])) {
+    return;
+  }
+
+  $element = $variables['element'];
+
+  // When options are sorted (viu #sort_options: true) make sure the
+  // select '_other_' options is always last.
+  // @see \Drupal\webform\Element\WebformOtherBase::processWebformOther
+  // @see template_preprocess_select().
+  if (!empty($element['#sort_options']) && !empty($element['#webform_other'])) {
+    $options =& $variables['options'];
+    foreach ($options as $index => $option) {
+      if ($option['value'] === WebformSelectOther::OTHER_OPTION) {
+        unset($options[$index]);
+        $options[] = $option;
+        $options = array_values($options);
+        break;
+      }
+    }
+  }
+}
+
 /**
  * Prepares variable for status_messages.
  */
@@ -294,7 +326,7 @@ function webform_preprocess_status_messages(&$variables) {
 /******************************************************************************/
 
 /**
- * Prepares variables for table templates.
+ * Implements hook_preprocess_table() for table templates.
  */
 function webform_preprocess_table(&$variables) {
   // Add links to 'Translate' webform tab.
@@ -338,13 +370,23 @@ function webform_preprocess_table(&$variables) {
 /******************************************************************************/
 
 /**
- * Prepares variables for datetime form element templates.
+ * Implements hook_preprocess_datetime_form() for datetime form element templates.
  */
 function webform_preprocess_datetime_form(&$variables) {
   if (!WebformElementHelper::isWebformElement($variables['element'])) {
     return;
   }
 
+  $element = $variables['element'];
+
+  // Date and time custom placeholder.
+  if (isset($element['#date_date_placeholder']) && isset($variables['content']['date'])) {
+    $variables['content']['date']['#attributes']['placeholder'] = $element['#date_date_placeholder'];
+  }
+  if (isset($element['#date_time_placeholder']) && isset($variables['content']['time'])) {
+    $variables['content']['time']['#attributes']['placeholder'] = $element['#date_time_placeholder'];
+  }
+
   // Add .container-inline to datetime form wrapper which is missing from the
   // stable base theme.
   // @see core/themes/classy/templates/form/datetime-form.html.twig
@@ -353,7 +395,7 @@ function webform_preprocess_datetime_form(&$variables) {
 }
 
 /**
- * Prepares variables for details element templates.
+ * Implements hook_preprocess_details() for details element templates.
  */
 function webform_preprocess_details(&$variables) {
   if (!WebformElementHelper::isWebformElement($variables['element'])) {
@@ -380,7 +422,7 @@ function webform_preprocess_details(&$variables) {
 }
 
 /**
- * Prepares variables for fieldset element templates.
+ * Implements hook_preprocess_fieldset() for fieldset templates.
  */
 function webform_preprocess_fieldset(&$variables) {
   if (!WebformElementHelper::isWebformElement($variables['element'])) {
@@ -445,7 +487,7 @@ function webform_preprocess_fieldset(&$variables) {
 /******************************************************************************/
 
 /**
- * Prepares variables for form element templates.
+ * Implements hook_preprocess_form_element() for form element templates.
  */
 function webform_preprocess_form_element(&$variables) {
   if (!WebformElementHelper::isWebformElement($variables['element'])) {
@@ -479,7 +521,7 @@ function webform_preprocess_form_element(&$variables) {
 }
 
 /**
- * Prepares variables for form label templates.
+ * Implements hook_preprocess_form_element_label() for form element label templates.
  */
 function webform_preprocess_form_element_label(&$variables) {
   $element = &$variables['element'];
@@ -491,7 +533,7 @@ function webform_preprocess_form_element_label(&$variables) {
   if (isset($variables['title'])
     && is_array($variables['title'])
     && is_array($variables['title']['#markup'])) {
-      $variables['title'] = $variables['title']['#markup'];
+    $variables['title'] = $variables['title']['#markup'];
   }
 
   // Remove label 'for' attribute.
@@ -507,7 +549,7 @@ function webform_preprocess_form_element_label(&$variables) {
 /******************************************************************************/
 
 /**
- * Prepares variables for file managed file templates.
+ * Implements hook_preprocess_file_managed_file() for file managed file templates.
  *
  * @see https://stackoverflow.com/questions/21842274/cross-browser-custom-styling-for-file-upload-button
  * @see template_preprocess_file_managed_file()
@@ -564,17 +606,35 @@ function webform_preprocess_file_managed_file(&$variables) {
 }
 
 /**
- * Prepares variables for file upload help text templates.
+ * Implements hook_preprocess_file_upload_help() for file upload help text templates.
+ *
+ * @see \Drupal\webform\Plugin\WebformElement\WebformManagedFileBase::prepare
  */
 function webform_preprocess_file_upload_help(&$variables) {
   $upload_validators = $variables['upload_validators'];
+
   if (isset($upload_validators['webform_file_limit']) && $upload_validators['webform_file_limit'][0]) {
     $variables['descriptions'][] = t('@size limit per form.', ['@size' => format_size($upload_validators['webform_file_limit'][0])]);
   }
+
+  // Issue #3136578: Comma-separate the list of allowed file extensions.
+  // @see https://www.drupal.org/project/drupal/issues/3136578
+  if (isset($upload_validators['webform_file_validate_extensions'])) {
+    foreach ($variables['descriptions'] as $index => $description) {
+      if ($description instanceof TranslatableMarkup
+        && $description->getUntranslatedString() === 'Allowed types: @extensions.') {
+        $arguments = $description->getArguments();
+        if (strpos($arguments['@extensions'], ',') === FALSE) {
+          $arguments['@extensions'] = preg_replace('/ +/', ', ', $arguments['@extensions']);
+          $variables['descriptions'][$index] = new TranslatableMarkup($description->getUntranslatedString(), $arguments);
+        }
+      }
+    }
+  }
 }
 
 /**
- * Prepares variables for file link templates.
+ * Implements hook_preprocess_file_link() for file link templates.
  *
  * @see webform_file_access
  */
@@ -595,7 +655,7 @@ function webform_preprocess_file_link(&$variables) {
 }
 
 /**
- * Prepares variables for image.
+ * Implements hook_preprocess_image() for image templates.
  *
  * Make sure the image src for the 'webform_image_file' src is an absolute URL.
  */
@@ -606,18 +666,6 @@ function webform_preprocess_image(&$variables) {
   }
 }
 
-/******************************************************************************/
-// Preprocess webform specific elements.
-/******************************************************************************/
-
-/**
- * Prepares variables for webform section element templates.
- */
-function webform_preprocess_webform_section(&$variables) {
-  // Setup description, help, and more.
-  _webform_preprocess_element($variables);
-}
-
 /******************************************************************************/
 // Preprocess helpers.
 /******************************************************************************/
@@ -634,6 +682,9 @@ function _webform_preprocess_options(array &$variables) {
   $variables['attributes']['class'][] = Html::getClass('js-webform-' . $element['#type']);
 
   if (!empty($element['#options_display'])) {
+    if (strpos($element['#options_display'], 'buttons_') === 0) {
+      $variables['attributes']['class'][] = 'webform-options-display-buttons';
+    }
     $variables['attributes']['class'][] = Html::getClass('webform-options-display-' . $element['#options_display']);
     $variables['#attached']['library'][] = 'webform/webform.element.options';
   }
@@ -733,7 +784,7 @@ function _webform_preprocess_description_help(array &$variables) {
   // Move #description to #help for webform admin routes.
   if (\Drupal::config('webform.settings')->get('ui.description_help')
     && \Drupal::service('webform.request')->isWebformAdminRoute()
-    && \Drupal::routeMatch()->getRouteName() != 'webform.contribute.settings'
+    && \Drupal::routeMatch()->getRouteName() !== 'webform.contribute.settings'
     && !isset($element['#help'])
     && !empty($element['#title']) && (empty($element['#title_display']) || !in_array($element['#title_display'], ['attribute', 'invisible']))
     && !empty($element['#description']) && (empty($element['#description_display']) || !in_array($element['#description_display'], ['invisible']))
@@ -828,7 +879,7 @@ function _webform_preprocess_help(array &$variables, $title_parents = ['title'])
 
   // Place help before the target.
   if (isset($build[$target])) {
-    if (($target == 'title' && $title_display === 'inline')
+    if (($target === 'title' && $title_display === 'inline')
       || $help_display === 'title_before'
       || $help_display === 'element_before') {
       $build[$target]['#weight'] = 0;
@@ -888,10 +939,10 @@ function _webform_preprocess_form_element_description_more(array &$variables) {
 function _webform_theme_suggestions(array $variables, $hook) {
   $suggestions = [];
 
-  if ($hook == 'webform' && isset($variables['element']) && isset($variables['element']['#webform_id'])) {
+  if ($hook === 'webform' && isset($variables['element']) && isset($variables['element']['#webform_id'])) {
     $suggestions[] = $hook . '__' . $variables['element']['#webform_id'];
   }
-  elseif ($hook == 'webform_submission_form' && isset($variables['form']) && isset($variables['form']['#webform_id'])) {
+  elseif ($hook === 'webform_submission_form' && isset($variables['form']) && isset($variables['form']['#webform_id'])) {
     $suggestions[] = $hook . '__' . $variables['form']['#webform_id'];
   }
   elseif (strpos($hook, 'webform_element_base_') === 0 || strpos($hook, 'webform_container_base_') === 0) {
@@ -951,7 +1002,7 @@ function _webform_devel_hook_theme_suggestions_generate() {
   print '<pre>';
   foreach ($theme as $hook => $info) {
     $suggestion = FALSE;
-    if ($hook == 'webform') {
+    if ($hook === 'webform') {
       $suggestion = TRUE;
     }
     elseif (strpos($hook, 'webform_element_base_') === 0 || strpos($hook, 'webform_container_base_') === 0) {
@@ -1132,7 +1183,7 @@ function _webform_theme_suggestions_options(array $variables, $type) {
 
   $element = $variables['element'];
   $suggestions = [];
-  if (!empty($element['#options_display']) && $element['#options_display'] === 'buttons') {
+  if (!empty($element['#options_display']) && strpos($element['#options_display'], 'buttons') === 0) {
     $suggestions[] = $type . '__webform_' . $element['#options_display'];
   }
   return $suggestions;
diff --git a/web/modules/webform/includes/webform.theme.template.inc b/web/modules/webform/includes/webform.theme.template.inc
index 32ca02d7f4..2190037c9f 100644
--- a/web/modules/webform/includes/webform.theme.template.inc
+++ b/web/modules/webform/includes/webform.theme.template.inc
@@ -23,7 +23,7 @@
 use Drupal\webform\Utility\WebformElementHelper;
 
 /**
- * Prepares variables for webform help.
+ * Prepares variables for webform help templates.
  *
  * Default template: webform_help.html.twig.
  *
@@ -351,7 +351,7 @@ function template_preprocess_webform_submission_information(array &$variables) {
     }
     elseif (\Drupal::currentUser()->hasPermission("view webform node submissions own $entity_type")
       && method_exists($source_entity, 'getOwnerId')
-      && $source_entity->getOwnerId() == \Drupal::currentUser()->id()
+      && (int) $source_entity->getOwnerId() === (int) \Drupal::currentUser()->id()
     ) {
       $variables['submissions_view'] = TRUE;
     }
@@ -375,7 +375,7 @@ function template_preprocess_webform_submission_information(array &$variables) {
 }
 
 /**
- * Prepares variables for webform CodeMirror template.
+ * Prepares variables for webform CodeMirror templates.
  *
  * Default template: webform-codemirror.html.twig.
  *
@@ -393,7 +393,7 @@ function template_preprocess_webform_codemirror(array &$variables) {
 }
 
 /**
- * Prepares variables for webform element base HTML template.
+ * Prepares variables for webform element base HTML templates.
  *
  * Default template: webform-element-base-html.html.twig.
  *
@@ -446,7 +446,7 @@ function template_preprocess_webform_element_base_html(array &$variables) {
 }
 
 /**
- * Prepares variables for webform element base text template.
+ * Prepares variables for webform element base text templates.
  *
  * Default template: webform-element-base-text.html.twig.
  *
@@ -488,11 +488,11 @@ function _template_progress_webform_set_title(array &$variables, $strip_tags = F
 }
 
 /******************************************************************************/
-// Progress templates.
+// Preprocess templates.
 /******************************************************************************/
 
 /**
- * Prepares variables for webform 'wizard' progress template.
+ * Prepares variables for webform 'wizard' progress templates.
  *
  * Default template: webform-progress.html.twig.
  *
@@ -507,11 +507,12 @@ function template_preprocess_webform_progress(array &$variables) {
 
   /** @var \Drupal\webform\WebformInterface $webform */
   $webform = $variables['webform'];
+  /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
   $webform_submission = $variables['webform_submission'];
   $current_page = $variables['current_page'];
   $operation = $variables['operation'];
 
-  $pages = $webform->getPages($operation, $webform_submission);
+  $pages = $variables['pages'] ?: $webform->getPages($operation, $webform_submission);
 
   $page_keys = array_keys($pages);
   $page_indexes = array_flip($page_keys);
@@ -519,6 +520,9 @@ function template_preprocess_webform_progress(array &$variables) {
 
   $total = count($page_keys);
 
+  $variables['index'] = ($current_index + 1);
+  $variables['total'] = $total;
+
   if ($webform->getSetting('wizard_progress_bar')) {
     $variables['bar'] = [
       '#theme' => ($libraries_manager->isIncluded('progress-tracker')) ? 'webform_progress_tracker' : 'webform_progress_bar',
@@ -526,11 +530,12 @@ function template_preprocess_webform_progress(array &$variables) {
       '#webform_submission' => $webform_submission,
       '#current_page' => $current_page,
       '#operation' => $operation,
+      '#pages' => $variables['pages'],
     ];
   }
 
   if ($webform->getSetting('wizard_progress_pages')) {
-    $variables['summary'] = t('Page @start of @end', ['@start' => $current_index + 1, '@end' => $total]);
+    $variables['summary'] = t('@start of @end', ['@start' => $current_index + 1, '@end' => $total]);
   }
 
   if ($webform->getSetting('wizard_progress_percentage')) {
@@ -539,7 +544,7 @@ function template_preprocess_webform_progress(array &$variables) {
 }
 
 /**
- * Prepares variables for webform 'wizard' progress bar template.
+ * Prepares variables for webform 'wizard' progress bar templates.
  *
  * Default template: webform-progress-bar.html.twig.
  *
@@ -553,7 +558,7 @@ function template_preprocess_webform_progress_bar(array &$variables) {
 }
 
 /**
- * Prepares variables for webform 'wizard' progress tracker template.
+ * Prepares variables for webform 'wizard' progress tracker templates.
  *
  * Default template: webform-progress-tracker.html.twig.
  *
@@ -567,7 +572,7 @@ function template_preprocess_webform_progress_tracker(array &$variables) {
 }
 
 /**
- * Prepares variables for webform 'wizard' progress bar & tracker template.
+ * Prepares variables for webform 'wizard' progress bar & tracker templates.
  *
  * @param array $variables
  *   An associative array containing the following key:
@@ -577,11 +582,12 @@ function template_preprocess_webform_progress_tracker(array &$variables) {
 function _template_preprocess_webform_progress(array &$variables) {
   /** @var \Drupal\webform\WebformInterface $webform */
   $webform = $variables['webform'];
+  /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
   $webform_submission = $variables['webform_submission'];
   $current_page = $variables['current_page'];
   $operation = $variables['operation'];
 
-  $pages = $webform->getPages($operation, $webform_submission);
+  $pages = $variables['pages'] ?: $webform->getPages($operation, $webform_submission);
 
   $page_keys = array_keys($pages);
   $page_indexes = array_flip($page_keys);
@@ -594,6 +600,7 @@ function _template_preprocess_webform_progress(array &$variables) {
     $variables['progress'][] = [
       'name' => $key,
       'title' => (isset($page['#title'])) ? $page['#title'] : '',
+      'type' => (isset($page['#type'])) ? $page['#type'] : 'page',
     ];
   }
 }
@@ -603,7 +610,7 @@ function _template_preprocess_webform_progress(array &$variables) {
 /******************************************************************************/
 
 /**
- * Prepares variables for Webform message templates.
+ * Prepares variables for webform message templates.
  *
  * Default template: webform-message.html.twig.
  *
@@ -637,7 +644,7 @@ function template_preprocess_webform_message(array &$variables) {
 }
 
 /**
- * Prepares variables for Webform HTML Editor markup templates.
+ * Prepares variables for webform HTML Editor markup templates.
  *
  * Default template: webform-html-editor-markup.html.twig.
  *
@@ -654,7 +661,7 @@ function template_preprocess_webform_html_editor_markup(array &$variables) {
 }
 
 /**
- * Prepares variables for Webform horizontal rule templates.
+ * Prepares variables for webform horizontal rule templates.
  *
  * Default template: webform-horizontal-rule.html.twig.
  *
@@ -703,7 +710,7 @@ function template_preprocess_webform_section(array &$variables) {
   }
 
   // Add 'visually-hidden' class to title attributes.
-  if ($variables['title_display'] == 'invisible') {
+  if ($variables['title_display'] === 'invisible') {
     $variables['title_attributes']['class'][] = 'visually-hidden';
   }
   $variables['title_attributes'] = new Attribute($variables['title_attributes']);
@@ -720,6 +727,9 @@ function template_preprocess_webform_section(array &$variables) {
 
   // Suppress error messages.
   $variables['errors'] = NULL;
+
+  // Setup description, help, and more.
+  _webform_preprocess_element($variables);
 }
 
 /******************************************************************************/
@@ -727,7 +737,7 @@ function template_preprocess_webform_section(array &$variables) {
 /******************************************************************************/
 
 /**
- * Prepares variables for composite element templates.
+ * Prepares variables for webform composite templates.
  *
  * @param array $variables
  *   An associative array containing:
@@ -748,9 +758,9 @@ function _template_preprocess_webform_composite(array &$variables) {
 }
 
 /**
- * Prepares variables for address composite element templates.
+ * Prepares variables for composite address templates.
  *
- * Default template: webform-element-address.html.twig.
+ * Default template: webform-composite-address.html.twig.
  *
  * @param array $variables
  *   An associative array containing:
@@ -761,9 +771,9 @@ function template_preprocess_webform_composite_address(array &$variables) {
 }
 
 /**
- * Prepares variables for contact composite element templates.
+ * Prepares variables for composite contact templates.
  *
- * Default template: webform-element-contact.html.twig.
+ * Default template: webform-composite-contact.html.twig.
  *
  * @param array $variables
  *   An associative array containing:
@@ -774,9 +784,9 @@ function template_preprocess_webform_composite_contact(array &$variables) {
 }
 
 /**
- * Prepares variables for link composite element templates.
+ * Prepares variables for composite link templates.
  *
- * Default template: webform-element-link.html.twig.
+ * Default template: webform-composite-link.html.twig.
  *
  * @param array $variables
  *   An associative array containing:
@@ -787,9 +797,9 @@ function template_preprocess_webform_composite_link(array &$variables) {
 }
 
 /**
- * Prepares variables for location composite element templates.
+ * Prepares variables for composite location templates.
  *
- * Default template: webform-element-location.html.twig.
+ * Default template: webform-composite-location.html.twig.
  *
  * @param array $variables
  *   An associative array containing:
@@ -800,9 +810,9 @@ function template_preprocess_webform_composite_location(array &$variables) {
 }
 
 /**
- * Prepares variables for name composite element templates.
+ * Prepares variables for composite name templates.
  *
- * Default template: webform-element-name.html.twig.
+ * Default template: webform-composite-name.html.twig.
  *
  * @param array $variables
  *   An associative array containing:
@@ -813,9 +823,9 @@ function template_preprocess_webform_composite_name(array &$variables) {
 }
 
 /**
- * Prepares variables for telephone composite element templates.
+ * Prepares variables for composite telephone templates.
  *
- * Default template: webform-element-telephone.html.twig.
+ * Default template: webform-composite-telephone.html.twig.
  *
  * @param array $variables
  *   An associative array containing:
@@ -830,7 +840,7 @@ function template_preprocess_webform_composite_telephone(array &$variables) {
 /******************************************************************************/
 
 /**
- * Prepares variables for element help.
+ * Prepares variables for webform element help templates.
  *
  * Default template: webform-element-help.html.twig.
  *
@@ -859,7 +869,7 @@ function template_preprocess_webform_element_help(array &$variables) {
 }
 
 /**
- * Prepares variables for element more.
+ * Prepares variables for webform element more templates.
  *
  * Default template: webform-element-more.html.twig.
  *
@@ -893,7 +903,7 @@ function template_preprocess_webform_element_more(array &$variables) {
 }
 
 /**
- * Prepares variables for a managed file element.
+ * Prepares variables for webform element managed file templates.
  *
  * @param array $variables
  *   An associative array containing the following key:
@@ -917,7 +927,7 @@ function template_preprocess_webform_element_managed_file(array &$variables) {
 }
 
 /**
- * Prepares variables for an audio file element.
+ * Prepares variables for webform element audio file templates.
  *
  * Default template: webform-element-audio-file.html.twig.
  *
@@ -933,7 +943,7 @@ function template_preprocess_webform_element_audio_file(array &$variables) {
 }
 
 /**
- * Prepares variables for a document file element.
+ * Prepares variables for webform element document file templates.
  *
  * Default template: webform-element-document-file.html.twig.
  *
@@ -949,7 +959,7 @@ function template_preprocess_webform_element_document_file(array &$variables) {
 }
 
 /**
- * Prepares variables for an image file element.
+ * Prepares variables for webform element image file templates.
  *
  * Default template: webform-element-image-file.html.twig.
  *
@@ -1007,7 +1017,7 @@ function template_preprocess_webform_element_image_file(array &$variables) {
     }
 
     // Wrap 'image' in a link/modal.
-    if ($format && $format != 'image') {
+    if ($format && $format !== 'image') {
       $variables['image'] = [
         '#type' => 'link',
         '#title' => $variables['image'],
@@ -1031,7 +1041,7 @@ function template_preprocess_webform_element_image_file(array &$variables) {
 }
 
 /**
- * Prepares variables for a video file element.
+ * Prepares variables for webform element video file templates.
  *
  * Default template: webform-element-video-file.html.twig.
  *
diff --git a/web/modules/webform/includes/webform.translation.inc b/web/modules/webform/includes/webform.translation.inc
index 5df4058a21..0c0913127d 100644
--- a/web/modules/webform/includes/webform.translation.inc
+++ b/web/modules/webform/includes/webform.translation.inc
@@ -17,7 +17,7 @@
 use Drupal\field\Entity\FieldConfig;
 
 /**
- * Implements hook_form_FORM_ID_alter() for language_content_settings_form().
+ * Implements hook_form_FORM_ID_alter() for language content settings form.
  */
 function webform_form_language_content_settings_form_alter(array &$form, FormStateInterface $form_state) {
   // Completely remove webform_submission from Content language admin
@@ -32,7 +32,7 @@ function webform_form_language_content_settings_form_alter(array &$form, FormSta
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for locale translate edit form.
  */
 function webform_form_locale_translate_edit_form_alter(&$form, FormStateInterface $form_state) {
   // Don't allow YAML to be validated using locale string translation.
@@ -57,16 +57,16 @@ function webform_form_locale_translate_edit_form_alter(&$form, FormStateInterfac
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for config translation add form.
  */
 function webform_form_config_translation_add_form_alter(&$form, FormStateInterface $form_state, $is_new = TRUE) {
   // Manually apply YAML editor to text field that store YAML data.
   foreach ($form['config_names'] as $config_name => &$config_element) {
-    if ($config_name == 'webform.settings') {
+    if ($config_name === 'webform.settings') {
       _webform_form_config_translate_add_form_alter_yaml_element($config_element['test']['types']);
       _webform_form_config_translate_add_form_alter_yaml_element($config_element['test']['names']);
     }
-    elseif ($config_name == 'block.block.webform') {
+    elseif ($config_name === 'block.block.webform') {
       _webform_form_config_translate_add_form_alter_yaml_element($config_element['settings']['default_data']);;
     }
     elseif (strpos($config_name, 'field.field.') === 0
@@ -103,12 +103,49 @@ function webform_form_config_translation_add_form_alter(&$form, FormStateInterfa
       $form_state->set('webform_config_name', $config_name);
       $form_state->set('webform_source_elements', $source_elements);
 
-      // Tweak default 128 max length for certain settings.
-      $config_element['title']['translation']['#maxlength'] = 255;
-      $config_element['settings']['submission_label']['translation']['#maxlength'] = NULL;
+      // Tweak form elements.
+      $element_alterations = [
+        // Form settings.
+        'title' => ['#maxlength' => 255],
+        // Submission settings.
+        'submission_label' => ['#maxlength' => NULL],
+        // Email handler.
+        // @see \Drupal\webform\Plugin\WebformHandler\EmailWebformHandler
+        'subject' => ['#maxlength' => NULL],
+        'from_name' => ['#maxlength' => 255],
+        'sender_name' => ['#maxlength' => 255],
+      ];
+      _webform_form_config_translation_add_form_alter_elements($config_element, $element_alterations);
 
       $form['#validate'][] = '_webform_form_config_translate_add_form_validate';
+
+    }
+  }
+}
+
+/**
+ * Alter form element recursively.
+ *
+ * @param array $elements
+ *   An associative array of form elements.
+ * @param array $element_alterations
+ *   An associative array of element alterations.
+ */
+function _webform_form_config_translation_add_form_alter_elements(array &$elements, array $element_alterations) {
+  foreach ($elements as $key => &$element) {
+    if (Element::property($key) || !is_array($element)) {
+      continue;
     }
+
+    // Override/alter translation element.
+    if (array_key_exists($key, $element_alterations)
+      && isset($element['translation'])
+      && isset($element['translation']['#type'])) {
+      $element['translation'] = $element_alterations[$key] + $element['translation'];
+    }
+
+    _webform_form_config_translation_add_form_alter_elements($element, $element_alterations);
+
   }
 }
 
@@ -152,7 +189,7 @@ function _webform_form_config_translate_add_form_filter_elements(array &$transla
       continue;
     }
     $source_element = $source_elements[$key];
-    if ($translation_element == $source_element) {
+    if ($translation_element === $source_element) {
       unset($translation_elements[$key]);
     }
     elseif (is_array($translation_element)) {
@@ -165,7 +202,7 @@ function _webform_form_config_translate_add_form_filter_elements(array &$transla
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for config translation edit form.
  */
 function webform_form_config_translation_edit_form_alter(&$form, FormStateInterface $form_state) {
   webform_form_config_translation_add_form_alter($form, $form_state, FALSE);
diff --git a/web/modules/webform/js/webform.admin.js b/web/modules/webform/js/webform.admin.js
index 48408cbf0c..a421d1d21a 100644
--- a/web/modules/webform/js/webform.admin.js
+++ b/web/modules/webform/js/webform.admin.js
@@ -47,7 +47,7 @@
           return true;
         }
 
-        if ($(event.target).parents('a[href]').length) {
+        if ($(event.target).parents('a[href]').length || $(event.target).parents('.dropbutton-widget').length) {
           return true;
         }
 
diff --git a/web/modules/webform/js/webform.ajax.js b/web/modules/webform/js/webform.ajax.js
index cd4b5482d9..32cf3dd420 100644
--- a/web/modules/webform/js/webform.ajax.js
+++ b/web/modules/webform/js/webform.ajax.js
@@ -3,7 +3,7 @@
  * JavaScript behaviors for Ajax.
  */
 
-(function ($, Drupal) {
+(function ($, Drupal, drupalSettings) {
 
   'use strict';
 
@@ -288,7 +288,16 @@
         Drupal.behaviors.webformUnsaved.clear();
       }
 
-      this.redirect(ajax, response, status);
+      // For webform embedded in an iframe, open all redirects in the top
+      // of the browser window.
+      // @see \Drupal\webform_share\Controller\WebformShareController::page
+      if (drupalSettings.webform_share &&
+        drupalSettings.webform_share.page) {
+        window.top.location = response.url;
+      }
+      else {
+        this.redirect(ajax, response, status);
+      }
     }
   };
 
@@ -373,4 +382,4 @@
     return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
   }
 
-})(jQuery, Drupal);
+})(jQuery, Drupal, drupalSettings);
diff --git a/web/modules/webform/js/webform.dialog.js b/web/modules/webform/js/webform.dialog.js
index 99135a692f..ddee9db0f0 100644
--- a/web/modules/webform/js/webform.dialog.js
+++ b/web/modules/webform/js/webform.dialog.js
@@ -12,6 +12,23 @@
   Drupal.webform.dialog = Drupal.webform.dialog || {};
   Drupal.webform.dialog.options = Drupal.webform.dialog.options || {};
 
+  /**
+   * Programatically open a webform (or page) in a dialog.
+   *
+   * @param {string} url
+   *   Webform URL.
+   * @param {string} type
+   *   Webform dialog type defined via /admin/structure/webform/config.
+   */
+  Drupal.webformOpenDialog = function (url, type) {
+    // Create a div with link but don't attach it to the page.
+    var $div = $('<div><a href="' + url + '" class="webform-dialog ' + type + '"></a></div>');
+    // Init the webform dialog behavior.
+    Drupal.behaviors.webformDialog.attach($div);
+    // Trigger the link.
+    $div.find('a').click();
+  };
+
   /**
    * Open webform dialog using preset options.
    *
diff --git a/web/modules/webform/js/webform.element.checkboxes.js b/web/modules/webform/js/webform.element.checkboxes.js
index 35ca690a98..761ff3d5d3 100644
--- a/web/modules/webform/js/webform.element.checkboxes.js
+++ b/web/modules/webform/js/webform.element.checkboxes.js
@@ -7,6 +7,90 @@
 
   'use strict';
 
+  /**
+   * Adds check all or none checkboxes support.
+   *
+   * @type {Drupal~behavior}
+   *
+   * @see https://www.drupal.org/project/webform/issues/3068998
+   */
+  Drupal.behaviors.webformCheckboxesAllorNone = {
+    attach: function (context) {
+      $('[data-options-all], [data-options-none]', context)
+        .once('webform-checkboxes-all-or-none')
+        .each(function () {
+          var $element = $(this);
+
+          var options_all_value = $element.data('options-all');
+          var options_none_value = $element.data('options-none');
+
+          // Get all checkboxes.
+          var $checkboxes = $element.find('input[type="checkbox"]');
+          // Get all options/checkboxes.
+          var $options = $checkboxes
+            .not('[value="' + options_all_value + '"]')
+            .not('[value="' + options_none_value + '"]');
+
+          // All of the above.
+          if (options_all_value) {
+            var $options_all = $element
+              .find(':checkbox[value="' + options_all_value + '"]');
+            $options_all.on('click', function () {
+              var checked = this.checked;
+              $checkboxes.each(function () {
+                if (this.value === options_none_value) {
+                  this.checked = false;
+                }
+                else {
+                  this.checked = checked;
+                }
+              });
+            });
+
+            $options.on('click', toggleCheckAllEventHandler);
+            toggleCheckAllEventHandler();
+
+            /**
+             * Toggle check all checkbox checked state.
+             */
+            function toggleCheckAllEventHandler() {
+              var checked = true;
+              $options.each(function () {
+                if (!this.checked) {
+                  checked = false;
+                }
+              });
+              $options_all[0].checked = checked;
+            }
+          }
+
+          // None of the above.
+          if (options_none_value) {
+            var $options_none = $element.find(':checkbox[value="' + options_none_value + '"]');
+            $options_none.on('click', toggleCheckNoneEventHandler);
+            toggleCheckNoneEventHandler();
+
+            /**
+             * Toggle check none checkbox checked state.
+             */
+            function toggleCheckNoneEventHandler() {
+              var checked = $options_none[0].checked;
+              $checkboxes.each(function () {
+                if (this.value !== options_none_value) {
+                  if (checked && this.checked) {
+                    this.checked = false;
+                    $(this).change();
+                  }
+                  this.disabled = checked;
+                }
+              });
+            }
+
+          }
+        });
+    }
+  };
+
   /**
    * Adds HTML5 validation to required checkboxes.
    *
diff --git a/web/modules/webform/js/webform.element.counter.js b/web/modules/webform/js/webform.element.counter.js
index 0bb83af7eb..3b605433de 100644
--- a/web/modules/webform/js/webform.element.counter.js
+++ b/web/modules/webform/js/webform.element.counter.js
@@ -33,6 +33,7 @@
           inputErrorClass: 'webform-counter-warning',
           counterErrorClass: 'webform-counter-warning',
           countSpaces: true,
+          twoCharCarriageReturn: true,
           stopInputAtMaximum: false,
           // Don't display min/max message since server-side validation will
           // display these messages.
diff --git a/web/modules/webform/js/webform.element.signature.js b/web/modules/webform/js/webform.element.signature.js
index 6a3cf84633..253718a2fa 100644
--- a/web/modules/webform/js/webform.element.signature.js
+++ b/web/modules/webform/js/webform.element.signature.js
@@ -23,7 +23,6 @@
         return;
       }
 
-
       $(context).find('input.js-webform-signature').once('webform-signature').each(function () {
         var $input = $(this);
         var value = $input.val();
@@ -105,6 +104,14 @@
             $button.show();
           }
         });
+
+        // If the signature pad is not visible (i.e. in a modal dialog),
+        // recalculate the dimensions, after everything has rendered.
+        if (!$input.is(':visible')) {
+          setTimeout(function () {
+            calculateDimensions();
+          }, 1);
+        }
       });
     }
   };
diff --git a/web/modules/webform/js/webform.form.unsaved.js b/web/modules/webform/js/webform.form.unsaved.js
index b7f66ebd22..0b1fd17886 100644
--- a/web/modules/webform/js/webform.form.unsaved.js
+++ b/web/modules/webform/js/webform.form.unsaved.js
@@ -98,14 +98,21 @@
       return;
     }
     $('a:not(.use-ajax)').bind('click', function (evt) {
-      var href = $(evt.target).closest('a').attr('href');
+      var a = $(evt.target).closest('a');
+      var href = a.attr('href');
       if (typeof href !== 'undefined' && !(href.match(/^#/) || href.trim() === '')) {
         if ($(window).triggerHandler('beforeunload')) {
           if (!window.confirm(Drupal.t('Changes you made may not be saved.') + '\n\n' + Drupal.t('Press OK to leave this page or Cancel to stay.'))) {
             return false;
           }
         }
-        window.location.href = href;
+        var target = a.attr('target');
+        if (target) {
+          window.open(href, target);
+        }
+        else {
+          window.location.href = href;
+        }
         return false;
       }
     });
diff --git a/web/modules/webform/js/webform.wizard.pages.js b/web/modules/webform/js/webform.wizard.pages.js
index 805033ad1c..b19f20cd7c 100644
--- a/web/modules/webform/js/webform.wizard.pages.js
+++ b/web/modules/webform/js/webform.wizard.pages.js
@@ -1,6 +1,6 @@
 /**
  * @file
- * JavaScript behaviors for webform wizard.
+ * JavaScript behaviors for webform wizard pages.
  */
 
 (function ($, Drupal) {
@@ -36,10 +36,16 @@
               .attr({
                 'role': 'link',
                 'title': title,
-                'aria-label': title
+                'aria-label': title,
+                'tabindex': '0'
               })
               .click(function () {
                 $button.click();
+              })
+              .keydown(function (event) {
+                if (event.which === 13) {
+                  $button.click();
+                }
               });
             // Only allow the marker to be tabbable.
             $progress.find('.progress-marker').attr('tabindex', 0);
diff --git a/web/modules/webform/modules/webform_access/src/Access/WebformAccessGroupAccess.php b/web/modules/webform/modules/webform_access/src/Access/WebformAccessGroupAccess.php
index caafe2a56f..484a86cad5 100644
--- a/web/modules/webform/modules/webform_access/src/Access/WebformAccessGroupAccess.php
+++ b/web/modules/webform/modules/webform_access/src/Access/WebformAccessGroupAccess.php
@@ -21,7 +21,7 @@ public static function checkAdminAccess() {
     if ($account->hasPermission('administer webform')) {
       $access_result = AccessResult::allowed();
     }
-    elseif (self::isAdmin($account)) {
+    elseif (static::isAdmin($account)) {
       $access_result = AccessResult::allowed();
       $access_result->addCacheTags(['webform_access_group_list']);
     }
diff --git a/web/modules/webform/modules/webform_access/src/Entity/WebformAccessGroup.php b/web/modules/webform/modules/webform_access/src/Entity/WebformAccessGroup.php
index dba9141453..9722108a31 100644
--- a/web/modules/webform/modules/webform_access/src/Entity/WebformAccessGroup.php
+++ b/web/modules/webform/modules/webform_access/src/Entity/WebformAccessGroup.php
@@ -226,7 +226,7 @@ public function addAdminId($uid) {
    */
   public function removeAdminId($uid) {
     foreach ($this->adminIds as $index => $adminId) {
-      if ($adminId == $uid) {
+      if ($adminId === $uid) {
         unset($this->adminIds[$index]);
       }
     }
@@ -249,7 +249,7 @@ public function addUserId($uid) {
    */
   public function removeUserId($uid) {
     foreach ($this->userIds as $index => $userId) {
-      if ($userId == $uid) {
+      if ($userId === $uid) {
         unset($this->userIds[$index]);
       }
     }
@@ -274,7 +274,7 @@ public function addEntityId($entity_type, $entity_id, $field_name, $webform_id)
   public function removeEntityId($entity_type, $entity_id, $field_name, $webform_id) {
     $entity = "$entity_type:$entity_id:$field_name:$webform_id";
     foreach ($this->entityIds as $index => $entityId) {
-      if ($entity == $entityId) {
+      if ($entity === $entityId) {
         unset($this->entityIds[$index]);
       }
     }
@@ -297,7 +297,7 @@ public function addEmail($email) {
    */
   public function removeEmail($email) {
     foreach ($this->emails as $index => $email_address) {
-      if ($email_address == $email) {
+      if ($email_address === $email) {
         unset($this->emails[$index]);
       }
     }
diff --git a/web/modules/webform/modules/webform_access/src/WebformAccessGroupForm.php b/web/modules/webform/modules/webform_access/src/WebformAccessGroupForm.php
index 363fd91e69..b75d5740bd 100644
--- a/web/modules/webform/modules/webform_access/src/WebformAccessGroupForm.php
+++ b/web/modules/webform/modules/webform_access/src/WebformAccessGroupForm.php
@@ -92,7 +92,7 @@ public static function create(ContainerInterface $container) {
    * {@inheritdoc}
    */
   protected function prepareEntity() {
-    if ($this->operation == 'duplicate') {
+    if ($this->operation === 'duplicate') {
       $this->setEntity($this->getEntity()->createDuplicate());
     }
     parent::prepareEntity();
diff --git a/web/modules/webform/modules/webform_access/src/WebformAccessGroupListBuilder.php b/web/modules/webform/modules/webform_access/src/WebformAccessGroupListBuilder.php
index 2a04fcd2b7..c3327f6afb 100644
--- a/web/modules/webform/modules/webform_access/src/WebformAccessGroupListBuilder.php
+++ b/web/modules/webform/modules/webform_access/src/WebformAccessGroupListBuilder.php
@@ -189,19 +189,19 @@ public function buildRow(EntityInterface $entity) {
     $row['type'] = $entity->getTypeLabel();
 
     // Users.
-    $row['users'] = ['data' => self::buildUserAccounts($entity->getUserIds())];
+    $row['users'] = ['data' => static::buildUserAccounts($entity->getUserIds())];
 
     // Entities.
-    $row['entities'] = ['data' => self::buildEntities($entity->getEntityIds())];
+    $row['entities'] = ['data' => static::buildEntities($entity->getEntityIds())];
 
     // Permissions.
-    $row['permissions'] = ['data' => self::buildPermissions($entity->get('permissions'))];
+    $row['permissions'] = ['data' => static::buildPermissions($entity->get('permissions'))];
 
     // Admins.
-    $row['admins'] = ['data' => self::buildUserAccounts($entity->getAdminIds())];
+    $row['admins'] = ['data' => static::buildUserAccounts($entity->getAdminIds())];
 
     // Emails.
-    $row['emails'] = ['data' => self::buildEmails($entity->getEmails())];
+    $row['emails'] = ['data' => static::buildEmails($entity->getEmails())];
 
     $row = $row + parent::buildRow($entity);
 
diff --git a/web/modules/webform/modules/webform_access/src/WebformAccessTypeListBuilder.php b/web/modules/webform/modules/webform_access/src/WebformAccessTypeListBuilder.php
index ce3fc48d1d..433cfd292e 100644
--- a/web/modules/webform/modules/webform_access/src/WebformAccessTypeListBuilder.php
+++ b/web/modules/webform/modules/webform_access/src/WebformAccessTypeListBuilder.php
@@ -24,7 +24,7 @@ class WebformAccessTypeListBuilder extends ConfigEntityListBuilder {
   protected $limit = FALSE;
 
   /**
-   * Access group storage.
+   * The access group storage.
    *
    * @var \Drupal\webform_access\WebformAccessGroupStorageInterface
    */
diff --git a/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessBrowserTestBase.php b/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessBrowserTestBase.php
index 3a5b090368..57d227fab3 100644
--- a/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessBrowserTestBase.php
+++ b/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessBrowserTestBase.php
@@ -49,7 +49,7 @@ abstract class WebformAccessBrowserTestBase extends WebformNodeBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create webform nodes.
diff --git a/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessSubmissionViewsTest.php b/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessSubmissionViewsTest.php
index af05e9e557..c58e5f73ac 100644
--- a/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessSubmissionViewsTest.php
+++ b/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessSubmissionViewsTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform access submission views.
  *
- * @group WebformAccess
+ * @group webform_access
  */
 class WebformAccessSubmissionViewsTest extends WebformAccessBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessTest.php b/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessTest.php
index 8b5115feb7..3787a1677f 100644
--- a/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessTest.php
+++ b/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform access.
  *
- * @group WebformAccess
+ * @group webform_access
  */
 class WebformAccessTest extends WebformAccessBrowserTestBase {
 
@@ -48,7 +48,7 @@ public function testWebformAccess() {
       $this->drupalPostForm(
         "/admin/structure/webform/access/group/manage/$name",
         ['users[]' => $this->users[$name]->id()],
-        t('Save')
+        'Save'
       );
     }
 
@@ -75,7 +75,7 @@ public function testWebformAccess() {
     $this->drupalPostForm(
       '/admin/structure/webform/access/group/manage/employee',
       ['users[]' => 1],
-      t('Save')
+      'Save'
     );
 
     // Assign employee user to manager group via the UI.
@@ -83,7 +83,7 @@ public function testWebformAccess() {
     $this->drupalPostForm(
       '/user/' . $this->users['employee']->id() . '/edit',
       ['webform_access_group[]' => 'manager'],
-      t('Save')
+      'Save'
     );
 
     // Check defining webform field's access groups default value.
@@ -97,7 +97,7 @@ public function testWebformAccess() {
         'default_value_input[webform][0][settings][default_data]' => 'test: test',
         'default_value_input[webform][0][settings][webform_access_group][]' => 'manager',
       ],
-      t('Save settings')
+      'Save settings'
     );
     $this->drupalGet('/node/add/webform');
     $this->assertFieldByName('webform[0][settings][webform_access_group][]', 'manager');
@@ -113,7 +113,7 @@ public function testWebformAccess() {
       $this->drupalPostForm(
         "/admin/structure/webform/access/group/manage/$name",
         ['entities[]' => 'node:' . $this->nodes['contact_02']->id() . ':webform:contact'],
-        t('Save')
+        'Save'
       );
     }
 
@@ -127,7 +127,7 @@ public function testWebformAccess() {
     $this->drupalPostForm(
       "/node/$nid/edit",
       ['webform[0][settings][webform_access_group][]' => 'manager'],
-      t('Save')
+      'Save'
     );
 
     // Check that employee can now access results.
diff --git a/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessTokensTest.php b/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessTokensTest.php
index e9933509bb..c81c5b3d4f 100644
--- a/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessTokensTest.php
+++ b/web/modules/webform/modules/webform_access/tests/src/Functional/WebformAccessTokensTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform tokens access.
  *
- * @group WebformAccess
+ * @group webform_access
  */
 class WebformAccessTokensTest extends WebformAccessBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_access/webform_access.info.yml b/web/modules/webform/modules/webform_access/webform_access.info.yml
index b694833907..3ba8af7239 100644
--- a/web/modules/webform/modules/webform_access/webform_access.info.yml
+++ b/web/modules/webform/modules/webform_access/webform_access.info.yml
@@ -1,13 +1,13 @@
 name: 'Webform Access'
 description: 'Provides webform access controls for webform nodes.'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 package: Webform
 type: module
 dependencies:
   - 'webform:webform'
   - 'webform:webform_node'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_access/webform_access.module b/web/modules/webform/modules/webform_access/webform_access.module
index 3ae03d0d21..3fc3766d58 100644
--- a/web/modules/webform/modules/webform_access/webform_access.module
+++ b/web/modules/webform/modules/webform_access/webform_access.module
@@ -156,7 +156,7 @@ function webform_access_menu_local_tasks_alter(&$data, $route_name) {
 }
 
 /**
- * Implements hook_ENTITY_TYPE_access().
+ * Implements hook_ENTITY_TYPE_access() for webform entities.
  */
 function webform_access_webform_access(WebformInterface $webform, $operation, AccountInterface $account) {
   // Prevent recursion when a webform is being passed as the source entity
@@ -199,7 +199,7 @@ function webform_access_webform_access(WebformInterface $webform, $operation, Ac
 }
 
 /**
- * Implements hook_ENTITY_TYPE_access().
+ * Implements hook_ENTITY_TYPE_access() for webform_submission entities.
  */
 function webform_access_webform_submission_access(WebformSubmissionInterface $webform_submission, $operation, AccountInterface $account) {
   if (!in_array($operation, ['view', 'update', 'delete'])) {
@@ -227,7 +227,7 @@ function webform_access_webform_submission_access(WebformSubmissionInterface $we
       // Is operation any.
       (in_array($operation . '_any', $permissions)) ||
       // Is operation own.
-      (in_array($operation . '_own', $permissions) && $webform_submission->getOwnerId() == $account->id())
+      (in_array($operation . '_own', $permissions) && $webform_submission->getOwnerId() === $account->id())
     ) {
       return AccessResult::allowed()
         ->cachePerUser()
@@ -398,7 +398,7 @@ function _webform_access_form_node_form_submit(&$form, FormStateInterface $form_
 /******************************************************************************/
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for user form.
  *
  * Add the webform access group to an individual user's account page.
  */
diff --git a/web/modules/webform/modules/webform_access/webform_access.tokens.inc b/web/modules/webform/modules/webform_access/webform_access.tokens.inc
index 02a5124eff..cf20492c59 100644
--- a/web/modules/webform/modules/webform_access/webform_access.tokens.inc
+++ b/web/modules/webform/modules/webform_access/webform_access.tokens.inc
@@ -77,7 +77,7 @@ function webform_access_token_info() {
  */
 function webform_access_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
   $replacements = [];
-  if ($type == 'webform_access' && !empty($data['webform_access'])) {
+  if ($type === 'webform_access' && !empty($data['webform_access'])) {
     /** @var \Drupal\webform_access\WebformAccessGroupStorageInterface $webform_access_group_storage */
     $webform_access_group_storage = \Drupal::entityTypeManager()->getStorage('webform_access_group');
 
diff --git a/web/modules/webform/modules/webform_attachment/src/Controller/WebformAttachmentController.php b/web/modules/webform/modules/webform_attachment/src/Controller/WebformAttachmentController.php
index ae128f3d6c..1e2efb5159 100644
--- a/web/modules/webform/modules/webform_attachment/src/Controller/WebformAttachmentController.php
+++ b/web/modules/webform/modules/webform_attachment/src/Controller/WebformAttachmentController.php
@@ -27,7 +27,7 @@ class WebformAttachmentController extends ControllerBase implements ContainerInj
   protected $elementInfo;
 
   /**
-   * A webform element plugin manager.
+   * The webform element plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
diff --git a/web/modules/webform/modules/webform_attachment/src/Plugin/WebformElement/WebformAttachmentBase.php b/web/modules/webform/modules/webform_attachment/src/Plugin/WebformElement/WebformAttachmentBase.php
index 3fa84bb263..0e47a16ddf 100644
--- a/web/modules/webform/modules/webform_attachment/src/Plugin/WebformElement/WebformAttachmentBase.php
+++ b/web/modules/webform/modules/webform_attachment/src/Plugin/WebformElement/WebformAttachmentBase.php
@@ -28,7 +28,7 @@ protected function defineDefaultProperties() {
       // Form display.
       'title_display' => '',
       // Display settings.
-      'display_on' => static::DISPLAY_ON_NONE,
+      'display_on' => WebformElementDisplayOnInterface::DISPLAY_ON_NONE,
       // Attachment values.
       'filename' => '',
       'sanitize' => FALSE,
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_access.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_access.yml
index 50a528f980..1384dabccb 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_access.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_access.yml
@@ -46,7 +46,7 @@ elements: |
     '#template': 'Admin users can access this attachment'
     '#private': true
     '#display_on': both
-  
+
 css: ''
 javascript: ''
 settings:
@@ -58,7 +58,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -88,6 +88,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -113,11 +118,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_email.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_email.yml
index d9900202e8..e359be96ff 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_email.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_email.yml
@@ -61,13 +61,13 @@ elements: |
             </SOURCE>
          </asx:values>
       </asx:abap>
-  
+
   attachment_twig:
     '#type': webform_attachment_twig
     '#title': attachment_twig
     '#filename': 'attachment_twig-[current-date:html_date].xml'
     '#template': "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<asx:abap xmlns:asx=\"http://www.sap.com/abapxml\" version=\"1.0\">\n   <asx:values>\n      <VERSION>1.0</VERSION>\n      <SENDER>{{ webform_id }}</SENDER>\n      <WEBFORM_ID>{{ data.email }}</WEBFORM_ID>\n      <SOURCE>\n        {% for key, value in data %}\n         <o2PARAVALU>\n            <NAME>{{ (elements_flattened[key]['#xml_name']) ? elements_flattened[key]['#xml_name'] : key }}</NAME>\n            <VALUE>{{ value }}</VALUE>\n         </o2PARAVALU>\n        {% endfor %}      \n      </SOURCE>\n   </asx:values>\n</asx:abap>"
-  
+
 css: ''
 javascript: ''
 settings:
@@ -79,7 +79,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -109,6 +109,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -134,11 +139,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_sanitize.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_sanitize.yml
index b4b5490eb7..b019e38eb7 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_sanitize.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_sanitize.yml
@@ -26,7 +26,7 @@ elements: |
     '#sanitize': true
     '#template': |
       textfield: [webform_submission:values:textfield]
-  
+
 css: ''
 javascript: ''
 settings:
@@ -38,7 +38,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -68,6 +68,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -93,11 +98,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_states.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_states.yml
index d3945c0f31..f53fd70d52 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_states.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_states.yml
@@ -27,7 +27,7 @@ elements: |
       'enabled':
         ':input[name="attach"]':
           checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -39,7 +39,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -69,6 +69,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -94,11 +99,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_token.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_token.yml
index 9583fe19ce..1216242a9a 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_token.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_token.yml
@@ -34,7 +34,7 @@ elements: |
       textfield: [webform_submission:values:textfield]
     '#download': true
     '#display_on': both
-  
+
 css: ''
 javascript: ''
 settings:
@@ -46,7 +46,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -76,6 +76,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -101,11 +106,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_twig.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_twig.yml
index 2027f05b3f..1239a801cb 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_twig.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_twig.yml
@@ -36,7 +36,7 @@ elements: |
       <textfield>{{ webform_token('[webform_submission:values:textfield:xmlencode]', webform_submission) }}</textfield>
     '#download': true
     '#display_on': both
-  
+
 css: ''
 javascript: ''
 settings:
@@ -48,7 +48,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -78,6 +78,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -103,11 +108,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_url.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_url.yml
index 0e50a25591..bef72cf834 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_url.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/config/install/webform.webform.test_attachment_url.yml
@@ -37,7 +37,7 @@ elements: |
     '#url': ''
     '#download': true
     '#display_on': both
-  
+
 css: ''
 javascript: ''
 settings:
@@ -49,7 +49,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -79,6 +79,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -104,11 +109,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/webform_attachment_test.info.yml b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/webform_attachment_test.info.yml
index d107cf6097..f5efbf1c89 100644
--- a/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/webform_attachment_test.info.yml
+++ b/web/modules/webform/modules/webform_attachment/tests/modules/webform_attachment_test/webform_attachment_test.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform Attachment Test'
+name: 'Webform Attachment test'
 type: module
-description: 'Support module for webform attachment element that provides test webforms.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform attachment element testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_attachment'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_attachment/tests/src/Functional/WebformAttachmentTest.php b/web/modules/webform/modules/webform_attachment/tests/src/Functional/WebformAttachmentTest.php
index 9c79458d1b..cf089aec83 100644
--- a/web/modules/webform/modules/webform_attachment/tests/src/Functional/WebformAttachmentTest.php
+++ b/web/modules/webform/modules/webform_attachment/tests/src/Functional/WebformAttachmentTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform example element.
  *
- * @group Webform
+ * @group webform_attachment
  */
 class WebformAttachmentTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_attachment/webform_attachment.info.yml b/web/modules/webform/modules/webform_attachment/webform_attachment.info.yml
index 26788d67e4..5670dca5d2 100644
--- a/web/modules/webform/modules/webform_attachment/webform_attachment.info.yml
+++ b/web/modules/webform/modules/webform_attachment/webform_attachment.info.yml
@@ -1,12 +1,12 @@
 name: 'Webform Attachment'
 type: module
-description: 'Provides an element generates or loads a file that can be attached to a submission or email.'
-package: 'Webform'
-core_version_requirement: ^8.7.7 || ^9
+description: 'Provides an element that generates or loads a file that can be attached to a submission or email.'
+package: Webform
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_bootstrap/src/WebformBootstrapRenderCallbacks.php b/web/modules/webform/modules/webform_bootstrap/src/WebformBootstrapRenderCallbacks.php
new file mode 100644
index 0000000000..04936f0f94
--- /dev/null
+++ b/web/modules/webform/modules/webform_bootstrap/src/WebformBootstrapRenderCallbacks.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\webform_bootstrap;
+
+use Drupal\Core\Render\Element;
+use Drupal\Core\Render\Element\RenderCallbackInterface;
+
+/**
+ * Render callbacks for the webform bootstrap module.
+ */
+class WebformBootstrapRenderCallbacks implements RenderCallbackInterface {
+
+  /**
+   * Render callback for the likerts element.
+   *
+   * @param array $element
+   *   The render array.
+   *
+   * @return array
+   *   The altered render array.
+   */
+  public static function webformLikertPreRender(array $element) {
+    foreach (Element::children($element) as $element_key) {
+      // Likerts allow description display to be configured, so disable
+      // smart description.
+      if (!empty($element[$element_key]['#description'])) {
+        $element[$element_key]['#smart_description'] = FALSE;
+      }
+      $element[$element_key] = static::webformLikertPreRender($element[$element_key]);
+    }
+    return $element;
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_bootstrap/tests/modules/webform_bootstrap_test_module/webform_bootstrap_test_module.info.yml b/web/modules/webform/modules/webform_bootstrap/tests/modules/webform_bootstrap_test_module/webform_bootstrap_test_module.info.yml
index 702b6fb75f..2168aee54e 100644
--- a/web/modules/webform/modules/webform_bootstrap/tests/modules/webform_bootstrap_test_module/webform_bootstrap_test_module.info.yml
+++ b/web/modules/webform/modules/webform_bootstrap/tests/modules/webform_bootstrap_test_module/webform_bootstrap_test_module.info.yml
@@ -1,14 +1,14 @@
 name: 'Webform Test Bootstrap Helper'
 type: module
-description: 'Installs and integrates the Webform Test Bootstrap theme.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Suport module for webform bootstrap integration testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'styleguide:styleguide'
   - 'webform:webform'
   - 'webform:webform_bootstrap'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_bootstrap/tests/themes/webform_bootstrap_test_theme/webform_bootstrap_test_theme.info.yml b/web/modules/webform/modules/webform_bootstrap/tests/themes/webform_bootstrap_test_theme/webform_bootstrap_test_theme.info.yml
index 9a444caab6..3e312777d2 100644
--- a/web/modules/webform/modules/webform_bootstrap/tests/themes/webform_bootstrap_test_theme/webform_bootstrap_test_theme.info.yml
+++ b/web/modules/webform/modules/webform_bootstrap/tests/themes/webform_bootstrap_test_theme/webform_bootstrap_test_theme.info.yml
@@ -1,10 +1,10 @@
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 type: theme
 base theme: bootstrap
 
 name: 'Webform Test Bootstrap'
-description: 'Test Webform Bootstrap integration.'
-package: 'Webform Test'
+description: 'Support theme for webform bootstrap integration testing.'
+package: 'Webform Testing'
 
 regions:
   navigation: 'Navigation'
@@ -22,7 +22,7 @@ regions:
 libraries:
   - 'webform_bootstrap_test_theme/global-styling'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.info.yml b/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.info.yml
index 6d4353e882..eec1a7c4c1 100644
--- a/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.info.yml
+++ b/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Bootstrap'
 type: module
 description: 'Helps support Webform to Bootstrap integration.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.module b/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.module
index fa615a8815..09c02cd2dc 100644
--- a/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.module
+++ b/web/modules/webform/modules/webform_bootstrap/webform_bootstrap.module
@@ -9,7 +9,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\webform\Utility\WebformArrayHelper;
 use Drupal\webform\Utility\WebformElementHelper;
-use Drupal\Core\Render\Element;
+use Drupal\webform_bootstrap\WebformBootstrapRenderCallbacks;
 
 /**
  * Implements hook_page_attachments().
@@ -35,19 +35,7 @@ function webform_bootstrap_webform_element_webform_terms_of_service_alter(array
  * Implements hook_webform_element_ELEMENT_TYPE_alter().
  */
 function webform_bootstrap_webform_element_webform_likert_alter(array &$element, \Drupal\Core\Form\FormStateInterface $form_state, array $context) {
-  $element['#pre_render'] = array_merge(['_webform_bootstrap_webform_element_webform_likert_pre_render'], $element['#pre_render']);
-}
-
-function _webform_bootstrap_webform_element_webform_likert_pre_render(array $element) {
-  foreach (Element::children($element) as $element_key) {
-    // Likerts allow description display to be configured, so disable
-    // smart description.
-    if (!empty($element[$element_key]['#description'])) {
-      $element[$element_key]['#smart_description'] = FALSE;
-    }
-    $element[$element_key] = _webform_bootstrap_webform_element_webform_likert_pre_render($element[$element_key]);
-  }
-  return $element;
+  $element['#pre_render'] = array_merge([[WebformBootstrapRenderCallbacks::class, 'webformLikertPreRender']], $element['#pre_render']);
 }
 
 /**
@@ -178,7 +166,7 @@ function webform_bootstrap_preprocess_input(&$variables) {
 }
 
 /**
- * Prepares variables for form element templates.
+ * Implements hook_preprocess_form_element() for form element templates.
  */
 function webform_bootstrap_preprocess_form_element(&$variables) {
   if (!_webform_bootstrap_is_active_theme()) {
diff --git a/web/modules/webform/modules/webform_cards/css/webform_cards.admin.css b/web/modules/webform/modules/webform_cards/css/webform_cards.admin.css
new file mode 100644
index 0000000000..ce4dba5ddc
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/css/webform_cards.admin.css
@@ -0,0 +1,25 @@
+/**
+ * @file
+ * Webform cards admin styles.
+ */
+
+/**
+ * Fix webform ui builder message and toggle weight placement.
+ */
+.webform-message + .tabledrag-toggle-weight-wrapper {
+  position: inherit;
+}
+
+.webform-message + .tabledrag-toggle-weight-wrapper > .tabledrag-toggle-weight {
+  position: inherit;
+}
+
+.webform-message[style="display: none;"] + .tabledrag-toggle-weight-wrapper,
+.webform-message.js-webform-message--close-storage + .tabledrag-toggle-weight-wrapper {
+  position: relative;
+}
+
+.webform-message[style="display: none;"] + .tabledrag-toggle-weight-wrapper > .tabledrag-toggle-weight,
+.webform-message.js-webform-message--close-storage + .tabledrag-toggle-weight-wrapper > .tabledrag-toggle-weight {
+  position: absolute;
+}
diff --git a/web/modules/webform/modules/webform_cards/css/webform_cards.css b/web/modules/webform/modules/webform_cards/css/webform_cards.css
new file mode 100644
index 0000000000..c6dbe6acea
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/css/webform_cards.css
@@ -0,0 +1,78 @@
+/**
+ * @file
+ * Webform cards styles.
+ */
+
+.webform-card {
+  border: 1px solid #ccc;
+  padding: 20px;
+  margin-bottom: 1em;
+}
+
+html.js .webform-card,
+html.js .webform-card[style*="display: block"] {
+  display: none !important;
+}
+
+html.js .webform-card.webform-card--active,
+html.js .webform-card.webform-card--error,
+html.js .webform-card.webform-card--active[style*="display: block"],
+html.js .webform-card.webform-card--error[style*="display: block"] {
+  display: block !important;
+}
+
+.webform-cards .webform-cards-button--previous,
+.webform-cards .webform-cards-button--next {
+  display: none;
+}
+
+.webform-preview .webform-card-edit {
+  display: none;
+}
+
+.webform-wizard-pages-links {
+  display: none;
+}
+
+/**
+ * Toggle.
+ */
+.webform-cards-toggle-wrapper {
+  text-align: right; /* LTR */
+}
+
+[dir="rtl"] .webform-cards-toggle-wrapper {
+  text-align: left;
+}
+
+.webform-cards-toggle-wrapper {
+  margin-top: 1em;
+}
+
+.webform-cards-toggle {
+  margin-top: 0;
+  padding: 0;
+  cursor: pointer;
+  border: 0;
+  background: transparent;
+  font-size: 1em;
+}
+
+.webform-cards-toggle {
+  text-decoration: none;
+  color: #337ab7;
+}
+
+.webform-cards-toggle:hover,
+.webform-cards-togglelink:focus {
+  text-decoration: underline;
+}
+
+html.js form.webform-cards-toggle-show .webform-card,
+html.js form.webform-cards-toggle-show .webform-card[style*="display: block"] {
+  display: block !important;
+}
+
+html.js form.webform-cards-toggle-show .webform-progress {
+  display: none;
+}
diff --git a/web/modules/webform/modules/webform_cards/js/webform_cards.admin.js b/web/modules/webform/modules/webform_cards/js/webform_cards.admin.js
new file mode 100644
index 0000000000..808032e2c2
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/js/webform_cards.admin.js
@@ -0,0 +1,40 @@
+/**
+ * @file
+ * JavaScript behaviors for webform cards admin.
+ */
+
+(function ($, Drupal) {
+
+  'use strict';
+
+  /**
+   * Webform cards administration.
+   *
+   * @type {Drupal~behavior}
+   */
+  Drupal.behaviors.webformCardsAdmin = {
+    attach: function (context) {
+      // Determine if the form is the context or it is within the context.
+      var $forms = $(context).is('form.webform-edit-form')
+        ? $(context)
+        : $('form.webform-edit-form', context);
+
+      $forms.once('webform-cards-admin').each(function () {
+        var $form = $(this);
+        if ($form.find('[data-webform-type="webform_wizard_page"]').length) {
+          $('#webform-ui-add-page').parent('li').show();
+          $('#webform-ui-add-card').parent('li').hide();
+        }
+        else if ($form.find('[data-webform-type="webform_card"]').length) {
+          $('#webform-ui-add-page').parent('li').hide();
+          $('#webform-ui-add-card').parent('li').show();
+        }
+        else {
+          $('#webform-ui-add-page').parent('li').show();
+          $('#webform-ui-add-card').parent('li').show();
+        }
+      });
+    }
+  };
+
+})(jQuery, Drupal);
diff --git a/web/modules/webform/modules/webform_cards/js/webform_cards.js b/web/modules/webform/modules/webform_cards/js/webform_cards.js
new file mode 100644
index 0000000000..76d2594abe
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/js/webform_cards.js
@@ -0,0 +1,641 @@
+/**
+ * @file
+ * JavaScript behaviors for webform cards.
+ */
+
+(function ($, Drupal) {
+
+  'use strict';
+
+  /**
+   * Initialize webform cards.
+   *
+   * @type {Drupal~behavior}
+   */
+  Drupal.behaviors.webformCards = {
+    attach: function (context) {
+      // Determine if the form is the context or it is within the context.
+      var $forms = $(context).is('form.webform-submission-form')
+        ? $(context)
+        : $('form.webform-submission-form', context);
+
+      $forms.once('webform-cards').each(function () {
+        // Form.
+        var $form = $(this);
+
+        // Options from data-* attributes.
+        var options = {
+          progressStates: $form[0].hasAttribute('data-progress-states'),
+          progressLink: $form[0].hasAttribute('data-progress-link'),
+          autoForward: $form[0].hasAttribute('data-auto-forward'),
+          previewLink: $form[0].hasAttribute('data-preview-link'),
+          confirmation: $form[0].hasAttribute('data-confirmation'),
+          track: $form.data('track'),
+          toggle: $form[0].hasAttribute('data-toggle'),
+          toggleHideLabel: $form.data('toggle-hide-label'),
+          toggleShowLabel: $form.data('toggle-show-label'),
+          ajaxEffect: $form.data('ajax-effect'),
+          ajaxSpeed: $form.data('ajax-speed')
+        };
+
+        var currentPage = $form.data('current-page');
+
+        // Progress.
+        var $progress = $('.webform-progress');
+
+        // Current card.
+        var $currentCardInput = $form.find(':input[name="current_card"]');
+
+        // Cards.
+        var $allCards = $form.find('.webform-card');
+
+        // Preview.
+        if (!$allCards.length) {
+          setPreviewLinks();
+          return;
+        }
+
+        // Display show/hide all cards link.
+        if (options.toggle) {
+          setToggle();
+        }
+
+        // Server-side validation errors.
+        // @see \Drupal\Core\Render\Element\RenderElement::setAttributes
+        var $invalidCards = $allCards.filter(':has(.form-item--error-message)');
+        if ($invalidCards.length) {
+          // Hide progress.
+          $form.find('.webform-progress').hide();
+          // Show invalid cards and shake'em.
+          $invalidCards
+            .addClass('webform-card--error')
+            .effect('shake', {distance: 10});
+          return;
+        }
+
+        // Actions, preview, and submit buttons.
+        var $formActions = $form.find('.form-actions');
+        var $previewButton = $formActions.find('.webform-button--preview');
+        var $submitButton = $formActions.find('.webform-button--submit');
+
+        // Previous and next buttons.
+        var $previousButton = $form.find('.webform-button--previous');
+        var $nextButton = $form.find('.webform-button--next');
+        $previousButton.data('default-label', $previousButton.val());
+        $nextButton.data('default-label', $nextButton.val());
+        $previousButton.on('click', previousButtonClickEventHandler).show();
+        $nextButton.on('click', nextButtonClickEventHandler).show();
+
+        // Auto-forward.
+        if (options.autoForward) {
+          // Auto-forward on enter.
+          $form.find('input')
+            .not(':button, :submit, :reset, :image, :file')
+            .on('keypress', function (event) {
+              if (event.which === 13) {
+                autoForwardEventHandler(event);
+                // Disable auto submit.
+                // @see Drupal.behaviors.webformDisableAutoSubmit
+                event.preventDefault();
+                return false;
+              }
+            });
+
+          // Auto-forward on change.
+          $form.find('select[data-images]:not([multiple]), input[type="range"].form-webform-rating')
+            .on('change', autoForwardEventHandler);
+
+          // Auto-forward radios with label.
+          $form.find('input:radio, label[for]')
+            .on('mouseup', function (event) {
+              var $radio = (event.target.tagName === 'LABEL')
+                ? $('#' + $(event.target).attr('for'))
+                : $(this);
+              if ($radio.is(':radio') && $radio.val() !== '_other_') {
+                setTimeout(function () {
+                  autoForwardEventHandler(event);
+                });
+              }
+            });
+        }
+
+        // Track when cards are hidden/shown via #states conditional logic.
+        if (options.progressStates) {
+          $(document).on('state:visible state:visible-slide', function stateVisibleEventHandler(e) {
+            if ($(e.target).hasClass('webform-card') && $.contains($form[0], e.target)) {
+              trackProgress();
+            }
+          });
+        }
+
+        initialize();
+
+        /* ****************************************************************** */
+        // Private functions.
+        /* ****************************************************************** */
+
+        /**
+         * Initialize the active card.
+         */
+        function initialize() {
+          var currentCard = $currentCardInput.val();
+          var $activeCard = currentCard ? $allCards.filter('[data-webform-key="' + currentCard + '"]') : [];
+          if (!$activeCard.length) {
+            $activeCard = $allCards.first();
+          }
+          setActiveCard($activeCard, true);
+        }
+
+        /**
+         * Set the active card.
+         *
+         * @param {jQuery} $activeCard
+         *   An jQuery object containing the active card.
+         * @param {boolean} initialize
+         *   Are cards being initialize
+         */
+        function setActiveCard($activeCard, initialize) {
+          if (!$activeCard.length) {
+            return;
+          }
+
+          // Unset the active card
+          $allCards.filter('.webform-card--active').removeClass('webform-card--active');
+
+          // Set the previous and next labels.
+          $previousButton.val($activeCard.data('prev-button-label') || $previousButton.data('default-label'));
+          $nextButton.val($activeCard.data('next-button-label') || $nextButton.data('default-label'));
+
+          // Show/hide the previous button.
+          var hasPrevCard = !!$activeCard.prevAll('.webform-card:not([style*="display: none"])').length;
+          $previousButton.toggle(hasPrevCard);
+
+          // Hide/show the next button and submit buttons.
+          var hasNextCard = !!$activeCard.nextAll('.webform-card:not([style*="display: none"])').length;
+          $previewButton.toggle(!hasNextCard);
+          $submitButton.toggle(!hasNextCard);
+          $nextButton.toggle(hasNextCard);
+
+          // Activate the card.
+          $activeCard.addClass('webform-card--active');
+
+          // Show the active card.
+          if (!initialize) {
+            applyAjaxEffect($activeCard);
+          }
+
+          // Focus the active card's first visible input.
+          if (!initialize || $form.hasClass('js-webform-autofocus')) {
+            $activeCard.find(':input:visible').first().focus();
+          }
+
+          // Set current page.
+          $currentCardInput.val($activeCard.data('webform-key'));
+
+          // Track the current page in a form data attribute and the URL.
+          trackCurrentPage($activeCard);
+
+          // Track progress.
+          trackProgress();
+        }
+
+        /**
+         * Track the current page in a form data attribute and the URL.
+         *
+         * @param {jQuery} $activeCard
+         *   An jQuery object containing the active card.
+         *
+         * @see \Drupal\webform\WebformSubmissionForm::form
+         * @see Drupal.behaviors.webformWizardTrackPage
+         */
+        function trackCurrentPage($activeCard) {
+          if (!options.track) {
+            return;
+          }
+
+          var page = (options.track === 'index')
+            ? ($allCards.index($activeCard) + 1)
+            : $activeCard.data('webform-key');
+
+          // Set form data attribute.
+          $form.data('webform-wizard-current-page', page);
+
+          // Set URL
+          var url = window.location.toString();
+          var regex = /([?&])page=[^?&]+/;
+          if (url.match(regex)) {
+            url = url.replace(regex, '$1page=' + page);
+          }
+          else {
+            url = url + (url.indexOf('?') !== -1 ? '&page=' : '?page=') + page;
+          }
+          window.history.replaceState(null, null, url);
+        }
+
+        /**
+         * Track progress.
+         *
+         * @see webform/templates/webform-progress.html.twig
+         * @see webform/templates/webform-progress-tracker.html.twig
+         */
+        function trackProgress() {
+          // Hide/show cards and update steps.
+          var cards = getCardsProgressSteps();
+          for (var i = 0; i < cards.length; i++) {
+            var card = cards[i];
+            var cardAttributeName = '[data-webform-' + card.type + '="' + card.key + '"]';
+
+            var $cardStep = $progress.find(cardAttributeName);
+
+            // Set card and page step.
+            $cardStep.find('[data-webform-progress-step]').html(card.step);
+            if (card.type === 'page') {
+              continue;
+            }
+
+            // Hide/show card step.
+            $cardStep.toggle(!card.hidden);
+
+            // Set .is-active and .is-complete classes.
+            $cardStep.toggleClass('is-active', card.active);
+            $cardStep.toggleClass('is-complete', !card.active && card.complete);
+
+            // Set 'Current' and 'Complete' state.
+            var $cardState = $cardStep.find('[data-webform-progress-state]');
+            $cardState.toggle(card.active || card.complete);
+            if (card.active) {
+              $cardState.html(Drupal.t('Current'));
+            }
+            if (card.complete) {
+              $cardState.html(Drupal.t('Complete'));
+            }
+
+            // Link card step.
+            if (options.progressLink) {
+              var $links = $cardStep.find('[data-webform-progress-link]');
+              $links.data('webform-key', card.key);
+              if (card.complete) {
+                if ($links.attr('role') !== 'link') {
+                  $links
+                    .attr({'role': 'link', 'title': card.title, 'aria-label': card.title, 'tabindex': '0'})
+                    .click(function () {
+                      var $card = $allCards.filter('[data-webform-key="' + $(this).data('webform-key') + '"]');
+                      setActiveCard($card);
+                    })
+                    .keydown(function (event) {
+                      if (event.which === 13) {
+                        var $card = $allCards.filter('[data-webform-key="' + $(this).data('webform-key') + '"]');
+                        setActiveCard($card);
+                      }
+                    });
+                }
+              }
+              else if ($links.attr('role') === 'link') {
+                $links.removeAttr('role title aria-label tabindex')
+                  .off('click keydown');
+              }
+            }
+          }
+
+          // Set properties.
+          var properties = getCardsProgressProperties();
+          for (var property in properties) {
+            var attribute = '[data-webform-progress-' + property + ']';
+            var value = properties[property];
+            $progress.find(attribute).html(value);
+          }
+
+          // Set <progress> tag [value] and [max] attributes.
+          $progress.find('progress').attr({
+            value: properties.index,
+            max: properties.total
+          });
+        }
+
+        /**
+         * Set show/hide all cards toggle button.
+         */
+        function setToggle() {
+          var $toggle = $('<button type="button" class="webform-cards-toggle"></button>')
+            .html(options.toggleShowLabel)
+            .on('click', toggleEventHandler)
+            .wrap('<div class="webform-cards-toggle-wrapper"></div>')
+            .parent();
+          $allCards.eq(0).before($toggle);
+        }
+
+        /**
+         * Set links to previous pages/cards in preview.
+         */
+        function setPreviewLinks() {
+          if (currentPage !== 'webform_preview' || !$form.find('.webform-preview').length) {
+            return;
+          }
+
+          var $button = $form.find('.js-webform-wizard-pages-link[data-webform-page="webform_start"]');
+
+          // Link to previous pages in progress steps (aka bar).
+          if (options.progressLink) {
+            $progress.find('[data-webform-card]').each(function () {
+              var $step = $(this);
+              var card = $step.data('webform-card');
+              var title = $step.attr('title');
+              $step
+                .find('[data-webform-progress-link]')
+                .attr({'role': 'link', 'title': title, 'aria-label': title, 'tabindex': '0'})
+                .click(function () {
+                  // Set current card.
+                  $currentCardInput.val(card);
+                  // Click button to return to the 'webform_start' page.
+                  $button.click();
+                })
+                .keydown(function (event) {
+                  if (event.which === 13) {
+                    $(this).click();
+                  }
+                });
+            });
+          }
+
+          // Link to previous pages in preview.
+          if (options.previewLink) {
+            $form
+              .find('.webform-card-edit[data-webform-card]')
+              .each(function appendEditButton() {
+                var $card = $(this);
+
+                var card = $card.data('webform-card');
+                var title = $card.attr('title');
+
+                var $cardButton = $button.clone();
+                $cardButton
+                  .removeAttr('data-webform-page data-msg-required')
+                  .attr('id', $cardButton.attr('id') + '-' + card)
+                  .attr('name', $cardButton.attr('name') + '-' + card)
+                  .attr('data-drupal-selector', $cardButton.attr('data-drupal-selector') + '-' + card)
+                  .attr('title', Drupal.t("Edit '@title'", {'@title': title}).toString())
+                  .click(function () {
+                    // Set current card.
+                    $currentCardInput.val(card);
+                    // Click button to return to the 'webform_start' page.
+                    $button.click();
+                    return false;
+                  });
+                $card.append($cardButton).show();
+              });
+          }
+        }
+
+        /**
+         * Get cards progress properties.
+         *
+         * Properties include index, total, percentage, and summary.
+         *
+         * @return {{summary: string, total: number, percentage: string,
+         *   index: *}} Cards progress properties.
+         */
+        function getCardsProgressProperties() {
+          var $activeCard = $allCards.filter('.webform-card--active');
+
+          var $visibleCards = $allCards.filter(':not([style*="display: none"])');
+
+          var index = (currentPage === 'webform_preview')
+            ? $visibleCards.length + 1
+            : $visibleCards.index($activeCard);
+
+          var total = $visibleCards.length
+            + ($previewButton.length ? 1 : 0)
+            + (options.confirmation ? 1 : 0);
+
+          var percentage = Math.round((index / (total - 1)) * 100);
+
+          var summary = Drupal.t(
+            '@index of @total',
+            {'@index': index + 1, '@total': total}
+          );
+
+          return {
+            index: index + 1,
+            total: total,
+            percentage: percentage + '%',
+            summary: summary
+          };
+        }
+
+        /**
+         * Get cards as progress steps.
+         *
+         * @return {[]}
+         *   Cards as progress steps.
+         */
+        function getCardsProgressSteps() {
+          var $activeCard = $allCards.filter('.webform-card--active');
+          var activeKey = $activeCard.data('webform-key');
+
+          var cards = [];
+
+          // Append cards.
+          var step = 0;
+          var isComplete = true;
+          $allCards.each(function () {
+            var $card = $(this);
+            var key = $card.data('webform-key');
+            var title = $card.data('title');
+
+            // Set active and complete classes.
+            var isActive = (activeKey === key);
+            if (isActive) {
+              isComplete = false;
+            }
+
+            // Hide/show progress based on conditional logic.
+            var isHidden = false;
+            if (options.progressStates) {
+              isHidden = $card.is('[style*="display: none"]');
+              if (!isHidden) {
+                step++;
+              }
+            }
+            else {
+              step++;
+            }
+
+            cards.push({
+              type: 'card',
+              key: key,
+              title: title,
+              step: isHidden ? null : step,
+              hidden: isHidden,
+              active: isActive,
+              complete: isComplete
+            });
+          });
+
+          // Append preview and confirmation pages.
+          $(['webform_preview', 'webform_confirmation']).each(function () {
+            var $progressStep = $form.find('[data-webform-progress-steps] [data-webform-page="' + this + '"]');
+            if ($progressStep.length) {
+              step++;
+              cards.push({
+                type: 'page',
+                key: this,
+                step: step
+              });
+            }
+          });
+          return cards;
+        }
+
+        /**
+         * Apply Ajax effect to elements.
+         *
+         * @param {jQuery} $elements
+         *   An jQuery object containing elements to be displayed.
+         */
+        function applyAjaxEffect($elements) {
+          switch (options.ajaxEffect) {
+            case 'fade':
+              $elements.hide().fadeIn(options.ajaxSpeed);
+              break;
+
+            case 'slide':
+              $elements.hide().slideDown(options.ajaxSpeed);
+              break;
+          }
+        }
+
+        /**********************************************************************/
+        // Event handlers.
+        /**********************************************************************/
+
+        /**
+         * Toggle event handler.
+         *
+         * @param {jQuery.Event} event
+         *   The event triggered.
+         */
+        function toggleEventHandler(event) {
+          if ($form.hasClass('webform-cards-toggle-show')) {
+            $form.removeClass('webform-cards-toggle-show');
+            $(this)
+              .attr('title', options.toggleShowLabel)
+              .html(options.toggleShowLabel);
+            var $activeCard = $allCards.filter('.webform-card--active');
+            setActiveCard($activeCard);
+          }
+          else {
+            $form.addClass('webform-cards-toggle-show');
+            $(this)
+              .attr('title', options.toggleHideLabel)
+              .html(options.toggleHideLabel);
+            var $visibleCards = $allCards.filter(':not([style*="display: none"])');
+            applyAjaxEffect($visibleCards);
+            $nextButton.hide();
+            $previousButton.hide();
+            $previewButton.show();
+            $submitButton.show();
+          }
+        }
+
+        /**
+         * Previous button event handler.
+         *
+         * @param {jQuery.Event} event
+         *   The event triggered.
+         */
+        function previousButtonClickEventHandler(event) {
+          // Get previous visible card (not "display: none").
+          var $previousCard = $allCards.filter('.webform-card--active')
+            .prevAll('.webform-card:not([style*="display: none"])')
+            .first();
+          setActiveCard($previousCard);
+          // Prevent the button's default behavior.
+          event.preventDefault();
+        }
+
+        /**
+         * Next button event handler.
+         *
+         * @param {jQuery.Event} event
+         *   The event triggered.
+         */
+        function nextButtonClickEventHandler(event) {
+          var validator = $form.validate();
+          if (!$form.valid()) {
+            // Focus first invalid input.
+            validator.focusInvalid();
+            // Shake the invalid card.
+            var $activeCard = $allCards.filter('.webform-card--active');
+            $activeCard.effect('shake', {distance: 10});
+          }
+          else {
+            // Get next visible card (not "display: none").
+            var $nextCard = $allCards.filter('.webform-card--active')
+              .nextAll('.webform-card:not([style*="display: none"])')
+              .first();
+            if ($nextCard.length) {
+              setActiveCard($nextCard);
+            }
+            else if ($previewButton.length) {
+              $previewButton.click();
+            }
+            else {
+              $submitButton.click();
+            }
+          }
+          // Prevent the button's default behavior.
+          event.preventDefault();
+        }
+
+        /**
+         * Auto forward event handler.
+         *
+         * @param {jQuery.Event} event
+         *   The event triggered.
+         */
+        function autoForwardEventHandler(event) {
+          if ($form.hasClass('webform-cards-toggle-show')) {
+            return;
+          }
+
+          var $activeCard = $allCards.filter('.webform-card--active');
+          var $allInputs = $activeCard.find('input:visible, select:visible, textarea:visible');
+          var $autoForwardInputs = $activeCard.find('input:visible, select:visible');
+          if (!$autoForwardInputs.length || $allInputs.length !== $autoForwardInputs.length) {
+            return;
+          }
+
+          var inputValues = [];
+          $autoForwardInputs.each(function () {
+            var name = this.name;
+            if (!(name in inputValues)) {
+              inputValues[name] = false;
+            }
+            if (this.type === 'radio' && this.checked) {
+              inputValues[name] = true;
+            }
+            else if (this.type === 'select' && this.selectedIndex !== -1) {
+              inputValues[name] = true;
+            }
+            else if (this.type === 'range' && this.value) {
+              inputValues[name] = true;
+            }
+          });
+
+          // Only auto-forward when a single input is visible.
+          if (Object.keys(inputValues).length > 1) {
+            return;
+          }
+
+          var inputHasValue = inputValues.every(function (value) {
+            return value;
+          });
+          if (inputHasValue) {
+            $nextButton.click();
+          }
+        }
+      });
+    }
+  };
+
+})(jQuery, Drupal);
diff --git a/web/modules/webform/modules/webform_cards/src/Element/WebformCard.php b/web/modules/webform/modules/webform_cards/src/Element/WebformCard.php
new file mode 100644
index 0000000000..5457e6344a
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/src/Element/WebformCard.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Drupal\webform_cards\Element;
+
+use Drupal\Core\Render\Element\RenderElement;
+
+/**
+ * Provides a render element for a card container.
+ *
+ * @RenderElement("webform_card")
+ */
+class WebformCard extends RenderElement {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInfo() {
+    $class = get_class($this);
+    return [
+      '#prev_button_label' => '',
+      '#next_button_label' => '',
+      '#process' => [
+        [$class, 'processGroup'],
+        [$class, 'processAjaxForm'],
+      ],
+      '#pre_render' => [
+        [$class, 'preRenderWebformCard'],
+        [$class, 'preRenderGroup'],
+      ],
+      '#value' => NULL,
+      '#theme_wrappers' => ['webform_card'],
+    ];
+  }
+
+  /**
+   * Adds form element theming to webform card.
+   *
+   * @param array $element
+   *   An associative array containing the properties and children of the
+   *   webform card.
+   *
+   * @return array
+   *   The modified element.
+   */
+  public static function preRenderWebformCard(array $element) {
+    $element['#attributes']['data-title'] = $element['#title'];
+    if ($element['#webform_key']) {
+      $element['#attributes']['data-webform-key'] = $element['#webform_key'];
+    }
+    if ($element['#prev_button_label']) {
+      $element['#attributes']['data-prev-button-label'] = $element['#prev_button_label'];
+    }
+    if ($element['#next_button_label']) {
+      $element['#attributes']['data-next-button-label'] = $element['#next_button_label'];
+    }
+    return $element;
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/src/Form/WebformCardsConvertForm.php b/web/modules/webform/modules/webform_cards/src/Form/WebformCardsConvertForm.php
new file mode 100644
index 0000000000..cdcdc903cf
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/src/Form/WebformCardsConvertForm.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace Drupal\webform_cards\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Serialization\Yaml;
+use Drupal\webform\Entity\Webform;
+use Drupal\webform\WebformInterface;
+
+/**
+ * Form for converting wizard pages to cards.
+ */
+class WebformCardsConvertForm extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'webform_cards_convert_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state, WebformInterface $webform = NULL) {
+    $form['#title'] = $this->t('Convert @title wizard pages to cards', ['@title' => $webform->label()]);
+    $form['webform_id'] = [
+      '#type' => 'value',
+      '#value' => $webform->id(),
+    ];
+    $form['warning'] = [
+      '#type' => 'webform_message',
+      '#message_message' => '<strong>' . $this->t('Webform cards support is an experimental module/feature.') . '</strong><br/>'
+        . $this->t('Please make sure to test the converted webform on a staging server before using cards in production.'),
+      '#message_type' => 'warning',
+    ];
+    $form['description'] = [
+      '#markup' => '<p>' . $this->t('Cards provide an almost identical user experience to wizard pages, but moving between cards is much faster. Cards use JavaScript for pagination and client-side validation. Cards also support auto-forwarding with conditional logic.') . '</p>' .
+        '<p><em>' . $this->t('Please note: More complex webform elements may still require server-side validation.') . '</em></p>',
+    ];
+    $form['hr'] = ['#markup' => '<p><hr/></p>'];
+    $form['confirm'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t("Please confirm that you want to convert this webform's wizard pages to cards"),
+      '#required' => TRUE,
+    ];
+
+    $form['actions'] = ['#type' => 'actions'];
+    $form['actions']['submit'] = [
+      '#type' => 'submit',
+      '#value' => $this->t('Convert'),
+      '#button_type' => 'primary',
+    ];
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    /** @var \Drupal\webform\WebformInterface $webform */
+    $webform = Webform::load($form_state->getValue('webform_id'));
+    $elements = $webform->getElementsRaw();
+    $elements = str_replace("'#type': webform_wizard_page", "'#type': webform_card", $elements);
+    $webform->setElements(Yaml::decode($elements));
+    $webform->save();
+
+    $this->messenger()->addStatus($this->t('Wizard pages have been successfully converted to cards.'));
+    $form_state->setRedirectUrl($webform->toUrl('edit-form'));
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/src/Plugin/WebformElement/WebformCard.php b/web/modules/webform/modules/webform_cards/src/Plugin/WebformElement/WebformCard.php
new file mode 100644
index 0000000000..f0c0932f55
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/src/Plugin/WebformElement/WebformCard.php
@@ -0,0 +1,142 @@
+<?php
+
+namespace Drupal\webform_cards\Plugin\WebformElement;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\webform\Plugin\WebformElement\ContainerBase;
+use Drupal\webform\WebformSubmissionInterface;
+
+/**
+ * Provides a 'card' element.
+ *
+ * @WebformElement(
+ *   id = "webform_card",
+ *   label = @Translation("Card"),
+ *   description = @Translation("Provides an element for a fast clientside pagination."),
+ *   category = @Translation("Cards"),
+ *   hidden = TRUE,
+ * )
+ */
+class WebformCard extends ContainerBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineDefaultProperties() {
+    $properties = [
+      'title' => '',
+      'title_tag' => \Drupal::config('webform.settings')->get('element.default_section_title_tag'),
+      'title_display' => '',
+      'title_attributes' => [],
+      'prev_button_label' => '',
+      'next_button_label' => '',
+      // Submission display.
+      'format' => $this->getItemDefaultFormat(),
+      'format_html' => '',
+      'format_text' => '',
+      'format_attributes' => [],
+    ] + $this->defineDefaultBaseProperties();
+    unset($properties['flex']);
+    return $properties;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineTranslatableProperties() {
+    return array_merge(parent::defineTranslatableProperties(), ['prev_button_label', 'next_button_label']);
+  }
+
+  /****************************************************************************/
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isRoot() {
+    return TRUE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getItemDefaultFormat() {
+    return 'details';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
+    parent::prepare($element, $webform_submission);
+
+    if (empty($element['#title_tag'])) {
+      $element['#title_tag'] = $this->getDefaultProperty('title_tag');
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function formatHtmlItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $build = parent::formatHtmlItem($element, $webform_submission, $options);
+
+    // Add edit page link container to preview.
+    // @see Drupal.behaviors.webformCards
+    if ($build && isset($options['view_mode']) && $options['view_mode'] === 'preview' && $webform_submission->getWebform()->getSetting('wizard_preview_link')) {
+      $build['#children']['wizard_page_link'] = [
+        '#type' => 'container',
+        '#attributes' => [
+          'title' => $element['#title'],
+          'class' => ['webform-card-edit'],
+          'data-webform-card' => $element['#webform_key'],
+        ],
+      ];
+    }
+
+    return $build;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    $form = parent::form($form, $form_state);
+
+    /** @var \Drupal\webform\WebformInterface $webform */
+    $webform = $form_state->getFormObject()->getWebform();
+
+    $form['card'] = [
+      '#type' => 'fieldset',
+      '#title' => $this->t('Card settings'),
+    ];
+    $form['card']['title_tag'] = [
+      '#type' => 'webform_select_other',
+      '#title' => $this->t('Title tag'),
+      '#description' => $this->t("The card's title HTML tag."),
+      '#options' => [
+        'h1' => $this->t('Header 1 (h1)'),
+        'h2' => $this->t('Header 2 (h2)'),
+        'h3' => $this->t('Header 3 (h3)'),
+        'h4' => $this->t('Header 4 (h4)'),
+        'h5' => $this->t('Header 5 (h5)'),
+        'h6' => $this->t('Header 6 (h6)'),
+        'label' => $this->t('Label (label)'),
+      ],
+    ];
+    $form['card']['prev_button_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Previous page button label'),
+      '#description' => $this->t('This is used for the Next Page button on the card.') . '<br /><br />' .
+      $this->t('Defaults to: %value', ['%value' => $webform->getSetting('wizard_prev_button_label', TRUE)]),
+    ];
+    $form['card']['next_button_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Next page button label'),
+      '#description' => $this->t('This is used for the Previous button on the card.') . '<br /><br />' .
+      $this->t('Defaults to: %value', ['%value' => $webform->getSetting('wizard_next_button_label', TRUE)]),
+    ];
+
+    return $form;
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/src/Routing/WebformCardsRouteSubscriber.php b/web/modules/webform/modules/webform_cards/src/Routing/WebformCardsRouteSubscriber.php
new file mode 100644
index 0000000000..a80ef06408
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/src/Routing/WebformCardsRouteSubscriber.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\webform_cards\Routing;
+
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Routing\RouteSubscriberBase;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * Remove webform cards routes.
+ */
+class WebformCardsRouteSubscriber extends RouteSubscriberBase {
+
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * Constructs a WebformCardsRouteSubscriber object.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   */
+  public function __construct(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function alterRoutes(RouteCollection $collection) {
+    if (!$this->moduleHandler->moduleExists('webform_ui')) {
+      $collection->remove('entity.webform_ui.element.add_card');
+    }
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/src/WebformCardsManager.php b/web/modules/webform/modules/webform_cards/src/WebformCardsManager.php
new file mode 100644
index 0000000000..5c68e725bb
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/src/WebformCardsManager.php
@@ -0,0 +1,130 @@
+<?php
+
+namespace Drupal\webform_cards;
+
+use Drupal\webform\Plugin\WebformElementManagerInterface;
+use Drupal\webform\WebformInterface;
+use Drupal\webform\WebformSubmissionConditionsValidatorInterface;
+use Drupal\webform\WebformSubmissionInterface;
+use Drupal\webform_cards\Plugin\WebformElement\WebformCard;
+
+/**
+ * Manage webform cards.
+ */
+class WebformCardsManager implements WebformCardsManagerInterface {
+
+  /**
+   * The webform element manager.
+   *
+   * @var \Drupal\webform\Plugin\WebformElementManagerInterface
+   */
+  protected $elementManager;
+
+  /**
+   * The webform submission (server-side) conditions (#states) validator.
+   *
+   * @var \Drupal\webform\WebformSubmissionConditionsValidator
+   */
+  protected $conditionsValidator;
+
+  /**
+   * Constructs a WebformCardsManager object.
+   *
+   * @param \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager
+   *   The webform element manager.
+   * @param \Drupal\webform\WebformSubmissionConditionsValidatorInterface $conditions_validator
+   *   The webform submission conditions (#states) validator.
+   */
+  public function __construct(WebformElementManagerInterface $element_manager, WebformSubmissionConditionsValidatorInterface $conditions_validator) {
+    $this->elementManager = $element_manager;
+    $this->conditionsValidator = $conditions_validator;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasCards(WebformInterface $webform) {
+    return (strpos($webform->getElementsRaw(), "'#type': webform_card") !== FALSE);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildPages(WebformInterface $webform, $operation = 'default') {
+    $card_properties = [
+      '#title' => '#title',
+      '#states' => '#states',
+    ];
+
+    $pages = [];
+
+    // Add webform cards.
+    $elements = $webform->getElementsInitialized();
+    if (is_array($elements) && !in_array($operation, ['edit_all', 'api'])) {
+      foreach ($elements as $key => $element) {
+        if (!isset($element['#type'])) {
+          continue;
+        }
+
+        /** @var \Drupal\webform\Plugin\WebformElementInterface $element_plugin */
+        $element_plugin = $this->elementManager->getElementInstance($element, $webform);
+        if (!($element_plugin instanceof WebformCard)) {
+          continue;
+        }
+
+        // Check element access rules and only include pages that are visible
+        // to the current user.
+        $access_operation = (in_array($operation, ['default', 'add'])) ? 'create' : 'update';
+        if ($element_plugin->checkAccessRules($access_operation, $element)) {
+          $pages[$key] = array_intersect_key($element, $card_properties) + [
+            '#type' => 'card',
+            '#access' => TRUE,
+          ];
+        }
+      }
+    }
+
+    // Add preview.
+    if ($webform->getSetting('preview') !== DRUPAL_DISABLED) {
+      $pages[WebformInterface::PAGE_PREVIEW] = [
+        '#title' => $webform->getSetting('preview_label', TRUE),
+        '#type' => 'page',
+        '#access' => TRUE,
+      ];
+    }
+
+    // Add confirmation.
+    if ($webform->getSetting('wizard_confirmation')) {
+      $pages[WebformInterface::PAGE_CONFIRMATION] = [
+        '#title' => $webform->getSetting('wizard_confirmation_label', TRUE),
+        '#type' => 'page',
+        '#access' => TRUE,
+      ];
+    }
+
+    return $pages;
+  }
+
+  /**
+   * Update cards pages based on conditional logic (#states).
+   *
+   * @param array $pages
+   *   An associative array of webform cards.
+   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
+   *   A webform submission.
+   *
+   * @return array
+   *   An associative array of webform cards with conditional logic applied.
+   *
+   * @see \Drupal\webform\Entity\Webform::getPages
+   */
+  public function applyConditions(array $pages, WebformSubmissionInterface $webform_submission = NULL) {
+    if ($webform_submission && $webform_submission->getWebform()->getSetting('wizard_progress_states')) {
+      return $this->conditionsValidator->buildPages($pages, $webform_submission);
+    }
+    else {
+      return $pages;
+    }
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/src/WebformCardsManagerInterface.php b/web/modules/webform/modules/webform_cards/src/WebformCardsManagerInterface.php
new file mode 100644
index 0000000000..7020b027eb
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/src/WebformCardsManagerInterface.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Drupal\webform_cards;
+
+use Drupal\webform\WebformInterface;
+use Drupal\webform\WebformSubmissionInterface;
+
+/**
+ * Interface for webform cards manager.
+ */
+interface WebformCardsManagerInterface {
+
+  /**
+   * Determine if a webform has cards.
+   *
+   * @param \Drupal\webform\WebformInterface $webform
+   *   A webform.
+   *
+   * @return bool
+   *   TRUE if a webform has cards.
+   */
+  public function hasCards(WebformInterface $webform);
+
+  /**
+   * Build webform's cards based on the current operation.
+   *
+   * @param \Drupal\webform\WebformInterface $webform
+   *   A webform.
+   * @param string $operation
+   *   The webform submission operation.
+   *   Usually 'default', 'add', 'edit', 'edit_all', 'api', or 'test'.
+   *
+   * @return array
+   *   An associative array of webform cards.
+   *
+   * @see \Drupal\webform\Entity\Webform::buildPages
+   */
+  public function buildPages(WebformInterface $webform, $operation = 'default');
+
+  /**
+   * Update cards pages based on conditional logic (#states).
+   *
+   * @param array $pages
+   *   An associative array of webform cards.
+   * @param \Drupal\webform\WebformSubmissionInterface|null $webform_submission
+   *   A webform submission.
+   *
+   * @return array
+   *   An associative array of webform cards with conditional logic applied.
+   *
+   * @see \Drupal\webform\Entity\Webform::getPages
+   */
+  public function applyConditions(array $pages, WebformSubmissionInterface $webform_submission = NULL);
+
+}
diff --git a/web/modules/webform/modules/webform_cards/templates/webform-card.html.twig b/web/modules/webform/modules/webform_cards/templates/webform-card.html.twig
new file mode 100644
index 0000000000..34c92e944b
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/templates/webform-card.html.twig
@@ -0,0 +1,52 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a webform section element and its children.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the <section> element.
+ * - title: The title/header of the section header.
+ * - title_attributes: HTML attributes to apply to the title/header element.
+ * - description: The description element containing the following properties:
+ *   - content: The description content of the <div>.
+ *   - attributes: HTML attributes to apply to the description container.
+ * - children: The rendered child elements of the <div>.
+ * - prefix: The content to add before the .section-wrapper children.
+ * - suffix: The content to add after the .section-wrapper children.
+ *
+ * Copied from: fieldset.html.twig
+ *
+ * @see template_preprocess_webform_section()
+ *
+ * @ingroup themeable
+ */
+#}
+{%
+  set classes = [
+    'js-form-wrapper',
+    'form-wrapper',
+    'webform-card',
+  ]
+%}
+<section{{ attributes.addClass(classes) }}>
+  {%
+    set title_classes = [
+      'webform-card-title',
+    ]
+  %}
+  {% if title %}
+    <{{ title_tag }}{{ title_attributes.addClass(title_classes) }}>{{ title }}</{{ title_tag }}>
+  {% endif %}
+  <div class="webform-card-wrapper">
+    {% if description.content %}
+      <div{{ description.attributes.addClass('description') }}>{{ description.content }}</div>
+    {% endif %}
+    {% if prefix %}
+      <span class="field-prefix">{{ prefix }}</span>
+    {% endif %}
+    {{ children }}
+    {% if suffix %}
+      <span class="field-suffix">{{ suffix }}</span>
+    {% endif %}
+  </div>
+</section>
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_access.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_access.yml
new file mode 100644
index 0000000000..a5b92e45af
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_access.yml
@@ -0,0 +1,239 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_access
+title: 'Test: Webform: Cards access'
+description: 'Test cards with page specific access rules.'
+category: 'Test: Cards'
+elements: |
+  page_all:
+    '#title': All
+    '#type': webform_card
+    textfield_all:
+      '#type': textfield
+      '#title': textfield_all
+      '#default_value': '{textfield_all}'
+  page_anonymous:
+    '#type': webform_card
+    '#title': Anonymous
+    '#access_create_roles':
+      - anonymous
+    '#access_update_roles':
+      - anonymous
+    '#access_view_roles':
+      - anonymous
+    textfield_anonymous:
+      '#type': textfield
+      '#title': textfield_anonymous
+      '#default_value': '{textfield_anonymous}'
+  page_authenticated:
+    '#type': webform_card
+    '#title': Authenticated
+    '#access_create_roles':
+      - authenticated
+    '#access_update_roles':
+      - authenticated
+    '#access_view_roles':
+      - authenticated
+    textfield_authenticated:
+      '#type': textfield
+      '#title': textfield_authenticated
+      '#default_value': '{textfield_authenticated}'
+  page_private:
+    '#type': webform_card
+    '#title': Private
+    '#private': true
+    textfield_private:
+      '#type': textfield
+      '#title': textfield_private
+      '#default_value': '{textfield_private}'
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_progress_link: false
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_ajax.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_ajax.yml
new file mode 100644
index 0000000000..06ae63d004
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_ajax.yml
@@ -0,0 +1,208 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_ajax
+title: 'Test: Webform: Cards Ajax'
+description: 'Test cards progress ajax support.'
+category: 'Test: Cards'
+elements: |
+  card_1:
+    '#type': webform_card
+    '#title': 'Card 1'
+    element_1:
+      '#type': textfield
+      '#title': 'Element 1'
+      '#default_value': '{element_1}'
+  card_2:
+    '#type': webform_card
+    '#title': 'Card 2'
+    element_2:
+      '#type': textfield
+      '#title': 'Element 2'
+      '#default_value': '{element_2}'
+
+css: ''
+javascript: ''
+settings:
+  ajax: true
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: true
+  wizard_progress_percentage: true
+  wizard_progress_link: true
+  wizard_progress_states: true
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: true
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 2
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: all
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: inline
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_auto_forward.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_auto_forward.yml
new file mode 100644
index 0000000000..0d5a366021
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_auto_forward.yml
@@ -0,0 +1,270 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_auto_forward
+title: 'Test: Webform: Cards auto-forward'
+description: 'Test cards progress auto_forward.'
+category: 'Test: Cards'
+elements: |
+  textfield_example:
+    '#type': webform_card
+    '#title': 'Textfield'
+    textfield:
+      '#type': textfield
+      '#title': 'Text field'
+  radios_example:
+    '#type': webform_card
+    '#title': 'Radios'
+    radios:
+      '#type': radios
+      '#title': 'Radios'
+      '#options':
+        one: One
+        two: Two
+        three: Three
+      '#options_display': buttons
+  radios_other_example:
+    '#type': webform_card
+    '#title': 'Radios other'
+    radios_other:
+      '#type': webform_radios_other
+      '#title': 'Radios other'
+      '#options':
+        one: One
+        two: Two
+        three: Three
+      '#options_display': buttons
+  scale_example:
+    '#type': webform_card
+    '#title': 'Scale'
+    scale:
+      '#type': webform_scale
+      '#title': 'Scale'
+  rating_example:
+    '#type': webform_card
+    '#title': 'Rating'
+    rating:
+      '#type': webform_rating
+      '#title': 'Rating'
+  image_select_example:
+    '#type': webform_card
+    '#title': 'Image select'
+    image_select:
+      '#type': webform_image_select
+      '#title': 'Image select'
+      '#show_label': true
+      '#images':
+        kitten_1:
+          text: 'Cute Kitten 1'
+          src: 'http://placekitten.com/220/200'
+        kitten_2:
+          text: 'Cute Kitten 2'
+          src: 'http://placekitten.com/180/200'
+        kitten_3:
+          text: 'Cute Kitten 3'
+          src: 'http://placekitten.com/130/200'
+  radios_multiple_example:
+    '#type': webform_card
+    '#title': 'Radios multiple'
+    radios_multiple_1:
+      '#type': radios
+      '#title': 'Radios 1'
+      '#options':
+        one: One
+        two: Two
+        three: Three
+      '#options_display': buttons
+    radios_multiple_2:
+      '#type': radios
+      '#title': 'Radios 2'
+      '#options':
+        one: One
+        two: Two
+        three: Three
+      '#options_display': buttons
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: true
+  wizard_progress_percentage: true
+  wizard_progress_link: true
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: true
+  wizard_confirmation: false
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: all
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_draft.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_draft.yml
new file mode 100644
index 0000000000..41d5c2d358
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_draft.yml
@@ -0,0 +1,208 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_draft
+title: 'Test: Webform: Cards draft'
+description: 'Test cards progress with draft.'
+category: 'Test: Cards'
+elements: |
+  card_1:
+    '#type': webform_card
+    '#title': 'Card 1'
+    element_1:
+      '#type': textfield
+      '#title': 'Element 1'
+      '#default_value': '{element_1}'
+  card_2:
+    '#type': webform_card
+    '#title': 'Card 2'
+    element_2:
+      '#type': textfield
+      '#title': 'Element 2'
+      '#default_value': '{element_2}'
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: true
+  wizard_progress_percentage: true
+  wizard_progress_link: true
+  wizard_progress_states: true
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: true
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 2
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: all
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_long_100.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_long_100.yml
new file mode 100644
index 0000000000..a94d7db950
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_long_100.yml
@@ -0,0 +1,794 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_long_100
+title: 'Test: Webform: Cards: Long - 100 cards'
+description: 'Test form with 100 cards'
+category: 'Test: Cards'
+elements: |
+  card_1:
+    '#type': webform_card
+    '#title': 'Card #1'
+    element_1:
+      '#type': textfield
+      '#title': 'Element #1'
+  card_2:
+    '#type': webform_card
+    '#title': 'Card #2'
+    element_2:
+      '#type': textfield
+      '#title': 'Element #2'
+  card_3:
+    '#type': webform_card
+    '#title': 'Card #3'
+    element_3:
+      '#type': textfield
+      '#title': 'Element #3'
+  card_4:
+    '#type': webform_card
+    '#title': 'Card #4'
+    element_4:
+      '#type': textfield
+      '#title': 'Element #4'
+  card_5:
+    '#type': webform_card
+    '#title': 'Card #5'
+    element_5:
+      '#type': textfield
+      '#title': 'Element #5'
+  card_6:
+    '#type': webform_card
+    '#title': 'Card #6'
+    element_6:
+      '#type': textfield
+      '#title': 'Element #6'
+  card_7:
+    '#type': webform_card
+    '#title': 'Card #7'
+    element_7:
+      '#type': textfield
+      '#title': 'Element #7'
+  card_8:
+    '#type': webform_card
+    '#title': 'Card #8'
+    element_8:
+      '#type': textfield
+      '#title': 'Element #8'
+  card_9:
+    '#type': webform_card
+    '#title': 'Card #9'
+    element_9:
+      '#type': textfield
+      '#title': 'Element #9'
+  card_10:
+    '#type': webform_card
+    '#title': 'Card #10'
+    element_10:
+      '#type': textfield
+      '#title': 'Element #10'
+  card_11:
+    '#type': webform_card
+    '#title': 'Card #11'
+    element_11:
+      '#type': textfield
+      '#title': 'Element #11'
+  card_12:
+    '#type': webform_card
+    '#title': 'Card #12'
+    element_12:
+      '#type': textfield
+      '#title': 'Element #12'
+  card_13:
+    '#type': webform_card
+    '#title': 'Card #13'
+    element_13:
+      '#type': textfield
+      '#title': 'Element #13'
+  card_14:
+    '#type': webform_card
+    '#title': 'Card #14'
+    element_14:
+      '#type': textfield
+      '#title': 'Element #14'
+  card_15:
+    '#type': webform_card
+    '#title': 'Card #15'
+    element_15:
+      '#type': textfield
+      '#title': 'Element #15'
+  card_16:
+    '#type': webform_card
+    '#title': 'Card #16'
+    element_16:
+      '#type': textfield
+      '#title': 'Element #16'
+  card_17:
+    '#type': webform_card
+    '#title': 'Card #17'
+    element_17:
+      '#type': textfield
+      '#title': 'Element #17'
+  card_18:
+    '#type': webform_card
+    '#title': 'Card #18'
+    element_18:
+      '#type': textfield
+      '#title': 'Element #18'
+  card_19:
+    '#type': webform_card
+    '#title': 'Card #19'
+    element_19:
+      '#type': textfield
+      '#title': 'Element #19'
+  card_20:
+    '#type': webform_card
+    '#title': 'Card #20'
+    element_20:
+      '#type': textfield
+      '#title': 'Element #20'
+  card_21:
+    '#type': webform_card
+    '#title': 'Card #21'
+    element_21:
+      '#type': textfield
+      '#title': 'Element #21'
+  card_22:
+    '#type': webform_card
+    '#title': 'Card #22'
+    element_22:
+      '#type': textfield
+      '#title': 'Element #22'
+  card_23:
+    '#type': webform_card
+    '#title': 'Card #23'
+    element_23:
+      '#type': textfield
+      '#title': 'Element #23'
+  card_24:
+    '#type': webform_card
+    '#title': 'Card #24'
+    element_24:
+      '#type': textfield
+      '#title': 'Element #24'
+  card_25:
+    '#type': webform_card
+    '#title': 'Card #25'
+    element_25:
+      '#type': textfield
+      '#title': 'Element #25'
+  card_26:
+    '#type': webform_card
+    '#title': 'Card #26'
+    element_26:
+      '#type': textfield
+      '#title': 'Element #26'
+  card_27:
+    '#type': webform_card
+    '#title': 'Card #27'
+    element_27:
+      '#type': textfield
+      '#title': 'Element #27'
+  card_28:
+    '#type': webform_card
+    '#title': 'Card #28'
+    element_28:
+      '#type': textfield
+      '#title': 'Element #28'
+  card_29:
+    '#type': webform_card
+    '#title': 'Card #29'
+    element_29:
+      '#type': textfield
+      '#title': 'Element #29'
+  card_30:
+    '#type': webform_card
+    '#title': 'Card #30'
+    element_30:
+      '#type': textfield
+      '#title': 'Element #30'
+  card_31:
+    '#type': webform_card
+    '#title': 'Card #31'
+    element_31:
+      '#type': textfield
+      '#title': 'Element #31'
+  card_32:
+    '#type': webform_card
+    '#title': 'Card #32'
+    element_32:
+      '#type': textfield
+      '#title': 'Element #32'
+  card_33:
+    '#type': webform_card
+    '#title': 'Card #33'
+    element_33:
+      '#type': textfield
+      '#title': 'Element #33'
+  card_34:
+    '#type': webform_card
+    '#title': 'Card #34'
+    element_34:
+      '#type': textfield
+      '#title': 'Element #34'
+  card_35:
+    '#type': webform_card
+    '#title': 'Card #35'
+    element_35:
+      '#type': textfield
+      '#title': 'Element #35'
+  card_36:
+    '#type': webform_card
+    '#title': 'Card #36'
+    element_36:
+      '#type': textfield
+      '#title': 'Element #36'
+  card_37:
+    '#type': webform_card
+    '#title': 'Card #37'
+    element_37:
+      '#type': textfield
+      '#title': 'Element #37'
+  card_38:
+    '#type': webform_card
+    '#title': 'Card #38'
+    element_38:
+      '#type': textfield
+      '#title': 'Element #38'
+  card_39:
+    '#type': webform_card
+    '#title': 'Card #39'
+    element_39:
+      '#type': textfield
+      '#title': 'Element #39'
+  card_40:
+    '#type': webform_card
+    '#title': 'Card #40'
+    element_40:
+      '#type': textfield
+      '#title': 'Element #40'
+  card_41:
+    '#type': webform_card
+    '#title': 'Card #41'
+    element_41:
+      '#type': textfield
+      '#title': 'Element #41'
+  card_42:
+    '#type': webform_card
+    '#title': 'Card #42'
+    element_42:
+      '#type': textfield
+      '#title': 'Element #42'
+  card_43:
+    '#type': webform_card
+    '#title': 'Card #43'
+    element_43:
+      '#type': textfield
+      '#title': 'Element #43'
+  card_44:
+    '#type': webform_card
+    '#title': 'Card #44'
+    element_44:
+      '#type': textfield
+      '#title': 'Element #44'
+  card_45:
+    '#type': webform_card
+    '#title': 'Card #45'
+    element_45:
+      '#type': textfield
+      '#title': 'Element #45'
+  card_46:
+    '#type': webform_card
+    '#title': 'Card #46'
+    element_46:
+      '#type': textfield
+      '#title': 'Element #46'
+  card_47:
+    '#type': webform_card
+    '#title': 'Card #47'
+    element_47:
+      '#type': textfield
+      '#title': 'Element #47'
+  card_48:
+    '#type': webform_card
+    '#title': 'Card #48'
+    element_48:
+      '#type': textfield
+      '#title': 'Element #48'
+  card_49:
+    '#type': webform_card
+    '#title': 'Card #49'
+    element_49:
+      '#type': textfield
+      '#title': 'Element #49'
+  card_50:
+    '#type': webform_card
+    '#title': 'Card #50'
+    element_50:
+      '#type': textfield
+      '#title': 'Element #50'
+  card_51:
+    '#type': webform_card
+    '#title': 'Card #51'
+    element_51:
+      '#type': textfield
+      '#title': 'Element #51'
+  card_52:
+    '#type': webform_card
+    '#title': 'Card #52'
+    element_52:
+      '#type': textfield
+      '#title': 'Element #52'
+  card_53:
+    '#type': webform_card
+    '#title': 'Card #53'
+    element_53:
+      '#type': textfield
+      '#title': 'Element #53'
+  card_54:
+    '#type': webform_card
+    '#title': 'Card #54'
+    element_54:
+      '#type': textfield
+      '#title': 'Element #54'
+  card_55:
+    '#type': webform_card
+    '#title': 'Card #55'
+    element_55:
+      '#type': textfield
+      '#title': 'Element #55'
+  card_56:
+    '#type': webform_card
+    '#title': 'Card #56'
+    element_56:
+      '#type': textfield
+      '#title': 'Element #56'
+  card_57:
+    '#type': webform_card
+    '#title': 'Card #57'
+    element_57:
+      '#type': textfield
+      '#title': 'Element #57'
+  card_58:
+    '#type': webform_card
+    '#title': 'Card #58'
+    element_58:
+      '#type': textfield
+      '#title': 'Element #58'
+  card_59:
+    '#type': webform_card
+    '#title': 'Card #59'
+    element_59:
+      '#type': textfield
+      '#title': 'Element #59'
+  card_60:
+    '#type': webform_card
+    '#title': 'Card #60'
+    element_60:
+      '#type': textfield
+      '#title': 'Element #60'
+  card_61:
+    '#type': webform_card
+    '#title': 'Card #61'
+    element_61:
+      '#type': textfield
+      '#title': 'Element #61'
+  card_62:
+    '#type': webform_card
+    '#title': 'Card #62'
+    element_62:
+      '#type': textfield
+      '#title': 'Element #62'
+  card_63:
+    '#type': webform_card
+    '#title': 'Card #63'
+    element_63:
+      '#type': textfield
+      '#title': 'Element #63'
+  card_64:
+    '#type': webform_card
+    '#title': 'Card #64'
+    element_64:
+      '#type': textfield
+      '#title': 'Element #64'
+  card_65:
+    '#type': webform_card
+    '#title': 'Card #65'
+    element_65:
+      '#type': textfield
+      '#title': 'Element #65'
+  card_66:
+    '#type': webform_card
+    '#title': 'Card #66'
+    element_66:
+      '#type': textfield
+      '#title': 'Element #66'
+  card_67:
+    '#type': webform_card
+    '#title': 'Card #67'
+    element_67:
+      '#type': textfield
+      '#title': 'Element #67'
+  card_68:
+    '#type': webform_card
+    '#title': 'Card #68'
+    element_68:
+      '#type': textfield
+      '#title': 'Element #68'
+  card_69:
+    '#type': webform_card
+    '#title': 'Card #69'
+    element_69:
+      '#type': textfield
+      '#title': 'Element #69'
+  card_70:
+    '#type': webform_card
+    '#title': 'Card #70'
+    element_70:
+      '#type': textfield
+      '#title': 'Element #70'
+  card_71:
+    '#type': webform_card
+    '#title': 'Card #71'
+    element_71:
+      '#type': textfield
+      '#title': 'Element #71'
+  card_72:
+    '#type': webform_card
+    '#title': 'Card #72'
+    element_72:
+      '#type': textfield
+      '#title': 'Element #72'
+  card_73:
+    '#type': webform_card
+    '#title': 'Card #73'
+    element_73:
+      '#type': textfield
+      '#title': 'Element #73'
+  card_74:
+    '#type': webform_card
+    '#title': 'Card #74'
+    element_74:
+      '#type': textfield
+      '#title': 'Element #74'
+  card_75:
+    '#type': webform_card
+    '#title': 'Card #75'
+    element_75:
+      '#type': textfield
+      '#title': 'Element #75'
+  card_76:
+    '#type': webform_card
+    '#title': 'Card #76'
+    element_76:
+      '#type': textfield
+      '#title': 'Element #76'
+  card_77:
+    '#type': webform_card
+    '#title': 'Card #77'
+    element_77:
+      '#type': textfield
+      '#title': 'Element #77'
+  card_78:
+    '#type': webform_card
+    '#title': 'Card #78'
+    element_78:
+      '#type': textfield
+      '#title': 'Element #78'
+  card_79:
+    '#type': webform_card
+    '#title': 'Card #79'
+    element_79:
+      '#type': textfield
+      '#title': 'Element #79'
+  card_80:
+    '#type': webform_card
+    '#title': 'Card #80'
+    element_80:
+      '#type': textfield
+      '#title': 'Element #80'
+  card_81:
+    '#type': webform_card
+    '#title': 'Card #81'
+    element_81:
+      '#type': textfield
+      '#title': 'Element #81'
+  card_82:
+    '#type': webform_card
+    '#title': 'Card #82'
+    element_82:
+      '#type': textfield
+      '#title': 'Element #82'
+  card_83:
+    '#type': webform_card
+    '#title': 'Card #83'
+    element_83:
+      '#type': textfield
+      '#title': 'Element #83'
+  card_84:
+    '#type': webform_card
+    '#title': 'Card #84'
+    element_84:
+      '#type': textfield
+      '#title': 'Element #84'
+  card_85:
+    '#type': webform_card
+    '#title': 'Card #85'
+    element_85:
+      '#type': textfield
+      '#title': 'Element #85'
+  card_86:
+    '#type': webform_card
+    '#title': 'Card #86'
+    element_86:
+      '#type': textfield
+      '#title': 'Element #86'
+  card_87:
+    '#type': webform_card
+    '#title': 'Card #87'
+    element_87:
+      '#type': textfield
+      '#title': 'Element #87'
+  card_88:
+    '#type': webform_card
+    '#title': 'Card #88'
+    element_88:
+      '#type': textfield
+      '#title': 'Element #88'
+  card_89:
+    '#type': webform_card
+    '#title': 'Card #89'
+    element_89:
+      '#type': textfield
+      '#title': 'Element #89'
+  card_90:
+    '#type': webform_card
+    '#title': 'Card #90'
+    element_90:
+      '#type': textfield
+      '#title': 'Element #90'
+  card_91:
+    '#type': webform_card
+    '#title': 'Card #91'
+    element_91:
+      '#type': textfield
+      '#title': 'Element #91'
+  card_92:
+    '#type': webform_card
+    '#title': 'Card #92'
+    element_92:
+      '#type': textfield
+      '#title': 'Element #92'
+  card_93:
+    '#type': webform_card
+    '#title': 'Card #93'
+    element_93:
+      '#type': textfield
+      '#title': 'Element #93'
+  card_94:
+    '#type': webform_card
+    '#title': 'Card #94'
+    element_94:
+      '#type': textfield
+      '#title': 'Element #94'
+  card_95:
+    '#type': webform_card
+    '#title': 'Card #95'
+    element_95:
+      '#type': textfield
+      '#title': 'Element #95'
+  card_96:
+    '#type': webform_card
+    '#title': 'Card #96'
+    element_96:
+      '#type': textfield
+      '#title': 'Element #96'
+  card_97:
+    '#type': webform_card
+    '#title': 'Card #97'
+    element_97:
+      '#type': textfield
+      '#title': 'Element #97'
+  card_98:
+    '#type': webform_card
+    '#title': 'Card #98'
+    element_98:
+      '#type': textfield
+      '#title': 'Element #98'
+  card_99:
+    '#type': webform_card
+    '#title': 'Card #99'
+    element_99:
+      '#type': textfield
+      '#title': 'Element #99'
+  card_100:
+    '#type': webform_card
+    '#title': 'Card #100'
+    element_100:
+      '#type': textfield
+      '#title': 'Element #100'
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_progress_link: false
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 0
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress.yml
new file mode 100644
index 0000000000..b7301fad30
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress.yml
@@ -0,0 +1,208 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_progress
+title: 'Test: Webform: Cards progress'
+description: 'Test cards progress tracking.'
+category: 'Test: Cards'
+elements: |
+  card_1:
+    '#type': webform_card
+    '#title': 'Card 1'
+    element_1:
+      '#type': textfield
+      '#title': 'Element 1'
+      '#default_value': '{element_1}'
+  card_2:
+    '#type': webform_card
+    '#title': 'Card 2'
+    element_2:
+      '#type': textfield
+      '#title': 'Element 2'
+      '#default_value': '{element_2}'
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: true
+  wizard_progress_percentage: true
+  wizard_progress_link: false
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: false
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress_custom.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress_custom.yml
new file mode 100644
index 0000000000..5388ff0fe7
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress_custom.yml
@@ -0,0 +1,297 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_progress_custom
+title: 'Test: Webform: Cards progress custom'
+description: 'Test cards progress with custom tracking.'
+category: 'Test: Cards'
+elements: |
+  start:
+    '#title': Start
+    '#type': webform_card
+    trigger_cards:
+      '#type': checkboxes
+      '#title': trigger_cards
+      '#options':
+        card_1: card_1
+        card_2: card_2
+        card_3: card_3
+        card_4: card_4
+        card_5: card_5
+      '#default_value':
+        - card_1
+        - card_2
+        - card_3
+        - card_4
+        - card_5
+      '#states':
+        unchecked:
+          ':input[name="trigger_none"]':
+            checked: true
+        disabled:
+          ':input[name="trigger_none"]':
+            checked: true
+    trigger_none:
+      '#type': checkbox
+      '#title': trigger_none
+  card_1:
+    '#title': 'Card 1'
+    '#type': webform_card
+    '#states':
+      visible:
+        ':input[name="trigger_cards[card_1]"]':
+          checked: true
+        ':input[name="trigger_none"]':
+          unchecked: true
+    card_1_markup:
+      '#markup': 'This is card 1.'
+    card_1_element:
+      '#type': textfield
+      '#title': 'Element 1'
+      '#default_value': '{element_1}'
+  card_2:
+    '#title': 'Card 2'
+    '#type': webform_card
+    '#states':
+      visible:
+        ':input[name="trigger_cards[card_2]"]':
+          checked: true
+        ':input[name="trigger_none"]':
+          unchecked: true
+    card_2_markup:
+      '#markup': 'This is card 2.'
+    card_2_element:
+      '#type': textfield
+      '#title': 'Element 2'
+      '#default_value': '{element_2}'
+  card_3:
+    '#title': 'Card 3'
+    '#type': webform_card
+    '#states':
+      visible:
+        ':input[name="trigger_cards[card_3]"]':
+          checked: true
+        ':input[name="trigger_none"]':
+          unchecked: true
+    card_3_markup:
+      '#markup': 'This is card 3.'
+    card_3_element:
+      '#type': textfield
+      '#title': 'Element 3'
+      '#default_value': '{element_3}'
+  card_4:
+    '#title': 'Card 4'
+    '#type': webform_card
+    '#states':
+      visible:
+        ':input[name="trigger_cards[card_4]"]':
+          checked: true
+        ':input[name="trigger_none"]':
+          unchecked: true
+    card_4_markup:
+      '#markup': 'This is card 4.'
+    card_4_element:
+      '#type': textfield
+      '#title': 'Element 4'
+      '#default_value': '{element_4}'
+  card_5:
+    '#title': 'Card 5'
+    '#type': webform_card
+    '#states':
+      visible:
+        ':input[name="trigger_cards[card_5]"]':
+          checked: true
+        ':input[name="trigger_none"]':
+          unchecked: true
+    card_5_markup:
+      '#markup': 'This is card 5.'
+    card_5_element:
+      '#type': textfield
+      '#title': 'Element 5'
+      '#default_value': '{element_5}'
+
+css: ''
+javascript: ''
+settings:
+  ajax: true
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: true
+  wizard_progress_percentage: true
+  wizard_progress_link: true
+  wizard_progress_states: true
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: true
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: all
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: inline
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress_links.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress_links.yml
new file mode 100644
index 0000000000..f932468153
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_progress_links.yml
@@ -0,0 +1,208 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_progress_links
+title: 'Test: Webform: Cards progress links'
+description: 'Test cards progress links.'
+category: 'Test: Cards'
+elements: |
+  card_1:
+    '#type': webform_card
+    '#title': 'Card 1'
+    element_1:
+      '#type': textfield
+      '#title': 'Element 1'
+      '#default_value': '{element_1}'
+  card_2:
+    '#type': webform_card
+    '#title': 'Card 2'
+    element_2:
+      '#type': textfield
+      '#title': 'Element 2'
+      '#default_value': '{element_2}'
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_progress_link: true
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: true
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_states.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_states.yml
new file mode 100644
index 0000000000..e09676f11c
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_states.yml
@@ -0,0 +1,297 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_states
+title: 'Test: Webform: Cards conditional logic (#states)'
+description: 'Test a multiple step cards with conditional logic (#states)'
+category: 'Test: Cards'
+elements: |
+  start:
+    '#title': Start
+    '#type': webform_card
+    trigger_cards:
+      '#type': checkboxes
+      '#title': trigger_cards
+      '#options':
+        card_1: card_1
+        card_2: card_2
+        card_3: card_3
+        card_4: card_4
+        card_5: card_5
+      '#default_value':
+        - card_1
+        - card_2
+        - card_3
+        - card_4
+        - card_5
+      '#states':
+        unchecked:
+          ':input[name="trigger_none"]':
+            checked: true
+        disabled:
+          ':input[name="trigger_none"]':
+            checked: true
+    trigger_none:
+      '#type': checkbox
+      '#title': trigger_none
+  card_1:
+    '#title': 'Card 1'
+    '#type': webform_card
+    '#states':
+      visible:
+        ':input[name="trigger_cards[card_1]"]':
+          checked: true
+        ':input[name="trigger_none"]':
+          unchecked: true
+    card_1_markup:
+      '#markup': 'This is card 1.'
+    card_1_textfield:
+      '#type': textfield
+      '#title': 'Element 1'
+      '#default_value': '{element_1}'
+  card_2:
+    '#title': 'Card 2'
+    '#type': webform_card
+    '#states':
+      visible:
+        ':input[name="trigger_cards[card_2]"]':
+          checked: true
+        ':input[name="trigger_none"]':
+          unchecked: true
+    card_2_markup:
+      '#markup': 'This is card 2.'
+    card_2_textfield:
+      '#type': textfield
+      '#title': 'Element 2'
+      '#default_value': '{element_1}'
+  card_3:
+    '#title': 'Card 3'
+    '#type': webform_card
+    '#states':
+      visible:
+        ':input[name="trigger_cards[card_3]"]':
+          checked: true
+        ':input[name="trigger_none"]':
+          unchecked: true
+    card_3_markup:
+      '#markup': 'This is card 3.'
+    card_3_textfield:
+      '#type': textfield
+      '#title': 'Element 3'
+      '#default_value': '{element_3}'
+  card_4:
+    '#title': 'Card 4'
+    '#type': webform_card
+    '#states':
+      visible:
+        ':input[name="trigger_cards[card_4]"]':
+          checked: true
+        ':input[name="trigger_none"]':
+          unchecked: true
+    card_4_markup:
+      '#markup': 'This is card 4.'
+    card_4_textfield:
+      '#type': textfield
+      '#title': 'Element 4'
+      '#default_value': '{element_4}'
+  card_5:
+    '#title': 'Card 5'
+    '#type': webform_card
+    '#states':
+      visible:
+        ':input[name="trigger_cards[card_5]"]':
+          checked: true
+        ':input[name="trigger_none"]':
+          unchecked: true
+    card_5_markup:
+      '#markup': 'This is card 5.'
+    card_5_textfield:
+      '#type': textfield
+      '#title': 'Element 5'
+      '#default_value': '{element_5}'
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_progress_link: false
+  wizard_progress_states: true
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_titles.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_titles.yml
new file mode 100644
index 0000000000..599b2e99ef
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_titles.yml
@@ -0,0 +1,211 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_titles
+title: 'Test: Webform: Cards titles'
+description: 'Test cards title customization.'
+category: 'Test: Cards'
+elements: |
+  card_1:
+    '#type': webform_card
+    '#title': 'Card 1'
+    '#title_tag': 'h1'
+    '#title_attributes':
+      'style': 'border: 1px solid green; padding: 2px; color: green;'
+    element_1:
+      '#type': textfield
+      '#title': 'Element 1'
+      '#default_value': '{element_1}'
+  card_2:
+    '#type': webform_card
+    '#title': 'Card 2'
+    element_2:
+      '#type': textfield
+      '#title': 'Element 2'
+      '#default_value': '{element_2}'
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: true
+  wizard_progress_percentage: true
+  wizard_progress_link: false
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: false
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_toggle.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_toggle.yml
new file mode 100644
index 0000000000..84c20ea2c2
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_toggle.yml
@@ -0,0 +1,208 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_toggle
+title: 'Test: Webform: Cards toggle'
+description: 'Test cards toggle show/hide all elements.'
+category: 'Test: Cards'
+elements: |
+  card_1:
+    '#type': webform_card
+    '#title': 'Card 1'
+    element_1:
+      '#type': textfield
+      '#title': 'Element 1'
+      '#default_value': '{element_1}'
+  card_2:
+    '#type': webform_card
+    '#title': 'Card 2'
+    element_2:
+      '#type': textfield
+      '#title': 'Element 2'
+      '#default_value': '{element_2}'
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: true
+  wizard_progress_percentage: true
+  wizard_progress_link: false
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: false
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: true
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_validation_errors.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_validation_errors.yml
new file mode 100644
index 0000000000..822fff13c4
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/config/install/webform.webform.test_cards_validation_errors.yml
@@ -0,0 +1,216 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_cards_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_cards_validation_errors
+title: 'Test: Webform: Cards validation errors'
+description: 'Test webform cards element validation error handling.'
+category: 'Test: Cards'
+elements: |
+  card_1:
+    '#type': webform_card
+    '#title': 'Card 1'
+    element_1:
+      '#type': textfield
+      '#title': 'Element 1'
+      '#default_value': '{element_1}'
+  card_2:
+    '#type': webform_card
+    '#title': 'Card 2'
+    email_multiple:
+      '#type': webform_email_multiple
+      '#title': email_multiple
+      '#required': true
+      '#default_value': '{email_multiple not valid}'
+  card_3:
+    '#type': webform_card
+    '#title': 'Card 3'
+    element_2:
+      '#type': textfield
+      '#title': 'Element 2'
+      '#default_value': '{element_2}'
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: both
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_progress_link: false
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 0
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/templates/webform-progress--test-cards-progress-custom.html.twig b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/templates/webform-progress--test-cards-progress-custom.html.twig
new file mode 100644
index 0000000000..afa1a615e2
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/templates/webform-progress--test-cards-progress-custom.html.twig
@@ -0,0 +1,97 @@
+{#
+/**
+ * @file
+ * Default theme implementation for webform wizard progress.
+ *
+ * Available variables:
+ * - webform: A webform.
+ * - pages: Array of wizard pages.
+ * - current_page: Current wizard page.
+ * - total_pages: Current wizard page.
+ * - summary: Summary of progress.
+ * - percentage: Percentage completed.
+ * - bar: A progress bar.
+ *
+ * @see template_preprocess_webform_progress()
+ *
+ * @ingroup themeable
+ */
+#}
+
+{{ attach_library('webform/webform.progress') }}
+
+<div class="webform-progress">
+
+  <progress value="{{ index }}" max="{{ total }}" style="width: 100%;">{{ percentage }}</progress>
+
+  {{ bar }}
+
+  {% if summary or percentage %}
+    <div class="webform-progress__status">
+      {% if summary %}
+        <span class="webform-progress__summary" data-webform-progress-summary>{{ summary }}</span>
+        {% if percentage %}
+          <span class="webform-progress__percentage">(<span data-webform-progress-percentage>{{ percentage }}</span>)</span>
+        {% endif %}
+      {% else %}
+        <span class="webform-progress__percentage" data-webform-progress-percentage>{{ percentage }}</span>
+      {% endif %}
+    </div>
+  {% endif %}
+
+  <table width="100%">
+    <tbody>
+    <tr>
+      <th>{{ 'Summary'|t }} </th>
+      <td data-webform-progress-summary>{{ summary }}</td>
+    </tr>
+    <tr>
+      <th>{{ 'Percentage'|t }} </th>
+      <td data-webform-progress-percentage>{{ percentage }}</td>
+    </tr>
+    <tr>
+      <th>{{ 'Index'|t }} </th>
+      <td data-webform-progress-index>{{ index }}</td>
+    </tr>
+    <tr>
+      <th>{{ 'Total'|t }} </th>
+      <td data-webform-progress-total>{{ total }}</td>
+    </tr>
+    </tbody>
+  </table>
+
+  <table width="100%">
+    <thead>
+    <tr>
+      <th>{{ 'Index'|t }} </th>
+      <th>{{ 'State'|t }} </th>
+      <th>{{ 'Name'|t }} </th>
+      <th>{{ 'Title'|t }} </th>
+    </tr>
+    </thead>
+    <tbody>
+    {% for index, page in progress %}
+      {% set is_completed = index < current_index %}
+      {% set is_active = index == current_index %}
+      {%
+        set classes = [
+          is_completed ? 'is-complete',
+          is_active ? 'is-active',
+        ]
+      %}
+      {%
+        set attributes = create_attribute()
+          .setAttribute('data-webform-' ~ page.type, page.name)
+          .setAttribute('title', page.title)
+          .addClass(classes)
+      %}
+      <tr{{ attributes }}>
+        <td><span data-webform-progress-step>{{ index + 1 }}</span></td>
+        <td><span data-webform-progress-state></span></td>
+        <td><span data-webform-progress-link>{{ page.name }}</span></td>
+        <td>{{ page.title }}</td>
+      </tr>
+    {% endfor %}
+    </tbody>
+  </table>
+</div>
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/webform_cards_test.info.yml b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/webform_cards_test.info.yml
new file mode 100644
index 0000000000..4ed74b0701
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/webform_cards_test.info.yml
@@ -0,0 +1,12 @@
+name: 'Webform Cards test'
+type: module
+description: 'Support module for webform cards testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
+dependencies:
+  - 'webform:webform_cards'
+
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
+project: 'webform'
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/webform_cards_test.module b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/webform_cards_test.module
new file mode 100644
index 0000000000..2af0046675
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/modules/webform_cards_test/webform_cards_test.module
@@ -0,0 +1,32 @@
+<?php
+
+/**
+ * @file
+ * Support module for webform cards testing.
+ */
+
+/**
+ * Implements hook_theme().
+ */
+function webform_cards_test_theme() {
+  $info = [
+    'webform_progress__test_cards_progress_custom' => [
+      'variables' => [
+        'webform' => NULL,
+        'webform_submission' => NULL,
+        'current_page' => NULL,
+        'operation' => NULL,
+        'pages' => [],
+      ],
+    ],
+  ];
+  return $info;
+}
+
+/**
+ * Prepares variables for webform 'wizard' progress templates.
+ */
+function template_preprocess_webform_progress__test_cards_progress_custom(array &$variables) {
+  template_preprocess_webform_progress($variables);
+  _template_preprocess_webform_progress($variables);
+}
diff --git a/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsAjaxJavaScriptTest.php b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsAjaxJavaScriptTest.php
new file mode 100644
index 0000000000..49c1d79c22
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsAjaxJavaScriptTest.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Drupal\Tests\webform_cards\FunctionalJavaScript;
+
+use Drupal\Tests\webform\FunctionalJavascript\WebformWebDriverTestBase;
+
+/**
+ * Tests for webform cards ajax.
+ *
+ * @group webform_cards
+ */
+class WebformCardsAjaxJavaScriptTest extends WebformWebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['webform', 'webform_cards', 'webform_cards_test'];
+
+  /**
+   * Test webform cards ajax.
+   */
+  public function testAjax() {
+    global $base_path;
+
+    $session = $this->getSession();
+    $page = $session->getPage();
+    $assert_session = $this->assertSession();
+
+    /**************************************************************************/
+
+    // Get the webform and load card 1.
+    $this->drupalGet('/webform/test_cards_ajax');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_1"]');
+    $this->assertCssSelect('[data-webform-card="card_1"].is-active');
+
+    // Move to card 2.
+    $page->pressButton('edit-cards-next');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_2"]');
+    $this->assertCssSelect('[data-webform-card="card_2"].is-active');
+
+    // Move to preview.
+    $page->pressButton('edit-preview-next');
+    $assert_session->waitForElement('css', '.webform-preview');
+    $this->assertCssSelect('[data-webform-page="webform_preview"].is-active');
+
+    // Submit the form.
+    $page->pressButton('Submit');
+    $assert_session->waitForElement('css', '.webform-confirmation');
+    $this->assertCssSelect('[data-webform-page="webform_confirmation"].is-active');
+
+    // Confirm that the confirmation page is inline.
+    $actual_path = parse_url($this->getSession()->getCurrentUrl(), PHP_URL_PATH) ?: '';
+    $this->assertEquals($base_path . 'webform/test_cards_ajax', $actual_path);
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsAutoForwardJavaScriptTest.php b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsAutoForwardJavaScriptTest.php
new file mode 100644
index 0000000000..abefa8a4f3
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsAutoForwardJavaScriptTest.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Drupal\Tests\webform_cards\FunctionalJavaScript;
+
+use Drupal\Tests\webform\FunctionalJavascript\WebformWebDriverTestBase;
+
+/**
+ * Tests for webform cards auto-forward.
+ *
+ * @group webform_cards
+ */
+class WebformCardsAutoForwardJavaScriptTest extends WebformWebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['webform', 'webform_cards', 'webform_cards_test', 'webform_image_select'];
+
+  /**
+   * Test webform cards auto-forward.
+   */
+  public function testAutoForward() {
+    $session = $this->getSession();
+    $page = $session->getPage();
+    $assert_session = $this->assertSession();
+
+    /**************************************************************************/
+
+    $this->drupalGet('/webform/test_cards_auto_forward');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="textfield"]');
+
+    // Check that enter in textfield auto-forwards.
+    $session->executeScript('var event = jQuery.Event("keypress"); event.which = 13; jQuery("#edit-textfield").trigger(event);');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="radios_example"]');
+
+    // Check that radios auto-forwards.
+    $session->executeScript('jQuery("#edit-radios-one").mouseup();');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="radios_other_example"]');
+
+    // Check that clicking radios other 'Other…' does NOT auto-forward.
+    $session->executeScript('jQuery("#edit-radios-other-radios-other-").mouseup();');
+    $assert_session->waitForElement('css', '#edit-radios-other-other');
+    $this->assertCssSelect('.webform-card--active[data-webform-key="radios_other_example"]');
+
+    // Check that clicking radios other option does auto-forward.
+    $session->executeScript('jQuery("#edit-radios-other-radios-one").mouseup();');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="scale"]');
+
+    // Check that clicking scale does auto-forward.
+    $session->executeScript('jQuery("#edit-scale-1").change();');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="rating"]');
+
+    // Check that clicking rating does auto-forward.
+    $session->executeScript("jQuery('#edit-rating').val('1').change()");
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="image_select"]');
+
+    // Check that image select does auto-forward.
+    $session->executeScript("jQuery('#edit-image-select').val('kitten_1').change()");
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="radios_multiple"]');
+
+    // Check that clicking multiple radios does NOT auto-forward.
+    $session->executeScript('jQuery("#edit-radios-multiple-1-one, #edit-radios-multiple-1-two").mouseup();');
+
+    // Check that the form can be submitted.
+    $page->pressButton('edit-submit');
+    $assert_session->pageTextContains('New submission added to Test: Webform: Cards auto-forward.');
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsDraftJavaScriptTest.php b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsDraftJavaScriptTest.php
new file mode 100644
index 0000000000..15d8ad2534
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsDraftJavaScriptTest.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Drupal\Tests\webform_cards\FunctionalJavaScript;
+
+use Drupal\Tests\webform\FunctionalJavascript\WebformWebDriverTestBase;
+
+/**
+ * Tests for webform cards draft.
+ *
+ * @group webform_cards
+ */
+class WebformCardsDraftJavaScriptTest extends WebformWebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['webform', 'webform_cards', 'webform_cards_test'];
+
+  /**
+   * Test webform cards draft.
+   */
+  public function testDraft() {
+    $session = $this->getSession();
+    $page = $session->getPage();
+    $assert_session = $this->assertSession();
+
+    /**************************************************************************/
+
+    // Get the webform and load card 1.
+    $this->drupalGet('/webform/test_cards_draft');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_1"]');
+    $this->assertElementVisible('[data-webform-key="card_1"]');
+    $this->assertElementNotVisible('[data-webform-key="card_2"]');
+
+    // Move to card 2.
+    $page->pressButton('edit-cards-next');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_2"]');
+    $this->assertElementNotVisible('[data-webform-key="card_1"]');
+    $this->assertElementVisible('[data-webform-key="card_2"]');
+
+    // Save a draft.
+    $page->pressButton('edit-draft');
+    $assert_session->responseContains('Submission saved. You may return to this form later and it will restore the current values.');
+    $this->assertElementNotVisible('[data-webform-key="card_1"]');
+    $this->assertElementVisible('[data-webform-key="card_2"]');
+
+    // Reload the webform.
+    $this->drupalGet('/webform/test_cards_draft');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_2"]');
+    $this->assertElementNotVisible('[data-webform-key="card_1"]');
+    $this->assertElementVisible('[data-webform-key="card_2"]');
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsProgressJavaScriptTest.php b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsProgressJavaScriptTest.php
new file mode 100644
index 0000000000..e0865a1747
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsProgressJavaScriptTest.php
@@ -0,0 +1,207 @@
+<?php
+
+namespace Drupal\Tests\webform_cards\FunctionalJavaScript;
+
+use Drupal\webform\Entity\Webform;
+use Drupal\Tests\webform\FunctionalJavascript\WebformWebDriverTestBase;
+
+/**
+ * Tests for webform cards progress.
+ *
+ * @group webform_cards
+ */
+class WebformCardsProgressJavaScriptTest extends WebformWebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['webform', 'webform_cards', 'webform_cards_test'];
+
+  /**
+   * Test webform cards progress.
+   */
+  public function testProgress() {
+    $session = $this->getSession();
+    $page = $session->getPage();
+    $assert_session = $this->assertSession();
+
+    $webform = Webform::load('test_cards_progress');
+
+    /**************************************************************************/
+    // Progress (test_cards_progress).
+    /**************************************************************************/
+
+    // Get the webform and load card 1.
+    $this->drupalGet('/webform/test_cards_progress');
+
+    // Check that all the button are included on the page.
+    $this->assertCssSelect('#edit-cards-prev');
+    $this->assertCssSelect('#edit-cards-next');
+    $this->assertCssSelect('#edit-preview-next');
+    $this->assertCssSelect('#edit-submit');
+
+    // Check that only next button is visible on card 1.
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_1"]');
+    $this->assertElementNotVisible('#edit-cards-prev');
+    $this->assertElementVisible('#edit-cards-next');
+    $this->assertElementNotVisible('#edit-preview-next');
+    $this->assertElementNotVisible('#edit-submit');
+
+    // Move to card 2.
+    $page->pressButton('edit-cards-next');
+
+    // Check that only previous, preview, and submit buttons are visible
+    // on card 2.
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_2"]');
+    $assert_session->waitForElementVisible('css', '#edit-cards-prev');
+    $this->assertElementVisible('#edit-cards-prev');
+    $this->assertElementNotVisible('#edit-cards-next');
+    $this->assertElementVisible('#edit-preview-next');
+    $this->assertElementVisible('#edit-submit');
+
+    // Move to preview.
+    $page->pressButton('edit-preview-next');
+
+    // Check that preview is loaded.
+    $this->assertCssSelect('.webform-preview');
+
+    // Check that only previous and submit buttons are visible on preview page.
+    $this->assertElementVisible('#edit-preview-prev');
+    $this->assertElementVisible('#edit-submit');
+
+    /**************************************************************************/
+    // Progress track.
+    /**************************************************************************/
+
+    // Enable tracking by name.
+    $webform->setSetting('wizard_track', 'name')->save();
+
+    // Check page 1 URL with ?page=*.
+    $this->drupalGet('/webform/test_cards_progress');
+    $this->assertQuery('page=card_1');
+
+    // Check page 2 URL with ?page=2.
+    $page->pressButton('edit-cards-next');
+    $this->assertQuery('page=card_2');
+
+    // Check page 1 URL with ?page=1.
+    $page->pressButton('edit-cards-prev');
+    $this->assertQuery('page=card_1');
+
+    // Check page 1 URL with custom param.
+    $this->drupalGet('/webform/test_cards_progress', ['query' => ['custom_param' => '1']]);
+    $this->assertQuery('custom_param=1&page=card_1');
+
+    // Check page 2 URL with ?page=2.
+    $page->pressButton('edit-cards-next');
+    $this->assertQuery('custom_param=1&page=card_2');
+
+    // Check page 1 URL with ?page=1.
+    $page->pressButton('edit-cards-prev');
+    $this->assertQuery('custom_param=1&page=card_1');
+
+    // Check page 2 URL with ?page=2.
+    $page->pressButton('edit-cards-next');
+    $this->assertQuery('custom_param=1&page=card_2');
+
+    // Check preview URL with ?page=webform_preview.
+    $page->pressButton('edit-preview-next');
+    $this->assertQuery('custom_param=1&page=webform_preview');
+
+    /**************************************************************************/
+    // Progress confirmation.
+    /**************************************************************************/
+
+    // Check that confirmation is NOT included in progress.
+    $this->drupalGet('/webform/test_cards_progress');
+    $assert_session->pageTextNotContains('Complete');
+
+    // AD confirmation TO progress.
+    $webform->setSetting('wizard_confirmation', TRUE)->save();
+
+    // Check that confirmation 'Complete' is included in progress.
+    $this->drupalGet('/webform/test_cards_progress');
+    $assert_session->pageTextContains('Complete');
+
+    // Change the confirmation label to 'Done.
+    $webform->setSetting('wizard_confirmation_label', 'Done')->save();
+
+    // Check that confirmation 'Done' is included in progress.
+    $this->drupalGet('/webform/test_cards_progress');
+    $assert_session->pageTextNotContains('Complete');
+    $assert_session->pageTextContains('Done');
+
+    /**************************************************************************/
+    // Progress bar and links (test_cards_progress_links).
+    /**************************************************************************/
+
+    // Get the webform and load card 1.
+    $this->drupalGet('/webform/test_cards_progress_links');
+    $assert_session->waitForElement('css', '#edit-element-1');
+
+    // Check that no cards are linked in the progress bar.
+    $this->assertNoCssSelect('[data-webform-card="card_1"] .progress-marker[role="link"]');
+    $this->assertNoCssSelect('[data-webform-card="card_1"] .progress-title[role="link"]');
+    $this->assertNoCssSelect('[data-webform-card="card_2"] .progress-marker[role="link"]');
+    $this->assertNoCssSelect('[data-webform-card="card_2"] .progress-title[role="link"]');
+    $this->assertCssSelect('.progress-step.is-active[data-webform-card="card_1"]');
+
+    // Move to card 2.
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_1"]');
+    $page->pressButton('edit-cards-next');
+    $assert_session->waitForElement('css',  '#edit-element-2');
+
+    // Check that only card 1 is linked in the progress bar.
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_2"]');
+    $assert_session->waitForElementVisible('css', '#edit-cards-prev');
+    $this->assertCssSelect('[data-webform-card="card_1"] .progress-marker[role="link"]');
+    $this->assertCssSelect('[data-webform-card="card_1"] .progress-title[role="link"]');
+    $this->assertNoCssSelect('[data-webform-card="card_2"] .progress-marker[role="link"]');
+    $this->assertNoCssSelect('[data-webform-card="card_2"] .progress-title[role="link"]');
+    $this->assertCssSelect('.progress-step.is-complete[data-webform-card="card_1"]');
+    $this->assertCssSelect('.progress-step.is-active[data-webform-card="card_2"]');
+
+    // Move to preview.
+    $page->pressButton('edit-preview-next');
+    $assert_session->waitForElement('css', '.webform-preview');
+    $assert_session->waitForElement('css', 'input[type="submit"]#edit-webform-start-card_1');
+
+    // Check that both cards are linked in the progress bar.
+    $this->assertCssSelect('[data-webform-card="card_1"] .progress-marker[role="link"]');
+    $this->assertCssSelect('[data-webform-card="card_1"] .progress-title[role="link"]');
+    $this->assertCssSelect('[data-webform-card="card_2"] .progress-marker[role="link"]');
+    $this->assertCssSelect('[data-webform-card="card_2"] .progress-title[role="link"]');
+    $this->assertNoCssSelect('[data-webform-page="webform_preview"] .progress-marker[role="link"]');
+    $this->assertNoCssSelect('[data-webform-page="webform_preview"] .progress-title[role="link"]');
+    $this->assertCssSelect('.progress-step.is-active[data-webform-page="webform_preview"]');
+
+    // Check that both cards are linked in the preview.
+    $this->assertCssSelect('input[type="submit"]#edit-webform-start-card_1');
+    $this->assertCssSelect('input[type="submit"]#edit-webform-start-card_2');
+
+    // Move back to card 1.
+    $page->pressButton('edit-webform-start-card_1');
+    $assert_session->waitForElement('css', '#edit-element-1');
+
+    // Check that no cards are linked in the progress bar.
+    $this->assertNoCssSelect('[data-webform-card="card_1"] .progress-marker[role="link"]');
+    $this->assertNoCssSelect('[data-webform-card="card_1"] .progress-title[role="link"]');
+    $this->assertNoCssSelect('[data-webform-card="card_2"] .progress-marker[role="link"]');
+    $this->assertNoCssSelect('[data-webform-card="card_2"] .progress-title[role="link"]');
+    $this->assertCssSelect('.progress-step.is-active[data-webform-card="card_1"]');
+  }
+
+  /**
+   * Passes if the query string on the current page is matched, fail otherwise.
+   *
+   * @param string $expected_query
+   *   The expected query string.
+   */
+  protected function assertQuery($expected_query = '') {
+    $actual_query = parse_url($this->getSession()->getCurrentUrl(), PHP_URL_QUERY) ?: '';
+    $this->assertEquals($expected_query, $actual_query);
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsStatesJavaScriptTest.php b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsStatesJavaScriptTest.php
new file mode 100644
index 0000000000..7dedd939f2
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsStatesJavaScriptTest.php
@@ -0,0 +1,81 @@
+<?php
+
+namespace Drupal\Tests\webform_cards\FunctionalJavaScript;
+
+use Drupal\Tests\webform\FunctionalJavascript\WebformWebDriverTestBase;
+
+/**
+ * Tests for webform cards states.
+ *
+ * @group webform_cards
+ */
+class WebformCardsStatesJavaScriptTest extends WebformWebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['webform', 'webform_cards', 'webform_cards_test'];
+
+  /**
+   * Test webform cards states.
+   */
+  public function testStates() {
+    $session = $this->getSession();
+    $page = $session->getPage();
+    $assert_session = $this->assertSession();
+
+    /**************************************************************************/
+
+    // Check that all progress steps are visible.
+    $this->drupalGet('/webform/test_cards_states');
+    $this->assertElementVisible('[data-webform-card="start"][title="Start"]');
+    $this->assertElementVisible('[data-webform-card="card_1"][title="Card 1"]');
+    $this->assertElementVisible('[data-webform-card="card_2"][title="Card 2"]');
+    $this->assertElementVisible('[data-webform-card="card_3"][title="Card 3"]');
+    $this->assertElementVisible('[data-webform-card="card_4"][title="Card 4"]');
+    $this->assertElementVisible('[data-webform-card="card_5"][title="Card 5"]');
+    $this->assertElementVisible('[data-webform-page="webform_preview"][title="Preview"]');
+    $this->assertElementVisible('[data-webform-page="webform_confirmation"][title="Complete"]');
+    $this->assertCssSelect('.webform-card--active[data-webform-key="start"]');
+
+    // Check that card 1 is next.
+    $page->pressButton('edit-cards-next');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_1"]');
+    $this->assertCssSelect('.webform-card--active[data-webform-key="card_1"]');
+
+    // Go back to states.
+    $page->pressButton('edit-cards-prev');
+
+    // Check that progress steps can be conditionally hidden.
+    $this->click('#edit-trigger-cards-card-1');
+    $this->click('#edit-trigger-cards-card-3');
+    $this->click('#edit-trigger-cards-card-5');
+    $this->assertElementNotVisible('[data-webform-card="card_1"][title="Card 1"]');
+    $this->assertElementNotVisible('[data-webform-card="card_3"][title="Card 3"]');
+    $this->assertElementNotVisible('[data-webform-card="card_5"][title="Card 5"]');
+
+    // Check that card 2 is now next.
+    $page->pressButton('edit-cards-next');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_2"]');
+    $this->assertCssSelect('.webform-card--active[data-webform-key="card_2"]');
+
+    // Go back to states.
+    $page->pressButton('edit-cards-prev');
+
+    // Check that progress steps can be conditionally shown.
+    $this->click('#edit-trigger-cards-card-1');
+    $this->click('#edit-trigger-cards-card-3');
+    $this->click('#edit-trigger-cards-card-5');
+    $this->assertElementVisible('[data-webform-card="card_1"][title="Card 1"]');
+    $this->assertElementVisible('[data-webform-card="card_3"][title="Card 3"]');
+    $this->assertElementVisible('[data-webform-card="card_5"][title="Card 5"]');
+
+    // Check that card 1 is now next.
+    $page->pressButton('edit-cards-next');
+    $assert_session->waitForElement('css', '.webform-card--active[data-webform-key="card_1"]');
+    $this->assertCssSelect('.webform-card--active[data-webform-key="card_1"]');
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsToggleJavaScriptTest.php b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsToggleJavaScriptTest.php
new file mode 100644
index 0000000000..d55d500940
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsToggleJavaScriptTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Drupal\Tests\webform_cards\FunctionalJavaScript;
+
+use Drupal\Tests\webform\FunctionalJavascript\WebformWebDriverTestBase;
+
+/**
+ * Tests for webform cards toggle show/hide all.
+ *
+ * @group webform_cards
+ */
+class WebformCardsToggleJavaScriptTest extends WebformWebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['webform', 'webform_cards', 'webform_cards_test'];
+
+  /**
+   * Test webform cards toggle show/hide all.
+   */
+  public function testToggle() {
+    $session = $this->getSession();
+    $page = $session->getPage();
+    $assert_session = $this->assertSession();
+
+    /**************************************************************************/
+
+    $this->drupalGet('/webform/test_cards_toggle');
+    $assert_session->waitForElement('css', 'button.webform-cards-toggle');
+
+    // Check that only card 1 is visible.
+    $this->assertElementVisible('[data-webform-key="card_1"]');
+    $this->assertElementNotVisible('[data-webform-key="card_2"]');
+    // Check that only next button is visible.
+    $this->assertElementVisible('#edit-cards-next');
+    $this->assertElementNotVisible('#edit-submit');
+    // Check that progress is visible.
+    $this->assertElementVisible('.webform-progress');
+
+    // Press 'Show all' elements button.
+    $page->pressButton('Show all');
+
+    // Check that card 1 and 2 are visible.
+    $this->assertElementVisible('[data-webform-key="card_1"]');
+    $this->assertElementVisible('[data-webform-key="card_2"]');
+    // Check that only submit button is visible.
+    $this->assertElementNotVisible('#edit-cards-next');
+    $this->assertElementVisible('#edit-submit');
+    // Check that progress is not visible.
+    $this->assertElementNotVisible('.webform-progress');
+
+    // Press 'Hide all' elements button.
+    $page->pressButton('Hide all');
+
+    // Check that only card 1 is visible.
+    $this->assertElementVisible('[data-webform-key="card_1"]');
+    $this->assertElementNotVisible('[data-webform-key="card_2"]');
+    // Check that only next button is visible.
+    $this->assertElementVisible('#edit-cards-next');
+    $this->assertElementNotVisible('#edit-submit');
+    // Check that progress is visible.
+    $this->assertElementVisible('.webform-progress');
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsUiJavaScriptTest.php b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsUiJavaScriptTest.php
new file mode 100644
index 0000000000..bbe323ed51
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsUiJavaScriptTest.php
@@ -0,0 +1,54 @@
+<?php
+
+namespace Drupal\Tests\webform_cards\FunctionalJavaScript;
+
+use Drupal\Tests\webform\FunctionalJavascript\WebformWebDriverTestBase;
+
+/**
+ * Tests for webform cards UI.
+ *
+ * @group webform_cards
+ */
+class WebformCardsUiJavaScriptTest extends WebformWebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['block', 'webform', 'webform_ui', 'webform_cards', 'webform_cards_test'];
+
+  /**
+   * Webforms to load.
+   *
+   * @var array
+   */
+  protected static $testWebforms = ['test_form_wizard_basic'];
+
+  /**
+   * Test webform cards UI.
+   */
+  public function testUi() {
+    $this->placeBlocks();
+
+    $this->drupalLogin($this->rootUser);
+
+    /**************************************************************************/
+
+    // Check that 'Add page' and 'Add card' actions are visible.
+    $this->drupalGet('/admin/structure/webform/manage/contact');
+    $this->assertElementVisible('#webform-ui-add-page');
+    $this->assertElementVisible('#webform-ui-add-card');
+
+    // Check that only 'Add card' action is visible on cards form.
+    $this->drupalGet('/admin/structure/webform/manage/test_cards_progress');
+    $this->assertElementNotVisible('#webform-ui-add-page');
+    $this->assertElementVisible('#webform-ui-add-card');
+
+    // Check that only 'Add page' action is visible on wizard form.
+    $this->drupalGet('/admin/structure/webform/manage/test_form_wizard_basic');
+    $this->assertElementVisible('#webform-ui-add-page');
+    $this->assertElementNotVisible('#webform-ui-add-card');
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsValidationJavaScriptTest.php b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsValidationJavaScriptTest.php
new file mode 100644
index 0000000000..7aa0922acb
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/tests/src/FunctionalJavaScript/WebformCardsValidationJavaScriptTest.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Drupal\Tests\webform_cards\FunctionalJavaScript;
+
+use Drupal\Tests\webform\FunctionalJavascript\WebformWebDriverTestBase;
+
+/**
+ * Tests for webform cards validation.
+ *
+ * @group webform_cards
+ */
+class WebformCardsValidationJavaScriptTest extends WebformWebDriverTestBase {
+
+  /**
+   * Modules to enable.
+   *
+   * @var array
+   */
+  public static $modules = ['webform', 'webform_cards', 'webform_cards_test'];
+
+  /**
+   * Test webform cards validation.
+   */
+  public function testValidation() {
+    $session = $this->getSession();
+    $page = $session->getPage();
+    $assert_session = $this->assertSession();
+
+    /**************************************************************************/
+
+    $this->drupalGet('/webform/test_cards_validation_errors');
+
+    // Submit form with server-side validation errors.
+    $page->pressButton('edit-cards-next');
+    $page->pressButton('edit-cards-next');
+    $page->pressButton('edit-submit');
+
+    // Check that only the card with validation error is visible.
+    $assert_session->waitForElement('css', '.messages.messages--error');
+    $this->assertElementNotVisible('[data-webform-key="card_1"]');
+    $this->assertElementVisible('[data-webform-key="card_2"]');
+    $this->assertElementNotVisible('[data-webform-key="card_3"]');
+    $assert_session->responseContains('<strong>The email address <em class="placeholder">{email_multiple not valid}</em> is not valid.</strong>');
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_cards/webform_cards.info.yml b/web/modules/webform/modules/webform_cards/webform_cards.info.yml
new file mode 100644
index 0000000000..1b9b3c80c3
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/webform_cards.info.yml
@@ -0,0 +1,15 @@
+name: 'Webform Cards [EXPERIMENTAL]'
+type: module
+description: 'Provides a ''Card'' container element for fast clientside multistep form pagination.'
+experimental: true
+package: 'Webform [EXPERIMENTAL]'
+core_version_requirement: ^8.8
+dependencies:
+  - 'webform:webform'
+  - 'webform:webform_clientside_validation'
+  - 'drupal:inline_form_errors'
+
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
+project: 'webform'
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_cards/webform_cards.libraries.yml b/web/modules/webform/modules/webform_cards/webform_cards.libraries.yml
new file mode 100644
index 0000000000..93903414e7
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/webform_cards.libraries.yml
@@ -0,0 +1,22 @@
+webform_cards:
+  version: VERSION
+  css:
+    component:
+      css/webform_cards.css: { }
+  js:
+    js/webform_cards.js: { }
+  dependencies:
+    - core/drupal
+    - core/jquery.once
+    - core/jquery.ui.effects.shake
+
+webform_cards.admin:
+  version: VERSION
+  css:
+    component:
+      css/webform_cards.admin.css: { }
+  js:
+    js/webform_cards.admin.js: { }
+  dependencies:
+    - core/drupal
+    - core/jquery.once
diff --git a/web/modules/webform/modules/webform_cards/webform_cards.links.action.yml b/web/modules/webform/modules/webform_cards/webform_cards.links.action.yml
new file mode 100644
index 0000000000..424479a220
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/webform_cards.links.action.yml
@@ -0,0 +1,10 @@
+entity.webform_ui.element.card:
+  route_name: entity.webform_ui.element.add_card
+  title: 'Add card'
+  class: '\Drupal\webform\Plugin\Menu\LocalAction\WebformDialogLocalAction'
+  weight: 20
+  off_canvas: normal
+  attributes:
+    id: 'webform-ui-add-card'
+  appears_on:
+    - entity.webform.edit_form
diff --git a/web/modules/webform/modules/webform_cards/webform_cards.module b/web/modules/webform/modules/webform_cards/webform_cards.module
new file mode 100644
index 0000000000..85a8a2dc41
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/webform_cards.module
@@ -0,0 +1,497 @@
+<?php
+
+/**
+ * @file
+ * Provides a 'Card' container element for clientside multistep form pagination.
+ */
+
+use Drupal\Component\Utility\NestedArray;
+use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
+use Drupal\Core\Render\Element;
+use Drupal\Core\Render\Element\RenderElement;
+use Drupal\Core\Template\Attribute;
+use Drupal\Core\Url;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\webform\Element\WebformMessage;
+use Drupal\webform\Utility\WebformArrayHelper;
+use Drupal\webform\Utility\WebformDialogHelper;
+use Drupal\webform\WebformInterface;
+use Drupal\webform\WebformSubmissionInterface;
+
+/**
+ * Implements hook_entity_base_field_info().
+ */
+function webform_cards_entity_base_field_info(EntityTypeInterface $entity_type) {
+  if ($entity_type->id() === 'webform_submission') {
+    $fields = [];
+    $fields['current_card'] = BaseFieldDefinition::create('string')
+      ->setLabel(t('Current card'))
+      ->setDescription(t('The current card.'))
+      ->setSetting('max_length', 128);
+    return $fields;
+  }
+}
+
+/******************************************************************************/
+// Menu hook.
+/******************************************************************************/
+
+/**
+ * Implements hook_menu_local_actions_alter().
+ */
+function webform_cards_menu_local_actions_alter(&$local_actions) {
+  if (!\Drupal::moduleHandler()->moduleExists('webform_ui')) {
+    $local_actions['entity.webform_ui.element.card'];
+  }
+}
+
+/**
+ * Implements hook_preprocess_menu_local_action().
+ *
+ * @see webform_ui_preprocess_menu_local_action()
+ */
+function webform_cards_preprocess_menu_local_action(&$variables) {
+  if (\Drupal::routeMatch()->getRouteName() !== 'entity.webform.edit_form') {
+    return;
+  }
+
+  if ($variables['link']['#url']->getRouteName() === 'entity.webform_ui.element.add_card') {
+    $variables['link']['#options']['attributes']['class'][] = 'button--secondary';
+  }
+}
+
+/******************************************************************************/
+// Entity hook.
+/******************************************************************************/
+
+/**
+ * Implements hook_ENTITY_TYPE_presave() for webform_submission entities.
+ */
+function webform_cards_webform_submission_presave(WebformSubmissionInterface $webform_submission) {
+  if (!$webform_submission->isDraft()) {
+    $webform_submission->set('current_card', NULL);
+  }
+}
+
+/******************************************************************************/
+// Form alter hooks.
+/******************************************************************************/
+
+/**
+ * Implements hook_webform_submission_form_alter().
+ */
+function webform_cards_webform_submission_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
+  /** @var \Drupal\webform\WebformSubmissionForm $form_object */
+  $form_object = $form_state->getFormObject();
+
+  /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
+  $webform_submission = $form_object->getEntity();
+  /** @var \Drupal\webform\WebformInterface $webform */
+  $webform = $webform_submission->getWebform();
+
+  /** @var \Drupal\webform_cards\WebformCardsManagerInterface $webform_cards_manager */
+  $webform_cards_manager = \Drupal::service('webform_cards.manager');
+
+  // Check if the webform has cards.
+  $has_cards = $webform_cards_manager->hasCards($webform);
+  if (!$has_cards) {
+    return;
+  }
+
+  // Check if operation is edit all.
+  if ($form_object->getOperation() === 'edit_all') {
+    return;
+  }
+
+  // Add cards JavaScript.
+  $form['#attached']['library'][] = 'webform_cards/webform_cards';
+
+  // Track the current card which is used when saving and loading drafts.
+  $current_card = $webform_submission->current_card->value ?: '';
+  $form['current_card'] = [
+    '#type' => 'hidden',
+    '#default_value' => $current_card,
+  ];
+
+  // Add .webform-cards class to form with 'webform_card' elements.
+  $form['#attributes']['class'][] = 'webform-cards';
+
+  // Remove .js-webform-disable-autosubmit class when auto-forward is enabled.
+  if ($webform->getSetting('wizard_auto_forward', TRUE)) {
+    WebformArrayHelper::removeValue($form['#attributes']['class'], 'js-webform-disable-autosubmit');
+  }
+
+  // Track the current page.
+  $current_page = $form_state->get('current_page');
+  $form['#attributes']['data-current-page'] = $current_page;
+
+  // Add settings as data-* attributes.
+  $setting_names = [
+    // Update wizard/cards progress bar's pages based on conditions.
+    'wizard_progress_states',
+    // Link to previous pages in progress bar.
+    'wizard_progress_link',
+    // Link to previous pages in preview.
+    'wizard_preview_link',
+    // Include confirmation page in progress.
+    'wizard_confirmation',
+    // Update wizard/cards progress bar's pages based on conditions.
+    'wizard_progress_states',
+    // Link to previous pages in progress bar.
+    'wizard_progress_link',
+    // Auto forward to next page when the page is completed.
+    'wizard_auto_forward',
+    // Link to previous pages in preview.
+    'wizard_preview_link',
+    // Include confirmation page in progress.
+    'wizard_confirmation',
+    // Track wizard/cards progress in the URL.
+    'wizard_track',
+    // Display show/hide all wizard/cards pages link.
+    'wizard_toggle',
+    // Wizard/cards show all elements label.
+    'wizard_toggle_show_label',
+    // Wizard/cards show all elements label.
+    'wizard_toggle_hide_label',
+    // Ajax effect.
+    'ajax_effect',
+    // Ajax speed.
+    'ajax_speed',
+  ];
+  foreach ($setting_names as $setting_name) {
+    if ($value = $webform->getSetting($setting_name, TRUE)) {
+      $attribute_name = str_replace('wizard_', '', $setting_name);
+      $attribute_name = 'data-' . str_replace('_', '-', $attribute_name);
+      $form['#attributes'][$attribute_name] = $value;
+    }
+  }
+
+  // Add progress bar.
+  if ($current_page !== WebformInterface::PAGE_CONFIRMATION) {
+    $pages = $webform_cards_manager->buildPages($webform);
+    if (!in_array($current_page, [
+      WebformInterface::PAGE_PREVIEW,
+      WebformInterface::PAGE_CONFIRMATION,
+    ])) {
+      $current_page = $current_card ?: array_key_first($pages);
+    }
+    $form['progress'] = [
+      '#theme' => 'webform_progress',
+      '#webform' => $webform,
+      '#webform_submission' => $webform_submission,
+      '#pages' => $pages,
+      '#current_page' => $current_page,
+      '#operation' => $form_object->getOperation(),
+      '#weight' => -20,
+    ];
+  }
+  // Don't alter the preview page but apply conditional logic the pages..
+  if ($current_page === WebformInterface::PAGE_PREVIEW) {
+    // Unset JavaScript behaviors for webform wizard pages.
+    // @see Drupal.behaviors.webformWizardPagesLink
+    // @see \Drupal\webform\WebformSubmissionForm::pagesElement
+    if (NestedArray::keyExists($form, ['pages', '#attached', 'library'])) {
+      WebformArrayHelper::removeValue($form['pages']['#attached']['library'], 'webform/webform.wizard.pages');
+    }
+
+    $form['progress']['#pages'] = $webform_cards_manager->applyConditions($pages, $webform_submission);
+    return;
+  }
+
+  // Add previous and next buttons to form actions.
+  $form['actions']['cards_prev'] = [
+    '#type' => 'submit',
+    '#value' => $webform->getSetting('wizard_prev_button_label', TRUE),
+    '#attributes' => [
+      'class' => ['webform-button--previous', 'webform-cards-button--previous'],
+    ],
+    '#weight' => 0,
+  ];
+  $form['actions']['cards_next'] = [
+    '#type' => 'submit',
+    '#value' => $webform->getSetting('wizard_next_button_label', TRUE),
+    '#attributes' => [
+      'class' => ['webform-button--next', 'webform-cards-button--next'],
+    ],
+    '#weight' => 1,
+  ];
+
+  // Process the submitted values before they are stored.
+  $form['#entity_builders'][] = 'webform_card_webform_submission_builder';
+}
+
+/**
+ * Entity form builder to set the current card for a webform submission.
+ */
+function webform_card_webform_submission_builder($entity_type, WebformSubmissionInterface $entity, &$form, FormStateInterface $form_state) {
+  $entity->set('current_card', $form_state->getValue('current_card'));
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter() for webform UI and source edit form.
+ *
+ * @see \Drupal\webform_ui\WebformUiEntityElementsForm
+ */
+function webform_cards_form_webform_edit_form_alter(array &$form, FormStateInterface $form_state) {
+  if (!isset($form['webform_ui_elements'])) {
+    return;
+  }
+
+  /** @var \Drupal\webform_ui\WebformUiEntityElementsForm $form_object */
+  $form_object = $form_state->getFormObject();
+
+  /** @var \Drupal\webform\WebformInterface $webform */
+  $webform = $form_object->getEntity();
+  $wrapper_format = \Drupal::request()->get(MainContentViewSubscriber::WRAPPER_FORMAT);
+  $is_ajax_request = ($wrapper_format === 'drupal_ajax');
+  if ($webform->hasWizardPages() && !$is_ajax_request) {
+    $form['webform_cards_convert'] = [
+      '#type' => 'webform_message',
+      '#message_message' => [
+        'message' => ['#markup' => t("Do you want to convert this webform's wizard pages to cards?")],
+        'link' => [
+          '#type' => 'link',
+          '#title' => t('Convert'),
+          '#url' => Url::fromRoute('entity.webform.cards_convert_form', ['webform' => $webform->id()]),
+          '#attributes' => WebformDialogHelper::getModalDialogAttributes(WebformDialogHelper::DIALOG_NARROW, ['button', 'button--small']),
+          '#prefix' => ' ',
+        ],
+      ],
+      '#message_type' => 'info',
+      '#message_close' => TRUE,
+      '#message_storage' => WebformMessage::STORAGE_SESSION,
+      '#message_id' => 'webform_card_convert_' . $webform->id(),
+      '#weight' => -100,
+    ];
+  }
+
+  $form['#attached']['library'][] = 'webform_cards/webform_cards.admin';
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter() for webform configuration:forms.
+ *
+ * @see \Drupal\webform\Form\AdminConfig\WebformAdminConfigFormsForm
+ * @see /admin/structure/webform/config
+ */
+function webform_cards_form_webform_admin_config_forms_form_alter(array &$form, FormStateInterface $form_state) {
+  _webform_cards_form_alter_elements($form, [
+    'wizard_settings' => [
+      '#title' => t('Form wizard/cards settings'),
+      'default_wizard_prev_button_label' => [
+        '#title' => t('Default wizard/cards previous page button label'),
+      ],
+      'default_wizard_next_button_label' => [
+        '#title' => t('Default wizard/cards next page button label'),
+      ],
+      'default_wizard_start_label' => [
+        '#title' => t('Default wizard/cards start label'),
+      ],
+      'default_wizard_confirmation_label' => [
+        '#title' => t('Default/cards wizard end label'),
+      ],
+    ],
+  ]);
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter() for webform configuration:elements.
+ *
+ * @see \Drupal\webform\Form\AdminConfig\WebformAdminConfigElementsForm
+ * @see /admin/structure/webform/config/elements
+ */
+function webform_cards_form_webform_admin_config_elements_form_alter(array &$form, FormStateInterface $form_state) {
+  _webform_cards_form_alter_elements($form, [
+    'element' => [
+      'default_section_title_tag' => [
+        '#title' => t('Default section/card title tag'),
+      ],
+    ],
+  ]);
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter() for webform settings:form.
+ *
+ * @see \Drupal\webform\EntitySettings\WebformEntitySettingsFormForm
+ * @see /admin/structure/webform/manage/{webform}/settings/form
+ */
+function webform_cards_form_webform_settings_form_form_alter(array &$form, FormStateInterface $form_state) {
+  _webform_cards_form_alter_elements($form, [
+    'wizard_settings' => [
+      '#title' => t('Form wizard/cards settings'),
+      'wizard_progress_bar' => [
+        '#title' => t('Show wizard/cards progress bar'),
+      ],
+      'wizard_progress_pages' => [
+        '#title' => t('Show wizard/cards progress pages'),
+      ],
+      'wizard_progress_percentage' => [
+        '#title' => t('Show wizard/cards progress percentage'),
+      ],
+      'wizard_progress_states' => [
+        '#title' => t("Update wizard/cards progress bar's pages based on conditions"),
+        '#description' => t("If checked, the wizard/cards progress bar's pages will be hidden or shown based on each pages conditional logic."),
+      ],
+      'wizard_auto_forward' => [
+        '#access' => TRUE,
+      ],
+      'wizard_start_label' => [
+        '#title' => t('Wizard/cards start label'),
+        '#description' => t('The first page label in the progress bar. Subsequent pages are titled by their wizard/card page title.'),
+      ],
+      'wizard_confirmation_label' => [
+        '#title' => t('Wizard/cards end label'),
+      ],
+      'wizard_track' => [
+        '#title' => t('Track wizard/cards progress in the URL by'),
+      ],
+      'wizard_prev_button_label' => [
+        '#title' => t('Wizard/cards previous page button label'),
+        '#description' => t('This is used for the previous page button within a wizard/cards.'),
+      ],
+      'wizard_next_button_label' => [
+        '#title' => t('Wizard/cards next page button label'),
+        '#description' => t('This is used for the next page button within a wizard/cards.'),
+      ],
+      'wizard_toggle' => [
+        '#title' => t('Display show/hide all wizard/cards pages link'),
+        '#description' => t('If checked, a hide/show all elements link will be added to this webform when there are wizard/cards pages.'),
+        '#access' => TRUE,
+      ],
+      'wizard_toggle_show_label' => [
+        '#title' => t('Wizard/cards show all elements label'),
+        '#access' => TRUE,
+      ],
+      'wizard_toggle_hide_label' => [
+        '#title' => t('Wizard/card hide all elements label'),
+        '#access' => TRUE,
+      ],
+    ],
+  ]);
+}
+
+/**
+ * Alter webform wizard configuration and settings form elements.
+ *
+ * @param array &$form
+ *   The form to be altered.
+ * @param array $elements
+ *   The elements to be altered.
+ */
+function _webform_cards_form_alter_elements(array &$form, array $elements) {
+  foreach ($elements as $container_key => $container) {
+    foreach ($container as $key => $element) {
+      if (!isset($form[$container_key][$key])) {
+        continue;
+      }
+
+      if (Element::property($key)) {
+        $form[$container_key][$key] = $element;
+      }
+      elseif (is_array($container)) {
+        $form[$container_key][$key] = $element + $form[$container_key][$key];
+      }
+    }
+  }
+}
+
+/******************************************************************************/
+// Theming.
+/******************************************************************************/
+
+/**
+ * Implements hook_theme().
+ */
+function webform_cards_theme() {
+  $info = [
+    'webform_card' => [
+      'render element' => 'element',
+    ],
+  ];
+  return $info;
+}
+
+/**
+ * Prepares variables for webform section element templates.
+ *
+ * Default template: webform-section.html.twig.
+ *
+ * Copied from: template_preprocess_fieldset()
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties of the element.
+ *     Properties used: #attributes, #children, #description, #id, #title,
+ *     #value.
+ */
+function template_preprocess_webform_card(array &$variables) {
+  $element = $variables['element'];
+  Element::setAttributes($element, ['id']);
+  RenderElement::setAttributes($element);
+  $variables['attributes'] = isset($element['#attributes']) ? $element['#attributes'] : [];
+  $variables['prefix'] = isset($element['#field_prefix']) ? $element['#field_prefix'] : NULL;
+  $variables['suffix'] = isset($element['#field_suffix']) ? $element['#field_suffix'] : NULL;
+  $variables['title_display'] = isset($element['#title_display']) ? $element['#title_display'] : NULL;
+  $variables['title_tag'] = isset($element['#title_tag']) ? $element['#title_tag'] : 'h2';
+  $variables['title_attributes'] = isset($element['#title_attributes']) ? $element['#title_attributes'] : [];
+  $variables['children'] = $element['#children'];
+
+  // Allow markup in title.
+  if (isset($element['#title']) && $element['#title'] !== '') {
+    $variables['title'] = ['#markup' => $element['#title']];
+  }
+
+  // Add 'visually-hidden' class to title attributes.
+  if ($variables['title_display'] === 'invisible') {
+    $variables['title_attributes']['class'][] = 'visually-hidden';
+  }
+  $variables['title_attributes'] = new Attribute($variables['title_attributes']);
+
+  if (!empty($element['#description'])) {
+    $description_id = $element['#attributes']['id'] . '--description';
+    $description_attributes['id'] = $description_id;
+    $variables['description']['attributes'] = new Attribute($description_attributes);
+    $variables['description']['content'] = $element['#description'];
+
+    // Add the description's id to the fieldset aria attributes.
+    $variables['attributes']['aria-describedby'] = $description_id;
+  }
+
+  // Setup description, help, and more.
+  _webform_preprocess_element($variables);
+}
+
+/**
+ * Implements hook_preprocess_webform_confirmation() for webform cards.
+ */
+function webform_cards_preprocess_webform_confirmation(array &$variables) {
+  /** @var \Drupal\webform\WebformInterface $webform */
+  $webform = $variables['webform'];
+  /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
+  $webform_submission = $variables['webform_submission'];
+
+  /** @var \Drupal\webform_cards\WebformCardsManagerInterface $webform_cards_manager */
+  $webform_cards_manager = \Drupal::service('webform_cards.manager');
+
+  // Check if the webform has cards.
+  $has_cards = $webform_cards_manager->hasCards($webform);
+  if (!$has_cards) {
+    return;
+  }
+
+  // Set progress.
+  $pages = $webform_cards_manager->buildPages($webform);
+  $settings = $webform->getSettings();
+  if ($pages && $settings['wizard_confirmation'] && ($settings['wizard_progress_bar'] || $settings['wizard_progress_pages'] || $settings['wizard_progress_percentage'])) {
+    $variables['progress'] = [
+      '#theme' => 'webform_progress',
+      '#webform' => $webform,
+      '#webform_submission' => $webform_submission,
+      '#current_page' => WebformInterface::PAGE_CONFIRMATION,
+      '#pages' => $webform_cards_manager->applyConditions($pages, $webform_submission),
+    ];
+  }
+}
diff --git a/web/modules/webform/modules/webform_cards/webform_cards.routing.yml b/web/modules/webform/modules/webform_cards/webform_cards.routing.yml
new file mode 100644
index 0000000000..43345fbe03
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/webform_cards.routing.yml
@@ -0,0 +1,16 @@
+entity.webform_ui.element.add_card:
+  path: '/admin/structure/webform/manage/{webform}/element/add/card'
+  defaults:
+    _form: '\Drupal\webform_ui\Form\WebformUiElementAddForm'
+    _title: 'Add card'
+    type: webform_card
+  requirements:
+    _custom_access: '\Drupal\webform_ui\Access\WebformUiAccess::checkWebformElementAccess'
+
+entity.webform.cards_convert_form:
+  path: '/admin/structure/webform/manage/{webform}/cards/convert'
+  defaults:
+    _form: '\Drupal\webform_cards\Form\WebformCardsConvertForm'
+    _title: 'Convert wizard pages to cards'
+  requirements:
+    _entity_access: 'webform.update'
diff --git a/web/modules/webform/modules/webform_cards/webform_cards.services.yml b/web/modules/webform/modules/webform_cards/webform_cards.services.yml
new file mode 100644
index 0000000000..f4ddb263ff
--- /dev/null
+++ b/web/modules/webform/modules/webform_cards/webform_cards.services.yml
@@ -0,0 +1,9 @@
+services:
+  webform_cards.manager:
+    class: Drupal\webform_cards\WebformCardsManager
+    arguments: ['@plugin.manager.webform.element', '@webform_submission.conditions_validator']
+  webform_cards.route_subscriber:
+    class: Drupal\webform_cards\Routing\WebformCardsRouteSubscriber
+    arguments: ['@module_handler']
+    tags:
+      - { name: event_subscriber }
diff --git a/web/modules/webform/modules/webform_clientside_validation/css/webform_clientside_validation.ife.css b/web/modules/webform/modules/webform_clientside_validation/css/webform_clientside_validation.ife.css
new file mode 100644
index 0000000000..0d0ef9b75d
--- /dev/null
+++ b/web/modules/webform/modules/webform_clientside_validation/css/webform_clientside_validation.ife.css
@@ -0,0 +1,8 @@
+/**
+ * @file
+ * Webform clientside validation styles.
+ */
+
+.webform-submission-form strong.error.form-item--error-message {
+  display: block;
+}
diff --git a/web/modules/webform/modules/webform_clientside_validation/js/webform_clientside_validation.ife.js b/web/modules/webform/modules/webform_clientside_validation/js/webform_clientside_validation.ife.js
new file mode 100644
index 0000000000..b0fddf78b6
--- /dev/null
+++ b/web/modules/webform/modules/webform_clientside_validation/js/webform_clientside_validation.ife.js
@@ -0,0 +1,28 @@
+/**
+ * @file
+ * Attaches behaviors for the Clientside Validation jQuery module.
+ */
+
+(function ($) {
+
+  'use strict';
+
+  $(document).once('webform_cvjquery').on('cv-jquery-validate-options-update', function (event, options) {
+    options.errorElement = 'strong';
+    options.showErrors = function (errorMap, errorList) {
+      // Show errors using defaultShowErrors().
+      this.defaultShowErrors();
+
+      // Add '.form-item--error-message' class to all errors.
+      $(this.currentForm).find('strong.error').addClass('form-item--error-message');
+
+      // Move all radios, checkbox, and datelist errors to parent container.
+      $(this.currentForm).find('.form-checkboxes, .form-radios, .form-type-datelist .container-inline, .form-type-tel').each(function () {
+        var $container = $(this);
+        var $errorMessages = $container.find('strong.error.form-item--error-message');
+        $container.append($errorMessages);
+      });
+    };
+  });
+
+})(jQuery);
diff --git a/web/modules/webform/modules/webform_clientside_validation/js/webform_clientside_validation.novalidate.js b/web/modules/webform/modules/webform_clientside_validation/js/webform_clientside_validation.novalidate.js
new file mode 100644
index 0000000000..3465d5555f
--- /dev/null
+++ b/web/modules/webform/modules/webform_clientside_validation/js/webform_clientside_validation.novalidate.js
@@ -0,0 +1,25 @@
+/**
+ * @file
+ * Attaches behaviors for the Clientside Validation jQuery module.
+ */
+(function ($, Drupal) {
+
+  'use strict';
+
+  /**
+   * Disable clientside validation for webforms.
+   *
+   * @type {Drupal~behavior}
+   */
+  Drupal.behaviors.webformClientSideValidationNoValidation = {
+    attach: function (context) {
+      $(context)
+        .find('form[data-webform-clientside-validation-novalidate]')
+        .once('webformClientSideValidationNoValidate')
+        .each(function () {
+          $(this).validate().destroy();
+        });
+    }
+  };
+
+})(jQuery, Drupal);
diff --git a/web/modules/webform/modules/webform_clientside_validation/tests/modules/webform_clientside_validation_test/config/install/webform.webform.test_clientside_validation.yml b/web/modules/webform/modules/webform_clientside_validation/tests/modules/webform_clientside_validation_test/config/install/webform.webform.test_clientside_validation.yml
new file mode 100644
index 0000000000..52731f0307
--- /dev/null
+++ b/web/modules/webform/modules/webform_clientside_validation/tests/modules/webform_clientside_validation_test/config/install/webform.webform.test_clientside_validation.yml
@@ -0,0 +1,344 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_clientside_validation_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_clientside_validation
+title: 'Test: Clientside Validation'
+description: 'Test webform clientside validation.'
+category: 'Test: Clientside Validation'
+elements: |
+  basic_elements:
+    '#type': details
+    '#title': 'Basic elements'
+    '#open': true
+    textfield:
+      '#type': textfield
+      '#title': textfield
+      '#required': true
+    pattern:
+      '#type': textfield
+      '#title': 'pattern (^[a-z]+$)'
+      '#pattern': '^[a-z]+$'
+    input_mask:
+      '#type': textfield
+      '#title': 'input_mask - (999) 999-9999'
+      '#input_mask': '(999) 999-9999'
+    textarea:
+      '#type': textarea
+      '#title': textarea
+      '#required': true
+    select:
+      '#type': select
+      '#title': select
+      '#options':
+        one: One
+        two: Two
+        three: Three
+      '#required': true
+    checkboxes:
+      '#type': checkboxes
+      '#title': checkboxes
+      '#options':
+        one: One
+        two: Two
+        three: Three
+      '#required': true
+    radios:
+      '#type': radios
+      '#title': radios
+      '#options':
+        one: One
+        two: Two
+        three: Three
+      '#required': true
+  date_elements:
+    '#type': details
+    '#title': 'Date elements'
+    '#open': true
+    date:
+      '#type': date
+      '#title': date
+      '#required': true
+    datelist:
+      '#type': datelist
+      '#title': datelist
+      '#required': true
+    time:
+      '#type': webform_time
+      '#title': time
+      '#required': true
+  advanced_elements:
+    '#type': details
+    '#title': 'Advanced elements'
+    '#open': true
+    email:
+      '#type': email
+      '#title': email
+      '#required': true
+    email_multiple:
+      '#type': webform_email_multiple
+      '#title': email_multiple
+      '#required': true
+    email_confirm:
+      '#type': webform_email_confirm
+      '#title': email_confirm
+      '#required': true
+    tel:
+      '#type': tel
+      '#title': Telephone
+      '#required': true
+    tel_international:
+      '#type': tel
+      '#title': tel_international
+      '#international': true
+      '#telephone_validation_format': '0'
+      '#required': true
+    url:
+      '#type': url
+      '#title': url
+      '#required': true
+    number:
+      '#type': number
+      '#title': number
+      '#min': 0
+      '#max': 10
+      '#step': 1
+      '#required': true
+    range:
+      '#type': range
+      '#title': range
+      '#min': 0
+      '#max': 100
+      '#step': 1
+      '#output': right
+      '#output__field_prefix': $
+      '#output__field_suffix': '.00'
+      '#required': true
+    color:
+      '#type': color
+      '#title': color
+      '#required': true
+  custom_elements:
+    '#type': details
+    '#title': 'Custom elements'
+    '#open': true
+    autocomplete:
+      '#type': webform_autocomplete
+      '#title': autocomplete
+      '#autocomplete_items': country_names
+    image_select:
+      '#type': webform_image_select
+      '#title': image_select
+      '#show_label': true
+      '#images':
+        kitten_1:
+          text: 'Cute Kitten 1'
+          src: 'http://placekitten.com/220/200'
+        kitten_2:
+          text: 'Cute Kitten 2'
+          src: 'http://placekitten.com/180/200'
+        kitten_3:
+          text: 'Cute Kitten 3'
+          src: 'http://placekitten.com/130/200'
+      '#required': true
+    rating:
+      '#type': webform_rating
+      '#title': rating
+      '#required': true
+    scale:
+      '#type': webform_scale
+      '#title': scale
+      '#min': 1
+      '#max': 10
+      '#min_text': '1 = disagree'
+      '#max_text': '10 = agree'
+      '#required': true
+    signature:
+      '#type': webform_signature
+      '#title': signature
+      '#required': true
+
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: both
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_progress_link: false
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 0
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: page
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_clientside_validation/tests/modules/webform_clientside_validation_test/webform_clientside_validation_test.info.yml b/web/modules/webform/modules/webform_clientside_validation/tests/modules/webform_clientside_validation_test/webform_clientside_validation_test.info.yml
new file mode 100644
index 0000000000..9646ddaf72
--- /dev/null
+++ b/web/modules/webform/modules/webform_clientside_validation/tests/modules/webform_clientside_validation_test/webform_clientside_validation_test.info.yml
@@ -0,0 +1,12 @@
+name: 'Webform Clientside Validation test'
+type: module
+description: 'Support module for webform clientside validation testing.'
+package: Webform
+core_version_requirement: ^8.8
+dependencies:
+  - 'webform:webform_clientside_validation'
+
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
+project: 'webform'
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.info.yml b/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.info.yml
new file mode 100644
index 0000000000..09b6674fe4
--- /dev/null
+++ b/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.info.yml
@@ -0,0 +1,14 @@
+name: 'Webform Clientside Validation'
+type: module
+description: 'Helps support Webform to Clientside Validation integration.'
+package: Webform
+core_version_requirement: ^8.8
+dependencies:
+  - 'webform:webform'
+  - 'clientside_validation:clientside_validation'
+  - 'clientside_validation:clientside_validation_jquery'
+
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
+project: 'webform'
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.install b/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.install
new file mode 100644
index 0000000000..34bbb5fed7
--- /dev/null
+++ b/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.install
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @file
+ * Installation information for the 'Webform clientside validation' module.
+ */
+
+/**
+ * Implements hook_install().
+ */
+function webform_clientside_validation_install() {
+  // 'Webform clientside validation' module must execute before the
+  // 'Clientside validation' module.
+  // @see webform_clientside_validation_element_info_alter()
+  module_set_weight('webform_clientside_validation', -1);
+}
diff --git a/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.libraries.yml b/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.libraries.yml
new file mode 100644
index 0000000000..f3925c41e2
--- /dev/null
+++ b/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.libraries.yml
@@ -0,0 +1,16 @@
+webform_clientside_validation.novalidate:
+  version: VERSION
+  js:
+    js/webform_clientside_validation.novalidate.js: {}
+  dependencies:
+    - clientside_validation_jquery/cv.jquery.validate
+
+webform_clientside_validation.ife:
+  version: VERSION
+  js:
+    js/webform_clientside_validation.ife.js: {}
+  css:
+    component:
+      css/webform_clientside_validation.ife.css: { }
+  dependencies:
+    - clientside_validation_jquery/cv.jquery.validate.ife
diff --git a/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.module b/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.module
new file mode 100644
index 0000000000..42bd8c51d5
--- /dev/null
+++ b/web/modules/webform/modules/webform_clientside_validation/webform_clientside_validation.module
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * @file
+ * Helps support Webform to Clientside Validation integration.
+ */
+
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Implements hook_webform_submission_form_alter().
+ */
+function webform_clientside_validation_webform_submission_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
+  if (\Drupal::moduleHandler()->moduleExists('inline_form_errors')) {
+    $form['#attached']['library'][] = 'webform_clientside_validation/webform_clientside_validation.ife';
+  }
+  if (isset($form['#attributes']['novalidate'])) {
+    $form['#attributes']['data-webform-clientside-validation-novalidate'] = TRUE;
+    $form['#attached']['library'][] = 'webform_clientside_validation/webform_clientside_validation.novalidate';
+  }
+}
+
+/**
+ * Implements hook_element_info_alter().
+ */
+function webform_clientside_validation_element_info_alter(array &$info) {
+  if (isset($info['webform_email_confirm'])) {
+    $info['webform_email_confirm']['#process'][] = '_webform_clientside_validation_webform_email_confirm_process';
+  }
+}
+
+/**
+ * Process 'webform_email_confirm' element and add 'equal_to' validation rules.
+ *
+ * @see \Drupal\webform\Element\WebformEmailConfirm::processWebformEmailConfirm
+ */
+function _webform_clientside_validation_webform_email_confirm_process(&$element, FormStateInterface $form_state, &$complete_form) {
+  $validation_properties = [
+    '#equal_to' => $element['#name'] . '[mail_1]',
+    '#equal_to_error' => t('The specified email addresses do not match.'),
+  ];
+  if (empty($element['#flexbox'])) {
+    $element['mail_2'] += $validation_properties;
+  }
+  else {
+    $element['flexbox']['mail_2'] += $validation_properties;
+  }
+  return $element;
+}
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml
index d77827b5ad..81488ed2e4 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application.yml
@@ -157,7 +157,7 @@ elements: |
       '#access_update_roles': {  }
       '#access_view_roles':
         - authenticated
-  
+
 css: ''
 javascript: ''
 settings:
@@ -169,7 +169,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -199,6 +199,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: 'Application: [webform_submission:values:contact:name]'
   submission_log: false
   submission_views: {  }
@@ -224,11 +229,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml
index 02541abe05..3e379b9a7e 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/config/install/webform.webform.demo_application_evaluation.yml
@@ -25,12 +25,12 @@ elements: |
       {{ children }}
       <div>{{ 'Submitted by'|t }}: <em>[webform_submission:user]</em></div>
       <hr/>
-  
+
     '#format_text': |
       {{ children }}
       {{ 'Submitted by'|t }} [webform_submission:user]
       ------------------------------------------------------------
-  
+
     rating:
       '#type': webform_rating
       '#title': Rating
@@ -38,7 +38,7 @@ elements: |
     comments:
       '#type': textarea
       '#title': Comments
-  
+
 css: ''
 javascript: ''
 settings:
@@ -50,7 +50,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -80,6 +80,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -105,11 +110,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.info.yml b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.info.yml
index 8ce1cd6c6c..7f0e69cdff 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.info.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.info.yml
@@ -2,14 +2,14 @@ name: 'Webform Demo: Application/Evaluation System'
 type: module
 description: 'Demonstrates how to use the Webform module to build an application/evaluation system.'
 package: 'Webform Demo'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:block'
   - 'drupal:views'
   - 'webform:webform'
   - 'webform:webform_node'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.module b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.module
index e488c76dea..7b39f8e283 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.module
+++ b/web/modules/webform/modules/webform_demo/webform_demo_application_evaluation/webform_demo_application_evaluation.module
@@ -8,10 +8,10 @@
 use Drupal\webform\WebformSubmissionInterface;
 
 /**
- * Implements hook_ENTITY_TYPE_presave().
+ * Implements hook_ENTITY_TYPE_presave() for webform_submission entities.
  */
 function webform_demo_application_evaluation_webform_submission_presave(WebformSubmissionInterface $webform_submission) {
-  if ($webform_submission->getWebform()->id() != 'demo_application') {
+  if ($webform_submission->getWebform()->id() !== 'demo_application') {
     return;
   }
 
@@ -28,7 +28,7 @@ function webform_demo_application_evaluation_webform_submission_presave(WebformS
   // datetime. For example, if the current state is 'completed' the related
   // datetime element is called 'completed_date'.
   // @see /admin/structure/webform/manage/demo_application
-  if ($original_data['state'] != $current_data['state']) {
+  if ($original_data['state'] !== $current_data['state']) {
     /** @var \Drupal\Core\Datetime\DateFormatterInterface $date_formatter */
     $date_formatter = \Drupal::service('date.formatter');
     $current_data[$current_data['state'] . '_date'] = $date_formatter->format(time(), 'html_datetime');
@@ -38,21 +38,21 @@ function webform_demo_application_evaluation_webform_submission_presave(WebformS
 }
 
 /**
- * Implements hook_ENTITY_TYPE_insert().
+ * Implements hook_ENTITY_TYPE_insert() for webform_submission entities.
  */
 function webform_demo_application_evaluation_webform_submission_insert(WebformSubmissionInterface $webform_submission) {
   _webform_demo_application_evaluation_calculate_evaluation_rating($webform_submission);
 }
 
 /**
- * Implements hook_ENTITY_TYPE_update().
+ * Implements hook_ENTITY_TYPE_update() for webform_submission entities.
  */
 function webform_demo_application_evaluation_webform_submission_update(WebformSubmissionInterface $webform_submission) {
   _webform_demo_application_evaluation_calculate_evaluation_rating($webform_submission);
 }
 
 /**
- * Implements hook_ENTITY_TYPE_delete().
+ * Implements hook_ENTITY_TYPE_delete() for webform_submission entities.
  */
 function webform_demo_application_evaluation_webform_submission_delete(WebformSubmissionInterface $webform_submission) {
   _webform_demo_application_evaluation_calculate_evaluation_rating($webform_submission);
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_event_registration/config/install/webform.webform.demo_event_registration.yml b/web/modules/webform/modules/webform_demo/webform_demo_event_registration/config/install/webform.webform.demo_event_registration.yml
index 082ee871ea..e2bb3cbff2 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_event_registration/config/install/webform.webform.demo_event_registration.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_event_registration/config/install/webform.webform.demo_event_registration.yml
@@ -60,7 +60,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Register
-  
+
 css: ''
 javascript: ''
 settings:
@@ -72,7 +72,7 @@ settings:
   page: false
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -102,6 +102,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: true
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: true
   submission_views: {  }
@@ -127,11 +132,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.info.yml b/web/modules/webform/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.info.yml
index 03c67a96a9..9bfdd6c732 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.info.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_event_registration/webform_demo_event_registration.info.yml
@@ -2,17 +2,18 @@ name: 'Webform Demo: Event Registration System'
 type: module
 description: 'Demonstrates how to use the Webform module to build an event registration system with email reminders.'
 package: 'Webform Demo'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:datetime'
   - 'drupal:views'
   - 'token:token'
   - 'webform:webform'
   - 'webform:webform_node'
-  - 'webform:webform_scheduled_email'
   - 'webform:webform_options_limit'
+  - 'webform:webform_scheduled_email'
+  - 'webform:webform_share'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_group/config/install/webform.webform.webform_group_contact.yml b/web/modules/webform/modules/webform_demo/webform_demo_group/config/install/webform.webform.webform_group_contact.yml
index 10bf658ead..453d978dda 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_group/config/install/webform.webform.webform_group_contact.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_group/config/install/webform.webform.webform_group_contact.yml
@@ -86,7 +86,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send message'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -98,7 +98,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -128,6 +128,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -153,11 +158,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.info.yml b/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.info.yml
index 7cf1167001..dba2ae599a 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.info.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.info.yml
@@ -2,7 +2,7 @@ name: 'Webform Demo: Group'
 type: module
 description: 'Demonstrates how to integrate the Webform module with the Group module.'
 package: 'Webform Demo'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:path'
   - 'group:group'
@@ -11,7 +11,7 @@ dependencies:
   - 'webform:webform_node'
   - 'webform:webform_group'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.install b/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.install
index 64234b1535..47057ed5fe 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.install
+++ b/web/modules/webform/modules/webform_demo/webform_demo_group/webform_demo_group.install
@@ -206,8 +206,7 @@ function webform_demo_group_uninstall() {
   }
 
   // Delete URL aliases.
-  // @todo Remove once Drupal 8.8.x is only supported.
-  $table_name = (floatval(\Drupal::VERSION) >= 8.8) ? 'path_alias' : 'url_alias';
+  $table_name = 'path_alias';
   $params = [':alias' => '/webform/group/%'];
   \Drupal::database()->query('DELETE FROM {' . $table_name . '} WHERE alias LIKE :alias', $params);
 }
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_region_contact/config/install/webform.webform.demo_region_contact.yml b/web/modules/webform/modules/webform_demo/webform_demo_region_contact/config/install/webform.webform.demo_region_contact.yml
index f8b92068fb..34d532807a 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_region_contact/config/install/webform.webform.demo_region_contact.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_region_contact/config/install/webform.webform.demo_region_contact.yml
@@ -39,7 +39,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send message'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -51,7 +51,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -81,6 +81,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -106,11 +111,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_demo/webform_demo_region_contact/webform_demo_region_contact.info.yml b/web/modules/webform/modules/webform_demo/webform_demo_region_contact/webform_demo_region_contact.info.yml
index 1e962edda6..5ce458166e 100644
--- a/web/modules/webform/modules/webform_demo/webform_demo_region_contact/webform_demo_region_contact.info.yml
+++ b/web/modules/webform/modules/webform_demo/webform_demo_region_contact/webform_demo_region_contact.info.yml
@@ -2,7 +2,7 @@ name: 'Webform Demo: Region Contact System'
 type: module
 description: 'Demonstrates how to use the Webform module to build a region based contact system.'
 package: 'Webform Demo'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:datetime'
   - 'token:token'
@@ -10,7 +10,7 @@ dependencies:
   - 'webform:webform_node'
   - 'webform:webform_access'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_devel/src/Commands/WebformDevelCommands.php b/web/modules/webform/modules/webform_devel/src/Commands/WebformDevelCommands.php
index e6b90bc9df..16a5154afb 100644
--- a/web/modules/webform/modules/webform_devel/src/Commands/WebformDevelCommands.php
+++ b/web/modules/webform/modules/webform_devel/src/Commands/WebformDevelCommands.php
@@ -52,7 +52,7 @@ public function __construct(StateInterface $state, UserDataInterface $user_data)
   public function drush_webform_devel_config_update() {
     module_load_include('inc', 'webform', 'includes/webform.install');
 
-    $files = file_scan_directory(drupal_get_path('module', 'webform'), '/^webform\.webform\..*\.yml$/');
+    $files = $files = \Drupal::service('file_system')->scanDirectory(drupal_get_path('module', 'webform'), '/^webform\.webform\..*\.yml$/');
     $total = 0;
     foreach ($files as $filename => $file) {
       try {
@@ -70,7 +70,7 @@ public function drush_webform_devel_config_update() {
         $data = _webform_update_webform_setting($data);
         $tidied_yaml = WebformYaml::encode($data) . PHP_EOL;
 
-        if ($tidied_yaml != $original_yaml) {
+        if ($tidied_yaml !== $original_yaml) {
           $this->output()->writeln(dt('Updating @file…', ['@file' => $file->filename]));
           file_put_contents($file->uri, $tidied_yaml);
           $total++;
diff --git a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiBaseForm.php b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiBaseForm.php
index 35a415d356..39c0d8c42d 100644
--- a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiBaseForm.php
+++ b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiBaseForm.php
@@ -40,7 +40,7 @@ abstract class WebformDevelEntityFormApiBaseForm extends EntityForm {
   protected $tokenManager;
 
   /**
-   * The webform element (plugin) manager.
+   * The webform element plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
@@ -179,7 +179,7 @@ protected function wrapTranslatableValue($value) {
       return $value;
     }
     else {
-       return '<T>' . $value . '</T>';
+      return '<T>' . $value . '</T>';
     }
   }
 
diff --git a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiExportForm.php b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiExportForm.php
index b6c8e47875..1d33727e55 100644
--- a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiExportForm.php
+++ b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiExportForm.php
@@ -164,7 +164,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $webform = $this->getEntity();
 
     // Get the Tar archive.
-    $archive_file_path = file_directory_temp() . '/' . $webform->id() . '.tar.gz';
+    $archive_file_path = \Drupal::service('file_system')->getTempDirectory() . '/' . $webform->id() . '.tar.gz';
     $archive = new \Archive_Tar($archive_file_path, 'gz');
 
     // Add code to archive.
@@ -189,7 +189,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
   /****************************************************************************/
 
   /**
-   * Set webform elements default values using test data..
+   * Set webform elements default values using test data.
    *
    * @param array $elements
    *   An render array representing elements.
@@ -235,7 +235,7 @@ class {{ class_name }}SettingsForm extends ConfigFormBase {
   protected $tokenManager;
 
   /**
-   * The webform element (plugin) manager.
+   * The webform element plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
diff --git a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiTestForm.php b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiTestForm.php
index b3e88b273f..c0b01e7b1a 100644
--- a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiTestForm.php
+++ b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntityFormApiTestForm.php
@@ -92,7 +92,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
   /****************************************************************************/
 
   /**
-   * Set webform elements default values using test data..
+   * Set webform elements default values using test data.
    *
    * @param array $elements
    *   An render array representing elements.
diff --git a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntitySchemaForm.php b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntitySchemaForm.php
index 53b6833d3d..7516d5bb79 100644
--- a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntitySchemaForm.php
+++ b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelEntitySchemaForm.php
@@ -71,7 +71,7 @@ public function form(array $form, FormStateInterface $form_state) {
         $rows[$element_key][$key] = ['#markup' => $value];
       }
 
-      if ($element['datatype'] == 'Composite') {
+      if ($element['datatype'] === 'Composite') {
         $rows[$element_key]['#attributes']['class'][] = 'webform-devel-schema-composite';
       }
 
diff --git a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelSubmissionApiForm.php b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelSubmissionApiForm.php
index c093541ee8..e15fbf56f9 100644
--- a/web/modules/webform/modules/webform_devel/src/Form/WebformDevelSubmissionApiForm.php
+++ b/web/modules/webform/modules/webform_devel/src/Form/WebformDevelSubmissionApiForm.php
@@ -19,14 +19,14 @@
 class WebformDevelSubmissionApiForm extends FormBase {
 
   /**
-   * Webform submission storage.
+   * The webform submission storage.
    *
    * @var \Drupal\webform\WebformSubmissionStorageInterface
    */
   protected $submissionStorage;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
@@ -132,12 +132,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 $values = ' . Variable::export($values) . ';
 
 // Check that the webform is open.
-$webform = \Drupal\webform\entity\Webform::load(\'' . $webform->id() . '\'); 
+$webform = \Drupal\webform\entity\Webform::load(\'' . $webform->id() . '\');
 $is_open = \Drupal\webform\WebformSubmissionForm::isOpen($webform);
 if ($is_open === TRUE) {
   // Validate webform submission values.
   $errors = \Drupal\webform\WebformSubmissionForm::validateFormValues($values);
-  
+
   // Submit webform submission values.
   if (empty($errors)) {
     $webform_submission = \Drupal\webform\WebformSubmissionForm::submitFormValues($values);
diff --git a/web/modules/webform/modules/webform_devel/src/WebformDevelSchema.php b/web/modules/webform/modules/webform_devel/src/WebformDevelSchema.php
index f70a13e2d5..c1c0f7e658 100644
--- a/web/modules/webform/modules/webform_devel/src/WebformDevelSchema.php
+++ b/web/modules/webform/modules/webform_devel/src/WebformDevelSchema.php
@@ -25,14 +25,14 @@ class WebformDevelSchema implements WebformDevelSchemaInterface {
   use StringTranslationTrait;
 
   /**
-   * A element info manager.
+   * The element info manager.
    *
    * @var \Drupal\Core\Render\ElementInfoManagerInterface
    */
   protected $elementInfo;
 
   /**
-   * Webform element manager.
+   * The webform element manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
diff --git a/web/modules/webform/modules/webform_devel/webform_devel.info.yml b/web/modules/webform/modules/webform_devel/webform_devel.info.yml
index 673ded1f58..92c48f8c45 100644
--- a/web/modules/webform/modules/webform_devel/webform_devel.info.yml
+++ b/web/modules/webform/modules/webform_devel/webform_devel.info.yml
@@ -2,12 +2,12 @@ name: 'Webform Devel'
 type: module
 description: 'Provides development tools for the Webform module.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'devel:devel'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_devel/webform_devel.module b/web/modules/webform/modules/webform_devel/webform_devel.module
index 6c7ca7e65b..4058014662 100644
--- a/web/modules/webform/modules/webform_devel/webform_devel.module
+++ b/web/modules/webform/modules/webform_devel/webform_devel.module
@@ -13,6 +13,7 @@
  * Implements hook_webform_help_info().
  */
 function webform_devel_webform_help_info() {
+  $help = [];
   $help['webform_devel_schema'] = [
     'group' => 'development',
     'title' => t('Devel: Webform Schema'),
@@ -23,7 +24,6 @@ function webform_devel_webform_help_info() {
       'entity.webform.schema_form',
     ],
   ];
-
   $help['webform_devel_form_api_export'] = [
     'group' => 'forms',
     'title' => t('Form API Export'),
@@ -33,7 +33,6 @@ function webform_devel_webform_help_info() {
       'entity.webform.fapi_export_form',
     ],
   ];
-
   return $help;
 }
 
@@ -53,7 +52,7 @@ function webform_devel_entity_type_alter(array &$entity_types) {
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for config single export form.
  */
 function webform_devel_form_config_single_export_form_alter(&$form, FormStateInterface $form_state) {
   $form['export']['#type'] = 'webform_codemirror';
diff --git a/web/modules/webform/modules/webform_editorial/src/Controller/WebformEditorialController.php b/web/modules/webform/modules/webform_editorial/src/Controller/WebformEditorialController.php
index 0f1e980709..8c15136a37 100644
--- a/web/modules/webform/modules/webform_editorial/src/Controller/WebformEditorialController.php
+++ b/web/modules/webform/modules/webform_editorial/src/Controller/WebformEditorialController.php
@@ -58,7 +58,7 @@ class WebformEditorialController extends ControllerBase implements ContainerInje
   protected $elementManager;
 
   /**
-   * The libraries manager.
+   * The webform libraries manager.
    *
    * @var \Drupal\webform\WebformLibrariesManagerInterface
    */
diff --git a/web/modules/webform/modules/webform_editorial/webform_editorial.info.yml b/web/modules/webform/modules/webform_editorial/webform_editorial.info.yml
index 5a26eeb8d9..d2fcb654ab 100644
--- a/web/modules/webform/modules/webform_editorial/webform_editorial.info.yml
+++ b/web/modules/webform/modules/webform_editorial/webform_editorial.info.yml
@@ -2,13 +2,13 @@ name: 'Webform Editorial'
 type: module
 description: 'Provides editorial management tools for the Webform module.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 configure: webform_editorial.index
 hidden: true
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_entity_print/src/EventSubscriber/WebformEntityPrintRequestSubscriber.php b/web/modules/webform/modules/webform_entity_print/src/EventSubscriber/WebformEntityPrintRequestSubscriber.php
index a98957e290..4d31519614 100644
--- a/web/modules/webform/modules/webform_entity_print/src/EventSubscriber/WebformEntityPrintRequestSubscriber.php
+++ b/web/modules/webform/modules/webform_entity_print/src/EventSubscriber/WebformEntityPrintRequestSubscriber.php
@@ -34,7 +34,7 @@ public function __construct(RouteMatchInterface $route_match) {
    * Set custom webform entity print submission view mode.
    */
   public function requestSetViewMode(GetResponseEvent $event) {
-    if ($event->getRequestType() != HttpKernelInterface::MASTER_REQUEST) {
+    if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) {
       return;
     }
 
diff --git a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print.yml b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print.yml
index e8cfc14deb..9b96c400ad 100644
--- a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print.yml
+++ b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print.yml
@@ -18,7 +18,7 @@ elements: |
   textfield:
     '#type': textfield
     '#title': textfield
-  
+
 css: '/** custom webform css **/'
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: both
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print_custom.yml b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print_custom.yml
index 841a889929..e94d9f5e99 100644
--- a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print_custom.yml
+++ b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/config/install/webform.webform.test_entity_print_custom.yml
@@ -18,7 +18,7 @@ elements: |
   textfield:
     '#type': textfield
     '#title': textfield
-  
+
 css: '/** custom webform css **/'
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: both
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/webform_entity_print_test.info.yml b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/webform_entity_print_test.info.yml
index 873fc2e515..77aed7df4d 100644
--- a/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/webform_entity_print_test.info.yml
+++ b/web/modules/webform/modules/webform_entity_print/tests/modules/webform_entity_print_test/webform_entity_print_test.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform Entity Print (PDF) Test'
+name: 'Webform Entity Print (PDF) test'
 type: module
 description: 'Support module for webform entity print (PDF) testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_entity_print'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_entity_print/tests/src/Functional/WebformEntityPrintFunctionalTest.php b/web/modules/webform/modules/webform_entity_print/tests/src/Functional/WebformEntityPrintFunctionalTest.php
index 991120eabc..5800c40c0a 100644
--- a/web/modules/webform/modules/webform_entity_print/tests/src/Functional/WebformEntityPrintFunctionalTest.php
+++ b/web/modules/webform/modules/webform_entity_print/tests/src/Functional/WebformEntityPrintFunctionalTest.php
@@ -72,7 +72,7 @@ public function testEntityPrint() {
     $edit = [
       'third_party_settings[webform_entity_print][export_types][pdf][link_text]' => 'Generate PDF',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config', $edit, 'Save configuration');
     $this->drupalGet("/admin/structure/webform/manage/test_entity_print/submission/$sid");
     $this->assertNoLink('Download PDF');
     $this->assertLink('Generate PDF');
@@ -81,7 +81,7 @@ public function testEntityPrint() {
     $edit = [
       'third_party_settings[webform_entity_print][export_types][pdf][enabled]' => FALSE,
     ];
-    $this->drupalPostForm('/admin/structure/webform/config', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config', $edit, 'Save configuration');
     $this->drupalGet("/admin/structure/webform/manage/test_entity_print/submission/$sid");
     $this->assertNoLink('Download PDF');
 
@@ -98,7 +98,7 @@ public function testEntityPrint() {
     $edit = [
       'exporter' => 'webform_entity_print:pdf',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_entity_print/results/download', $edit, t('Download'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_entity_print/results/download', $edit, 'Download');
 
     // Load the tar and get a list of files.
     $files = $this->getArchiveContents($submission_exporter->getArchiveFilePath());
diff --git a/web/modules/webform/modules/webform_entity_print/tests/src/Functional/WebformEntityPrintFunctionalTestBase.php b/web/modules/webform/modules/webform_entity_print/tests/src/Functional/WebformEntityPrintFunctionalTestBase.php
index 9555c6ddb2..defcccfa4a 100644
--- a/web/modules/webform/modules/webform_entity_print/tests/src/Functional/WebformEntityPrintFunctionalTestBase.php
+++ b/web/modules/webform/modules/webform_entity_print/tests/src/Functional/WebformEntityPrintFunctionalTestBase.php
@@ -21,7 +21,11 @@ abstract class WebformEntityPrintFunctionalTestBase extends WebformBrowserTestBa
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
+    if (floatval(\Drupal::VERSION) >= 9) {
+      $this->markTestSkipped('Issue #3110478: [Webform 8.x-6.x] Track the D9 readiness state of the Webform module\'s (optional) dependencies');
+    }
+
     parent::setUp();
 
     // Use test print engine.
diff --git a/web/modules/webform/modules/webform_entity_print/webform_entity_print.info.yml b/web/modules/webform/modules/webform_entity_print/webform_entity_print.info.yml
index 58ad9e6e7b..d9781f6f5f 100644
--- a/web/modules/webform/modules/webform_entity_print/webform_entity_print.info.yml
+++ b/web/modules/webform/modules/webform_entity_print/webform_entity_print.info.yml
@@ -2,12 +2,12 @@ name: 'Webform Entity Print (PDF)'
 type: module
 description: 'Provides Entity Print (PDF) integration and allows site builders to download, export, and email PDF copies of webform submissions.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
   - 'entity_print:entity_print'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_entity_print/webform_entity_print.module b/web/modules/webform/modules/webform_entity_print/webform_entity_print.module
index 3d7c0e82e0..e3669ab094 100644
--- a/web/modules/webform/modules/webform_entity_print/webform_entity_print.module
+++ b/web/modules/webform/modules/webform_entity_print/webform_entity_print.module
@@ -13,7 +13,7 @@
 use Drupal\Core\Render\Markup;
 
 /**
- * Implements hook_ENTITY_TYPE_view_alter().
+ * Implements hook_ENTITY_TYPE_view_alter() for webform_submission entities.
  *
  * @see entity_print_entity_view_alter();
  */
diff --git a/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/config/install/webform.webform.test_entity_print_attachment.yml b/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/config/install/webform.webform.test_entity_print_attachment.yml
index 5937705a44..c78b2a91ae 100644
--- a/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/config/install/webform.webform.test_entity_print_attachment.yml
+++ b/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/config/install/webform.webform.test_entity_print_attachment.yml
@@ -33,7 +33,7 @@ elements: |
     '#display_on': both
     '#view_mode': twig
     '#template': '{This is a custom template}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -45,7 +45,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: both
   form_submit_once: false
   form_exception_message: ''
@@ -75,6 +75,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -100,11 +105,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/webform_entity_print_attachment_test.info.yml b/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/webform_entity_print_attachment_test.info.yml
index fb88feaf4f..1e12511a41 100644
--- a/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/webform_entity_print_attachment_test.info.yml
+++ b/web/modules/webform/modules/webform_entity_print_attachment/tests/modules/webform_entity_print_attachment_test/webform_entity_print_attachment_test.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform Entity Print (PDF) Attachment Test'
+name: 'Webform Entity Print (PDF) Attachment test'
 type: module
 description: 'Support module for webform entity print (PDF) attachment testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_entity_print_attachment'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_entity_print_attachment/webform_entity_print_attachment.info.yml b/web/modules/webform/modules/webform_entity_print_attachment/webform_entity_print_attachment.info.yml
index 38302effa5..ff5392e305 100644
--- a/web/modules/webform/modules/webform_entity_print_attachment/webform_entity_print_attachment.info.yml
+++ b/web/modules/webform/modules/webform_entity_print_attachment/webform_entity_print_attachment.info.yml
@@ -2,12 +2,12 @@ name: 'Webform Entity Print (PDF) Attachment'
 type: module
 description: 'Provides Webform Entity Print (PDF) Attachment integration.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_attachment'
   - 'webform:webform_entity_print'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_example_composite/config/install/webform.webform.webform_example_composite.yml b/web/modules/webform/modules/webform_example_composite/config/install/webform.webform.webform_example_composite.yml
index 78d833c4c6..154acab85d 100644
--- a/web/modules/webform/modules/webform_example_composite/config/install/webform.webform.webform_example_composite.yml
+++ b/web/modules/webform/modules/webform_example_composite/config/install/webform.webform.webform_example_composite.yml
@@ -23,7 +23,7 @@ elements: |
     '#title': 'Webform Example Composite Multiple'
     '#multiple': true
     '#multiple__header': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -35,7 +35,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -65,6 +65,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -90,11 +95,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_example_composite/templates/webform-example-composite.html.twig b/web/modules/webform/modules/webform_example_composite/templates/webform-example-composite.html.twig
index 55a6306102..eab9d033d8 100644
--- a/web/modules/webform/modules/webform_example_composite/templates/webform-example-composite.html.twig
+++ b/web/modules/webform/modules/webform_example_composite/templates/webform-example-composite.html.twig
@@ -13,7 +13,6 @@
 #}
 {{ attach_library('webform_example_composite/webform_example_composite') }}
 {% if flexbox %}
-
     <div class="webform-flexbox">
       {% if content.first_name %}
         <div class="webform-flex webform-flex--1"><div class="webform-flex--container">{{ content.first_name }}</div></div>
@@ -28,7 +27,6 @@
         <div class="webform-flex webform-flex--1"><div class="webform-flex--container">{{ content.gender }}</div></div>
       {% endif %}
     </div>
-
 {% else %}
   {{ content }}
 {% endif %}
diff --git a/web/modules/webform/modules/webform_example_composite/tests/src/Functional/WebformExampleCompositeTest.php b/web/modules/webform/modules/webform_example_composite/tests/src/Functional/WebformExampleCompositeTest.php
index a493d8638b..40f2958a0a 100644
--- a/web/modules/webform/modules/webform_example_composite/tests/src/Functional/WebformExampleCompositeTest.php
+++ b/web/modules/webform/modules/webform_example_composite/tests/src/Functional/WebformExampleCompositeTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform example composite.
  *
- * @group Webform
+ * @group webform_example_composite
  */
 class WebformExampleCompositeTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_example_composite/webform_example_composite.info.yml b/web/modules/webform/modules/webform_example_composite/webform_example_composite.info.yml
index 34d0b1db93..ca2fe0518b 100644
--- a/web/modules/webform/modules/webform_example_composite/webform_example_composite.info.yml
+++ b/web/modules/webform/modules/webform_example_composite/webform_example_composite.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Example Composite'
 type: module
 description: 'Provides an example that shows how to create a Webform composite.'
 package: 'Webform example'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_example_custom_form/config/install/webform.webform.webform_example_custom_form.yml b/web/modules/webform/modules/webform_example_custom_form/config/install/webform.webform.webform_example_custom_form.yml
index ba61a1dda0..3fc73f2751 100644
--- a/web/modules/webform/modules/webform_example_custom_form/config/install/webform.webform.webform_example_custom_form.yml
+++ b/web/modules/webform/modules/webform_example_custom_form/config/install/webform.webform.webform_example_custom_form.yml
@@ -303,7 +303,7 @@ elements: |
           last_name: Smith
         - first_name: Jane
           last_name: Doe
-  
+
 css: ''
 javascript: ''
 settings:
@@ -315,7 +315,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -345,6 +345,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -370,11 +375,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_example_custom_form/src/Form/WebformExampleCustomFormSettingsForm.php b/web/modules/webform/modules/webform_example_custom_form/src/Form/WebformExampleCustomFormSettingsForm.php
index 407f588a5f..6959e8cc5b 100644
--- a/web/modules/webform/modules/webform_example_custom_form/src/Form/WebformExampleCustomFormSettingsForm.php
+++ b/web/modules/webform/modules/webform_example_custom_form/src/Form/WebformExampleCustomFormSettingsForm.php
@@ -19,7 +19,7 @@ class WebformExampleCustomFormSettingsForm extends ConfigFormBase {
   protected $tokenManager;
 
   /**
-   * The webform element (plugin) manager.
+   * The webform element plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
diff --git a/web/modules/webform/modules/webform_example_custom_form/webform_example_custom_form.info.yml b/web/modules/webform/modules/webform_example_custom_form/webform_example_custom_form.info.yml
index 848176e74a..7622b25699 100644
--- a/web/modules/webform/modules/webform_example_custom_form/webform_example_custom_form.info.yml
+++ b/web/modules/webform/modules/webform_example_custom_form/webform_example_custom_form.info.yml
@@ -2,13 +2,13 @@ name: 'Webform Custom Form Example'
 type: module
 description: 'Provides an example of custom configuration form built using the Webform module.'
 package: 'Webform example'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 configure: webform_example_custom_form.settings
 dependencies:
   - 'webform:webform'
   - 'webform:webform_devel'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_example_element/config/install/webform.webform.webform_example_element.yml b/web/modules/webform/modules/webform_example_element/config/install/webform.webform.webform_example_element.yml
index 8f7ed20f6e..a336919001 100644
--- a/web/modules/webform/modules/webform_example_element/config/install/webform.webform.webform_example_element.yml
+++ b/web/modules/webform/modules/webform_example_element/config/install/webform.webform.webform_example_element.yml
@@ -22,7 +22,7 @@ elements: |
     '#type': webform_example_element
     '#title': 'Webform Example Element Multiple'
     '#multiple': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -34,7 +34,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -64,6 +64,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -89,11 +94,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_example_element/tests/src/Functional/WebformExampleElementTest.php b/web/modules/webform/modules/webform_example_element/tests/src/Functional/WebformExampleElementTest.php
index 2bebc72fbe..22896987f6 100644
--- a/web/modules/webform/modules/webform_example_element/tests/src/Functional/WebformExampleElementTest.php
+++ b/web/modules/webform/modules/webform_example_element/tests/src/Functional/WebformExampleElementTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform example element.
  *
- * @group Webform
+ * @group webform_example_element
  */
 class WebformExampleElementTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_example_element/webform_example_element.info.yml b/web/modules/webform/modules/webform_example_element/webform_example_element.info.yml
index 773d4bde24..a48c6cc317 100644
--- a/web/modules/webform/modules/webform_example_element/webform_example_element.info.yml
+++ b/web/modules/webform/modules/webform_example_element/webform_example_element.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Element Example'
 type: module
 description: 'Provides an example that shows how to create a Webform element.'
 package: 'Webform example'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_example_element_properties/tests/src/Functional/WebformExampleElementPropertiesTest.php b/web/modules/webform/modules/webform_example_element_properties/tests/src/Functional/WebformExampleElementPropertiesTest.php
index 540bdece78..ed3cce92b6 100644
--- a/web/modules/webform/modules/webform_example_element_properties/tests/src/Functional/WebformExampleElementPropertiesTest.php
+++ b/web/modules/webform/modules/webform_example_element_properties/tests/src/Functional/WebformExampleElementPropertiesTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform example element properties.
  *
- * @group Webform
+ * @group webform_example_element_properties
  */
 class WebformExampleElementPropertiesTest extends WebformBrowserTestBase {
 
@@ -58,7 +58,7 @@ public function testCustomProperties() {
     $edit = [
       'properties[custom_data]' => '',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/name/edit', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/name/edit', $edit, 'Save');
 
     // Get updated contact webform.
     $webform_storage->resetCache();
@@ -72,7 +72,7 @@ public function testCustomProperties() {
     $edit = [
       'properties[custom_data]' => 'custom-data',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/name/edit', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/name/edit', $edit, 'Save');
 
     // Get updated contact webform.
     $webform_storage->resetCache();
diff --git a/web/modules/webform/modules/webform_example_element_properties/webform_example_element_properties.info.yml b/web/modules/webform/modules/webform_example_element_properties/webform_example_element_properties.info.yml
index 8b55e9ec1b..c53e13a9f9 100644
--- a/web/modules/webform/modules/webform_example_element_properties/webform_example_element_properties.info.yml
+++ b/web/modules/webform/modules/webform_example_element_properties/webform_example_element_properties.info.yml
@@ -2,12 +2,12 @@ name: 'Webform Element Properties Example'
 type: module
 description: 'Provides an example that shows how to add custom properties to Webform elements.'
 package: 'Webform example'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
   - 'webform:webform_ui'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_example_handler/config/install/webform.webform.webform_example_handler.yml b/web/modules/webform/modules/webform_example_handler/config/install/webform.webform.webform_example_handler.yml
index 7fff2615a3..5a888bed1a 100644
--- a/web/modules/webform/modules/webform_example_handler/config/install/webform.webform.webform_example_handler.yml
+++ b/web/modules/webform/modules/webform_example_handler/config/install/webform.webform.webform_example_handler.yml
@@ -22,7 +22,7 @@ elements: |
     '#title': Value
     '#required': true
     '#description': 'Enter a value to displayed in a custom message.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -34,7 +34,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -64,6 +64,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -89,11 +94,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_example_handler/webform_example_handler.info.yml b/web/modules/webform/modules/webform_example_handler/webform_example_handler.info.yml
index 1694032e29..32f04e71be 100644
--- a/web/modules/webform/modules/webform_example_handler/webform_example_handler.info.yml
+++ b/web/modules/webform/modules/webform_example_handler/webform_example_handler.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Handler Example'
 type: module
 description: 'Provides an example of a webform handler.'
 package: 'Webform example'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_example_remote_post/config/install/webform.webform.example_remote_post.yml b/web/modules/webform/modules/webform_example_remote_post/config/install/webform.webform.example_remote_post.yml
index debc224bf4..3b4be2a462 100644
--- a/web/modules/webform/modules/webform_example_remote_post/config/install/webform.webform.example_remote_post.yml
+++ b/web/modules/webform/modules/webform_example_remote_post/config/install/webform.webform.example_remote_post.yml
@@ -39,7 +39,7 @@ elements: |
     '#title': 'Confirmation number'
     '#type': value
     '#value': '[webform:handler:remote_post:completed:confirmation_number]'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -51,7 +51,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -81,6 +81,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -106,11 +111,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -130,7 +141,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-    
+
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -238,22 +249,22 @@ handlers:
         confirmation_number: confirmation_number
       custom_data: |
         custom_all: true
-        
+
       custom_options: ''
       cast: false
       debug: true
       completed_url: '[site:url]webform_example_remote_post/completed'
       completed_custom_data: |
         custom_completed: true
-        
+
       updated_url: '[site:url]webform_example_remote_post/updated'
       updated_custom_data: |
         custom_updated: true
-        
+
       deleted_url: '[site:url]webform_example_remote_post/deleted'
       deleted_custom_data: |
         custom_deleted: true
-        
+
       draft_created_url: ''
       draft_created_custom_data: ''
       draft_updated_url: ''
diff --git a/web/modules/webform/modules/webform_example_remote_post/webform_example_remote_post.info.yml b/web/modules/webform/modules/webform_example_remote_post/webform_example_remote_post.info.yml
index a7d2be0491..abb68e9e7d 100644
--- a/web/modules/webform/modules/webform_example_remote_post/webform_example_remote_post.info.yml
+++ b/web/modules/webform/modules/webform_example_remote_post/webform_example_remote_post.info.yml
@@ -2,12 +2,12 @@ name: 'Webform Remote Post Example'
 type: module
 description: 'Provides an example of a webform submission posted to a remote server.'
 package: 'Webform example'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'token:token'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_ab_test.yml b/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_ab_test.yml
index 49887c04ec..dc4cf207b2 100644
--- a/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_ab_test.yml
+++ b/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_ab_test.yml
@@ -45,7 +45,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Submit feedback'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -57,7 +57,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -87,6 +87,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -112,11 +117,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -317,7 +328,7 @@ variants:
           '#title_display': 'inline'
         actions:
           '#title': 'Submit'
-        
+
       handlers:
         email_confirmation:
           status: false
diff --git a/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_segments.yml b/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_segments.yml
index 06a2749e9b..b222cc943c 100644
--- a/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_segments.yml
+++ b/web/modules/webform/modules/webform_example_variant/config/install/webform.webform.webform_example_variant_segments.yml
@@ -33,7 +33,7 @@ elements: |
   notes:
     '#type': textfield
     '#title': Notes
-  
+
 css: ''
 javascript: ''
 settings:
@@ -45,7 +45,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -75,6 +75,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -100,11 +105,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_example_variant/webform_example_variant.info.yml b/web/modules/webform/modules/webform_example_variant/webform_example_variant.info.yml
index 0fc4984145..27a12d9e06 100644
--- a/web/modules/webform/modules/webform_example_variant/webform_example_variant.info.yml
+++ b/web/modules/webform/modules/webform_example_variant/webform_example_variant.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Variant Example'
 type: module
 description: 'Provides an example of webform variants.'
 package: 'Webform example'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements.yml
index 72bdd8bd8b..36d89cdb2c 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements.yml
@@ -46,7 +46,7 @@ elements: |
           Hello {{ data.first_name }} {{ data.last_name }}!!!
         </h2>
         <p>You are {{ ('now'|date('Y')) - (data.date_of_birth|date('Y'))  }} years old.</p>
-  
+
 css: ''
 javascript: ''
 settings:
@@ -58,7 +58,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -88,6 +88,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -113,11 +118,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements_ajax.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements_ajax.yml
index 3a5ee98eea..75c2b57905 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements_ajax.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_computed_elements_ajax.yml
@@ -105,7 +105,7 @@ elements: |
       '#ajax': true
       '#hide_empty': true
       '#template': '[webform_submission:values:user:entity:created:clear]'
-  
+
 css: |
   .calculation {
     font-size: 2em;
@@ -114,7 +114,7 @@ css: |
     width: 4em;
     text-align: right;
   }
-  
+
 javascript: ''
 settings:
   ajax: false
@@ -125,7 +125,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -155,6 +155,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -180,11 +185,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_element_states.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_element_states.yml
index e41084ca6e..df7676951c 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_element_states.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_element_states.yml
@@ -191,7 +191,7 @@ elements: |
         readonly:
           ':input[name="readonly_checkbox"]':
             checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -203,7 +203,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -233,6 +233,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -258,11 +263,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_flexbox_layout.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_flexbox_layout.yml
index 1e09a09bef..b6dae0b8e6 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_flexbox_layout.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_flexbox_layout.yml
@@ -117,7 +117,7 @@ elements: |
     url:
       '#type': url
       '#title': 'Home page (URL)'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -129,7 +129,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -159,6 +159,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -184,11 +189,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_input_masks.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_input_masks.yml
index aa9b18a471..4d0d018ab8 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_input_masks.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_input_masks.yml
@@ -85,7 +85,7 @@ elements: |
       '#type': textfield
       '#title': lowercase
       '#input_mask': '''casing'': ''lower'''
-  
+
 css: ''
 javascript: ''
 settings:
@@ -97,7 +97,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -127,6 +127,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -152,11 +157,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_style_guide.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_style_guide.yml
index c56ea8d825..9102ae2067 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_style_guide.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_style_guide.yml
@@ -655,7 +655,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -685,6 +685,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -710,11 +715,17 @@ settings:
   wizard_progress_percentage: true
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_wizard.yml b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_wizard.yml
index 8b81393c65..168be2eb38 100644
--- a/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_wizard.yml
+++ b/web/modules/webform/modules/webform_examples/config/install/webform.webform.example_wizard.yml
@@ -24,13 +24,16 @@ elements: |
     first_name:
       '#title': 'First Name'
       '#type': textfield
+      '#required': true
     last_name:
       '#title': 'Last Name'
       '#type': textfield
+      '#required': true
     gender:
       '#type': webform_radios_other
       '#title': Gender
       '#options': gender
+      '#required': true
   contact:
     '#title': 'Contact Information'
     '#type': webform_wizard_page
@@ -38,9 +41,11 @@ elements: |
     email:
       '#title': Email
       '#type': email
+      '#required': true
     phone:
       '#title': Phone
       '#type': tel
+      '#required': true
     contact_via_phone:
       '#type': radios
       '#title': 'Can we contact you via phone?'
@@ -51,15 +56,11 @@ elements: |
     '#open': true
     comments:
       '#type': textarea
-  actions:
-    '#type': webform_actions
-    '#title': 'Submit button(s)'
-    '#submit__label': Apply
-  
+
 css: ''
 javascript: ''
 settings:
-  ajax: false
+  ajax: true
   ajax_scroll_top: form
   ajax_progress_type: ''
   ajax_effect: ''
@@ -67,7 +68,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -97,6 +98,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -122,11 +128,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: true
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: true
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 2
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples/config/optional/webform.webform.example_cards.yml b/web/modules/webform/modules/webform_examples/config/optional/webform.webform.example_cards.yml
new file mode 100644
index 0000000000..882b90cf6b
--- /dev/null
+++ b/web/modules/webform/modules/webform_examples/config/optional/webform.webform.example_cards.yml
@@ -0,0 +1,261 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_examples
+      - webform_cards
+open: null
+close: null
+weight: 0
+uid: 0
+template: false
+archive: false
+id: example_cards
+title: 'Example: Cards'
+description: 'Example of a multiple step &#39;cards&#39; webform.'
+category: Example
+elements: |
+  first_name_card:
+    '#type': webform_card
+    '#title': 'First Name'
+    '#title_display': invisible
+    '#format': container
+    first_name:
+      '#title': 'First Name'
+      '#type': textfield
+      '#required': true
+  last_name_card:
+    '#type': webform_card
+    '#title': 'Last Name'
+    '#title_display': invisible
+    '#format': container
+    last_name:
+      '#title': 'Last Name'
+      '#type': textfield
+      '#required': true
+  gender_card:
+    '#type': webform_card
+    '#title': Gender
+    '#title_display': invisible
+    '#format': container
+    gender:
+      '#type': webform_radios_other
+      '#title': Gender
+      '#options': gender
+      '#options_display': buttons_vertical
+      '#required': true
+  email_card:
+    '#type': webform_card
+    '#title': Email
+    '#title_display': invisible
+    '#format': container
+    email:
+      '#title': Email
+      '#type': email
+      '#required': true
+  phone_card:
+    '#type': webform_card
+    '#title': Phone
+    '#title_display': invisible
+    '#format': container
+    phone:
+      '#title': Phone
+      '#type': tel
+      '#required': true
+  contact_via_phone_card:
+    '#type': webform_card
+    '#title': 'Contact Phone'
+    '#title_display': invisible
+    '#format': container
+    contact_via_phone:
+      '#type': radios
+      '#title': 'Can we contact you via phone?'
+      '#options': yes_no
+      '#options_display': buttons
+      '#required': true
+  comments_card:
+    '#type': webform_card
+    '#title': Comments
+    '#title_display': invisible
+    '#format': container
+    comments:
+      '#title': Comments
+      '#type': textarea
+
+css: ''
+javascript: ''
+settings:
+  ajax: true
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: false
+  wizard_progress_pages: true
+  wizard_progress_percentage: true
+  wizard_progress_link: true
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: true
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: true
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: inline
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers: {  }
+variants: {  }
diff --git a/web/modules/webform/modules/webform_examples/webform_examples.info.yml b/web/modules/webform/modules/webform_examples/webform_examples.info.yml
index 0809a3eae7..f8ab38b146 100644
--- a/web/modules/webform/modules/webform_examples/webform_examples.info.yml
+++ b/web/modules/webform/modules/webform_examples/webform_examples.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Examples'
 type: module
 description: 'Provides examples of all webform elements and functionality which can used for demonstrating and testing advanced functionality or used as cut-n-paste code snippets for creating new webforms.'
 package: 'Webform example'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_advanced.yml b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_advanced.yml
index e25473f6f4..2f645a81e6 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_advanced.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_advanced.yml
@@ -209,7 +209,7 @@ elements: |
         last_name:
           '#type': textfield
           '#title': 'Last name'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -221,7 +221,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -251,6 +251,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -276,11 +281,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_basic.yml b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_basic.yml
index d198162892..770dac41f3 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_basic.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_basic.yml
@@ -125,7 +125,7 @@ elements: |
       '#output': right
       '#output__field_prefix': $
       '#output__field_suffix': '.00'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -137,7 +137,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -167,6 +167,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -192,11 +197,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_containers.yml b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_containers.yml
index fc3dc4a40f..82546e017f 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_containers.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_containers.yml
@@ -50,7 +50,7 @@ elements: |
     '#help': 'This is help text'
     '#required': true
     '#description': 'This is a description'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -62,7 +62,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -92,6 +92,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -117,11 +122,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_labels.yml b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_labels.yml
index 98b268ec57..5c95fcafa1 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_labels.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_labels.yml
@@ -180,7 +180,7 @@ elements: |
       '#help': 'This is help text'
       '#required': true
       '#description': 'This is a description'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -192,7 +192,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -222,6 +222,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -247,11 +252,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_wizard.yml b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_wizard.yml
index a72b73d52b..f538771f26 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_wizard.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/config/install/webform.webform.example_accessibility_wizard.yml
@@ -55,7 +55,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Apply
-  
+
 css: ''
 javascript: ''
 settings:
@@ -67,7 +67,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -97,6 +97,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -122,11 +127,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: true
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: true
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 2
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.info.yml b/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.info.yml
index dc75f3677b..273125a1cc 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.info.yml
+++ b/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Examples Accessibility'
 type: module
 description: 'Provides example webforms for reviewing and testing accessibility.'
 package: 'Webform example'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.module b/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.module
index b35c237c2b..9305408c29 100644
--- a/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.module
+++ b/web/modules/webform/modules/webform_examples_accessibility/webform_examples_accessibility.module
@@ -14,7 +14,7 @@
  */
 function webform_examples_accessibility_page_attachments(array &$attachments) {
   // Attach accessibility library which shows all fieldsets and labels.
-  if (\Drupal::request()->query->get('accessibility') == '1') {
+  if (\Drupal::request()->query->get('accessibility') === '1') {
     $attachments['#attached']['library'][] = 'webform_examples_accessibility/webform_examples_accessibility';
   }
 }
@@ -47,7 +47,7 @@ function webform_examples_accessibility_webform_submission_form_alter(array &$fo
   $query = \Drupal::request()->query->all();
   unset($query['ajax_form'], $query['_wrapper_format']);
 
-  $accessibility = (\Drupal::request()->query->get('accessibility') == '1') ? TRUE : FALSE;
+  $accessibility = (\Drupal::request()->query->get('accessibility') === '1') ? TRUE : FALSE;
 
   $form['accessibility']['accessibility'] = [
     '#type' => 'link',
@@ -61,10 +61,10 @@ function webform_examples_accessibility_webform_submission_form_alter(array &$fo
 
   $form['accessibility'][] = ['#markup' => ' | '];
 
-  if (\Drupal::request()->query->get('required') == '1') {
+  if (\Drupal::request()->query->get('required') === '1') {
     $required = TRUE;
   }
-  elseif (\Drupal::request()->query->get('required') == '0') {
+  elseif (\Drupal::request()->query->get('required') === '0') {
     $required = FALSE;
   }
   else {
@@ -92,7 +92,7 @@ function webform_examples_accessibility_webform_submission_form_alter(array &$fo
 
   $form['accessibility'][] = ['#markup' => ' | '];
 
-  if (\Drupal::request()->query->get('novalidate') == '1') {
+  if (\Drupal::request()->query->get('novalidate') === '1') {
     $form['#attributes']['novalidate'] = TRUE;
     $novalidate = TRUE;
   }
@@ -114,7 +114,7 @@ function webform_examples_accessibility_webform_submission_form_alter(array &$fo
   if (\Drupal::moduleHandler()->moduleExists('inline_form_errors')) {
     $form['accessibility'][] = ['#markup' => ' | '];
 
-    if (\Drupal::request()->query->get('disable_inline_form_errors') == '1') {
+    if (\Drupal::request()->query->get('disable_inline_form_errors') === '1') {
       $form['#disable_inline_form_errors'] = TRUE;
       $disable_inline_form_errors = TRUE;
     }
diff --git a/web/modules/webform/modules/webform_group/src/WebformGroupManager.php b/web/modules/webform/modules/webform_group/src/WebformGroupManager.php
index 9219519339..dce1b6b355 100644
--- a/web/modules/webform/modules/webform_group/src/WebformGroupManager.php
+++ b/web/modules/webform/modules/webform_group/src/WebformGroupManager.php
@@ -44,7 +44,6 @@ class WebformGroupManager implements WebformGroupManagerInterface {
    */
   protected $requestHandler;
 
-
   /**
    * The webform access rules manager.
    *
diff --git a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_element_group_roles.yml b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_element_group_roles.yml
index 00226cf7e8..2b2e5a4510 100644
--- a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_element_group_roles.yml
+++ b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_element_group_roles.yml
@@ -25,7 +25,7 @@ elements: |
     '#include_internal': false
     '#include_user_roles': true
     '#include_anonymous': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -37,7 +37,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -67,6 +67,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -92,11 +97,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_group_element_access.yml b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_group_element_access.yml
index 201affec04..31e16e9ff9 100644
--- a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_group_element_access.yml
+++ b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/config/install/webform.webform.test_group_element_access.yml
@@ -43,7 +43,7 @@ elements: |
     '#access_create_roles': {  }
     '#access_create_group_roles':
       - custom
-  
+
 css: ''
 javascript: ''
 settings:
@@ -55,7 +55,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -85,6 +85,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -110,11 +115,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/webform_group_test.info.yml b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/webform_group_test.info.yml
index 351b2a4dd9..79ef40a2ef 100644
--- a/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/webform_group_test.info.yml
+++ b/web/modules/webform/modules/webform_group/tests/modules/webform_group_test/webform_group_test.info.yml
@@ -1,13 +1,13 @@
-name: 'Webform Group Test'
+name: 'Webform Group test'
 type: module
 description: 'Support module for webform group integration testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_group'
   - 'group:group_test_config'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupBrowserTestBase.php b/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupBrowserTestBase.php
index b8c7f1dc6c..4da9a1e6f5 100644
--- a/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupBrowserTestBase.php
+++ b/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupBrowserTestBase.php
@@ -26,7 +26,7 @@ abstract class WebformGroupBrowserTestBase extends GroupBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function tearDown() {
+  protected function tearDown() {
     $this->purgeSubmissions();
     parent::tearDown();
   }
diff --git a/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupTokensTest.php b/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupTokensTest.php
index e4057249ef..26c3074ab3 100644
--- a/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupTokensTest.php
+++ b/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupTokensTest.php
@@ -25,8 +25,6 @@ public function testWebformAccessTokens() {
     $group->addContent($node, 'group_node:webform');
 
     // Users.
-    $outsider_user = $this->createUser([], 'outsider', FALSE, ['mail' => 'outsider@example.com']);
-
     $member_user = $this->createUser([], 'member', FALSE, ['mail' => 'member@example.com']);
     $group->addMember($member_user);
 
diff --git a/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupUserInterfaceTest.php b/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupUserInterfaceTest.php
index 03f4c8c813..d7d03dcdb3 100644
--- a/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupUserInterfaceTest.php
+++ b/web/modules/webform/modules/webform_group/tests/src/Functional/WebformGroupUserInterfaceTest.php
@@ -35,7 +35,7 @@ public function testGroupUserInterfaceAccess() {
     $this->assertFieldByName('access[create][group_roles][]');
 
     // Add create access to webform for the member group role.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/access', ['access[create][group_roles][]' => ['member']], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/access', ['access[create][group_roles][]' => ['member']], 'Save');
 
     // Check create access to webform for the member group role.
     \Drupal::entityTypeManager()->getStorage('webform')->resetCache();
@@ -55,7 +55,7 @@ public function testGroupUserInterfaceAccess() {
     $edit = ['properties[access_create_group_roles][]' => 'member'];
 
     // Add create access to name element for the member group role.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/name/edit', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/name/edit', $edit, 'Save');
 
     // Check create access to name element for the member group role.
     \Drupal::entityTypeManager()->getStorage('webform')->resetCache();
diff --git a/web/modules/webform/modules/webform_group/webform_group.info.yml b/web/modules/webform/modules/webform_group/webform_group.info.yml
index 5dbb148401..58b7c78395 100644
--- a/web/modules/webform/modules/webform_group/webform_group.info.yml
+++ b/web/modules/webform/modules/webform_group/webform_group.info.yml
@@ -1,16 +1,16 @@
 name: 'Webform Group [EXPERIMENTAL]'
 type: module
-description: 'Provides a Webform integration with the Group module.'
+description: 'Provides Webform and Group integration.'
 experimental: true
 package: 'Webform [EXPERIMENTAL]'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
   - 'webform:webform_node'
   - 'group:group'
   - 'group:gnode'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_group/webform_group.module b/web/modules/webform/modules/webform_group/webform_group.module
index 1cee450437..36c792dd17 100644
--- a/web/modules/webform/modules/webform_group/webform_group.module
+++ b/web/modules/webform/modules/webform_group/webform_group.module
@@ -41,7 +41,7 @@ function webform_group_config_schema_info_alter(&$definitions) {
 /******************************************************************************/
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for webform handler form.
  *
  * Adds group role token options to email handler elements.
  */
@@ -132,7 +132,7 @@ function _webform_group_form_webform_handler_form_alter_email_element_recursive(
       continue;
     }
     if (isset($element['#type']) && $element['#type'] === 'webform_select_other'
-      && isset($element['#other__type']) && $element['#other__type'] == 'webform_email_multiple') {
+      && isset($element['#other__type']) && $element['#other__type'] === 'webform_email_multiple') {
       $group_optgroup = (string) t('Group roles');
       $other_optgroup = (string) t('Other');
       $other_options = $element['#options'][$other_optgroup];
@@ -145,7 +145,7 @@ function _webform_group_form_webform_handler_form_alter_email_element_recursive(
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for webform settings access form.
  */
 function webform_group_form_webform_settings_access_form_alter(&$form, FormStateInterface $form_state) {
   /** @var \Drupal\webform_group\WebformGroupManagerInterface $webform_group_manager */
@@ -199,7 +199,7 @@ function webform_group_form_webform_settings_access_form_alter(&$form, FormState
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for webform ui element form.
  */
 function webform_group_form_webform_ui_element_form_alter(&$form, FormStateInterface $form_state) {
   $default_properties = $form_state->get('default_properties');
@@ -248,7 +248,7 @@ function webform_group_form_webform_ui_element_form_alter(&$form, FormStateInter
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for webform admin config handlers form.
  */
 function webform_group_form_webform_admin_config_handlers_form_alter(&$form, FormStateInterface $form_state) {
   $form['mail']['roles']['#weight'] = 0;
@@ -292,7 +292,7 @@ function _webform_group_form_webform_admin_config_handlers_form_submit(&$form, F
 /******************************************************************************/
 
 /**
- * Implements hook_ENTITY_TYPE_access().
+ * Implements hook_ENTITY_TYPE_access() for webform entities.
  */
 function webform_group_webform_access(WebformInterface $webform, $operation, AccountInterface $account) {
   // Prevent recursion when a webform is being passed as the source entity
@@ -329,7 +329,7 @@ function webform_group_webform_access(WebformInterface $webform, $operation, Acc
 }
 
 /**
- * Implements hook_ENTITY_TYPE_access().
+ * Implements hook_ENTITY_TYPE_access() for webform_submission entities.
  */
 function webform_group_webform_submission_access(WebformSubmissionInterface $webform_submission, $operation, AccountInterface $account) {
   if (!in_array($operation, ['view', 'update', 'delete'])) {
@@ -363,7 +363,7 @@ function webform_group_webform_submission_access(WebformSubmissionInterface $web
     // Is operation any.
     (array_intersect($access_rules[$operation . '_any']['group_roles'], $user_group_roles)) ||
     // Is operation own.
-    (array_intersect($access_rules[$operation . '_own']['group_roles'], $user_group_roles)  && $webform_submission->getOwnerId() == $account->id())
+    (array_intersect($access_rules[$operation . '_own']['group_roles'], $user_group_roles)  && (int) $webform_submission->getOwnerId() === (int) $account->id())
   ) {
     return AccessResult::allowed()
       ->cachePerUser()
diff --git a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck.yml b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck.yml
index 4444ca2bbd..0d0c1af0ac 100644
--- a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck.yml
+++ b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck.yml
@@ -97,7 +97,7 @@ elements: |
         enabled:
           ':input[name="checkboxes_trigger"]':
             filled: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -109,7 +109,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -139,6 +139,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -164,11 +169,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck_styles.yml b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck_styles.yml
index 244042ec21..c3fa046020 100644
--- a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck_styles.yml
+++ b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/config/install/webform.webform.test_element_icheck_styles.yml
@@ -831,7 +831,7 @@ elements: |
         three: Three
       '#default_value': one
       '#icheck': square-aero
-  
+
 css: ''
 javascript: ''
 settings:
@@ -843,7 +843,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -873,6 +873,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -898,11 +903,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/webform_icheck_test.info.yml b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/webform_icheck_test.info.yml
index 9ef83197e5..566a524e82 100644
--- a/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/webform_icheck_test.info.yml
+++ b/web/modules/webform/modules/webform_icheck/tests/modules/webform_icheck_test/webform_icheck_test.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform iCheck Test'
+name: 'Webform iCheck test'
 type: module
-description: 'Support module for webform that provides iCheck element working examples.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform iCheck element testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_icheck'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_icheck/tests/src/Functional/WebformIcheckElementTest.php b/web/modules/webform/modules/webform_icheck/tests/src/Functional/WebformIcheckElementTest.php
index 91d82f7736..cb95f50c46 100644
--- a/web/modules/webform/modules/webform_icheck/tests/src/Functional/WebformIcheckElementTest.php
+++ b/web/modules/webform/modules/webform_icheck/tests/src/Functional/WebformIcheckElementTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for iCheck element.
  *
- * @group Webform
+ * @group webform_icheck
  */
 class WebformIcheckElementTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_icheck/webform_icheck.info.yml b/web/modules/webform/modules/webform_icheck/webform_icheck.info.yml
index b2aa7ea4a7..6c4bea67fc 100644
--- a/web/modules/webform/modules/webform_icheck/webform_icheck.info.yml
+++ b/web/modules/webform/modules/webform_icheck/webform_icheck.info.yml
@@ -2,11 +2,11 @@ name: 'Webform iCheck'
 type: module
 description: 'Provides support for highly customizable checkboxes and radio buttons.'
 package: 'Webform [DEPRECATED]'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_icheck/webform_icheck.module b/web/modules/webform/modules/webform_icheck/webform_icheck.module
index c0fd4b4211..ee626e78de 100644
--- a/web/modules/webform/modules/webform_icheck/webform_icheck.module
+++ b/web/modules/webform/modules/webform_icheck/webform_icheck.module
@@ -82,7 +82,7 @@ function webform_icheck_webform_element_alter(array &$element, FormStateInterfac
   $icheck = NULL;
   $icheck_skin = NULL;
   if (isset($element['#icheck'])) {
-    if ($element['#icheck'] != 'none') {
+    if ($element['#icheck'] !== 'none') {
       $icheck = $element['#icheck'];
       $icheck_skin = strtok($element['#icheck'], '-');
     }
diff --git a/web/modules/webform/modules/webform_image_select/src/Element/WebformImageSelectElementImages.php b/web/modules/webform/modules/webform_image_select/src/Element/WebformImageSelectElementImages.php
index 7d98d3d6a8..2373c4afc1 100644
--- a/web/modules/webform/modules/webform_image_select/src/Element/WebformImageSelectElementImages.php
+++ b/web/modules/webform/modules/webform_image_select/src/Element/WebformImageSelectElementImages.php
@@ -85,7 +85,7 @@ public static function processWebformImageSelectElementImages(&$element, FormSta
       '#type' => 'select',
       '#description' => t('Please select <a href=":href">predefined images</a> or enter custom image.', $t_args),
       '#options' => [
-        self::CUSTOM_OPTION => t('Custom images…'),
+        static::CUSTOM_OPTION => t('Custom images…'),
       ] + $webform_images,
       '#attributes' => [
         'class' => [$class_name],
@@ -126,7 +126,7 @@ public static function validateWebformImageSelectElementImages(&$element, FormSt
     $custom_value = NestedArray::getValue($form_state->getValues(), $element['custom']['#parents']);
 
     $value = $options_value;
-    if ($options_value == self::CUSTOM_OPTION) {
+    if ($options_value === static::CUSTOM_OPTION) {
       $value = $custom_value;
     }
 
diff --git a/web/modules/webform/modules/webform_image_select/src/Entity/WebformImageSelectImages.php b/web/modules/webform/modules/webform_image_select/src/Entity/WebformImageSelectImages.php
index de070e2f56..34ed82123f 100644
--- a/web/modules/webform/modules/webform_image_select/src/Entity/WebformImageSelectImages.php
+++ b/web/modules/webform/modules/webform_image_select/src/Entity/WebformImageSelectImages.php
@@ -3,10 +3,10 @@
 namespace Drupal\webform_image_select\Entity;
 
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
-use Drupal\Core\Serialization\Yaml;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\webform\Utility\WebformYaml;
 use Drupal\webform_image_select\WebformImageSelectImagesInterface;
 
 /**
@@ -108,7 +108,7 @@ class WebformImageSelectImages extends ConfigEntityBase implements WebformImageS
   public function getImages() {
     if (!isset($this->imagesDecoded)) {
       try {
-        $options = Yaml::decode($this->images);
+        $options = WebformYaml::decode($this->images);
         // Since YAML supports simple values.
         $options = (is_array($options)) ? $options : [];
       }
@@ -126,7 +126,7 @@ public function getImages() {
    * {@inheritdoc}
    */
   public function setImages(array $images) {
-    $this->images = Yaml::encode($images);
+    $this->images = WebformYaml::encode($images);
     $this->imagesDecoded = NULL;
   }
 
diff --git a/web/modules/webform/modules/webform_image_select/src/Plugin/WebformElement/WebformImageSelect.php b/web/modules/webform/modules/webform_image_select/src/Plugin/WebformElement/WebformImageSelect.php
index 2ecb377309..14eeb0e618 100644
--- a/web/modules/webform/modules/webform_image_select/src/Plugin/WebformElement/WebformImageSelect.php
+++ b/web/modules/webform/modules/webform_image_select/src/Plugin/WebformElement/WebformImageSelect.php
@@ -154,7 +154,7 @@ protected function formatHtmlItem(array $element, WebformSubmissionInterface $we
    * {@inheritdoc}
    */
   protected function formatTextItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    if ($this->getItemFormat($element) == 'image') {
+    if ($this->getItemFormat($element) === 'image') {
       $element['#format'] = 'value';
     }
     return parent::formatTextItem($element, $webform_submission, $options);
diff --git a/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesForm.php b/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesForm.php
index 61f56f214f..2b3d739658 100644
--- a/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesForm.php
+++ b/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesForm.php
@@ -36,7 +36,7 @@ public static function create(ContainerInterface $container) {
    * {@inheritdoc}
    */
   protected function prepareEntity() {
-    if ($this->operation == 'duplicate') {
+    if ($this->operation === 'duplicate') {
       $this->setEntity($this->getEntity()->createDuplicate());
     }
 
diff --git a/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesListBuilder.php b/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesListBuilder.php
index a43dc187f6..d84422fc85 100644
--- a/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesListBuilder.php
+++ b/web/modules/webform/modules/webform_image_select/src/WebformImageSelectImagesListBuilder.php
@@ -188,7 +188,7 @@ protected function buildImages(WebformImageSelectImagesInterface $entity) {
 
     $build = [];
     foreach ($images as $key => $image) {
-      $title = $image['text'] . ($key != $image ? ' (' . $key . ')' : '');
+      $title = $image['text'] . ($key !== $image ? ' (' . $key . ')' : '');
       $build[] = [
         '#type' => 'html_tag',
         '#tag' => 'img',
diff --git a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_image_select.yml b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_image_select.yml
index e5fe8c1810..7c337f110b 100644
--- a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_image_select.yml
+++ b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_image_select.yml
@@ -163,7 +163,7 @@ elements: |
     '#filter__singular': 'animal'
     '#filter__plural': 'animals'
     '#filter__no_results': 'No animals found.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -175,7 +175,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -205,6 +205,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -230,11 +235,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_images.yml b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_images.yml
index 9b24b179dc..fca607cd61 100644
--- a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_images.yml
+++ b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/config/install/webform.webform.test_element_images.yml
@@ -64,7 +64,7 @@ elements: |
         kitten_4:
           text: 'Cute Kitten 4'
           src: 'http://placekitten.com/270/200'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -76,7 +76,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -106,6 +106,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -131,11 +136,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/webform_image_select_test.info.yml b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/webform_image_select_test.info.yml
index aa9fbff5a1..6ac50dc105 100644
--- a/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/webform_image_select_test.info.yml
+++ b/web/modules/webform/modules/webform_image_select/tests/modules/webform_image_select_test/webform_image_select_test.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform Image Select Test'
+name: 'Webform Image Select test'
 type: module
-description: 'Support module for webform that provides image select element working examples.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform image select element testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_image_select'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementImagesTest.php b/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementImagesTest.php
index c6e396970a..a0950b72af 100644
--- a/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementImagesTest.php
+++ b/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementImagesTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform image select images element.
  *
- * @group Webform
+ * @group webform_image_select
  */
 class WebformImageSelectElementImagesTest extends WebformElementBrowserTestBase {
 
@@ -23,7 +23,7 @@ class WebformImageSelectElementImagesTest extends WebformElementBrowserTestBase
    */
   public function testElementOptions() {
     // Check default value handling.
-    $this->drupalPostForm('/webform/test_element_images', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_images', [], 'Submit');
     $this->assertRaw("webform_image_select_images: {  }
 webform_image_select_images_default_value:
   kitten_1:
@@ -58,7 +58,7 @@ public function testElementOptions() {
       'webform_image_select_images[images][items][0][src]' => 'src01',
       'webform_image_select_images[images][items][1][src]' => 'src02',
     ];
-    $this->drupalPostForm('/webform/test_element_images', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_images', $edit, 'Submit');
     $this->assertRaw("The <em class=\"placeholder\">Image value</em> '' is already in use. It must be unique.");
   }
 
diff --git a/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementTest.php b/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementTest.php
index d6346be14d..00970e1fec 100644
--- a/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementTest.php
+++ b/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectElementTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform image select element.
  *
- * @group Webform
+ * @group webform_image_select
  */
 class WebformImageSelectElementTest extends WebformElementBrowserTestBase {
 
@@ -45,7 +45,7 @@ public function testImageSelect() {
     $edit = [
       'image_select_default' => 'kitten_1',
     ];
-    $this->postSubmission($webform, $edit, t('Preview'));
+    $this->postSubmission($webform, $edit, 'Preview');
     $this->assertRaw('<figure style="display: inline-block; margin: 0 6px 6px 0; padding: 6px; border: 1px solid #ddd;width: 220px"><img src="http://placekitten.com/220/200" width="220" height="200" alt="Cute Kitten 1" title="Cute Kitten 1" />');
 
   }
diff --git a/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectImagesTest.php b/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectImagesTest.php
index eaf497862c..67e743d2d5 100644
--- a/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectImagesTest.php
+++ b/web/modules/webform/modules/webform_image_select/tests/src/Functional/WebformImageSelectImagesTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform image select image entity.
  *
- * @group Webform
+ * @group webform_image_select
  */
 class WebformImageSelectImagesTest extends WebformElementBrowserTestBase {
 
@@ -89,7 +89,7 @@ public function testWebformImageSelectImages() {
     $webform_images->set('images', "not\nvalid\nyaml")->save();
 
     // Check invalid images.
-    $this->assertFalse($webform_images->getImages());
+    $this->assertEqual([], $webform_images->getImages());
 
     // Check admin user access denied.
     $this->drupalGet('/admin/structure/webform/config/images/manage');
@@ -108,7 +108,7 @@ public function testWebformImageSelectImages() {
 
     // Check image altered message.
     $this->drupalGet('/admin/structure/webform/config/images/manage/animals/edit');
-    $this->assertRaw('The <em class="placeholder">Cute Animals</em> images are being altered by the <em class="placeholder">Webform Image Select Test</em> module.');
+    $this->assertRaw('The <em class="placeholder">Cute Animals</em> images are being altered by the <em class="placeholder">Webform Image Select test</em> module.');
 
     // Check hook_webform_image_select_images_alter().
     // Check hook_webform_image_select_images_WEBFORM_IMAGE_SELECT_IMAGES_ID_alter().
diff --git a/web/modules/webform/modules/webform_image_select/webform_image_select.info.yml b/web/modules/webform/modules/webform_image_select/webform_image_select.info.yml
index 517a74be7e..ebe60bc11b 100644
--- a/web/modules/webform/modules/webform_image_select/webform_image_select.info.yml
+++ b/web/modules/webform/modules/webform_image_select/webform_image_select.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Image Select'
 type: module
 description: 'Provides a webform element for a selecting an image.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_image_select/webform_image_select.libraries.yml b/web/modules/webform/modules/webform_image_select/webform_image_select.libraries.yml
index f890a514e7..a872d1c7af 100644
--- a/web/modules/webform/modules/webform_image_select/webform_image_select.libraries.yml
+++ b/web/modules/webform/modules/webform_image_select/webform_image_select.libraries.yml
@@ -15,13 +15,13 @@ webform_image_select.element:
 
 libraries.jquery.image-picker:
   remote: https://rvera.github.io/image-picker/
-  version: '0.3.0'
+  version: '0.3.1'
   license:
     name: MIT
     url: https://github.com/rvera/image-picker/blob/master/LICENSE
     gpl-compatible: true
   cdn:
-    /libraries/jquery.image-picker/image-picker/: https://cdnjs.cloudflare.com/ajax/libs/image-picker/0.3.0/
+    /libraries/jquery.image-picker/image-picker/: https://cdnjs.cloudflare.com/ajax/libs/image-picker/0.3.1/
   css:
     component:
       /libraries/jquery.image-picker/image-picker/image-picker.css: {}
diff --git a/web/modules/webform/modules/webform_image_select/webform_image_select.module b/web/modules/webform/modules/webform_image_select/webform_image_select.module
index c38f50480a..966c262e6c 100644
--- a/web/modules/webform/modules/webform_image_select/webform_image_select.module
+++ b/web/modules/webform/modules/webform_image_select/webform_image_select.module
@@ -37,8 +37,8 @@ function webform_image_select_webform_libraries_info() {
     'description' => t('A simple jQuery plugin that transforms a select element into a more user friendly graphical interface.'),
     'notes' => t('Image Picker is used by the Image select element.'),
     'homepage_url' => Url::fromUri('https://rvera.github.io/image-picker/'),
-    'download_url' => Url::fromUri('https://github.com/rvera/image-picker/archive/0.3.0.zip'),
-    'version' => '0.3.0',
+    'download_url' => Url::fromUri('https://github.com/rvera/image-picker/archive/0.3.1.zip'),
+    'version' => '0.3.1',
     'elements' => ['webform_image_select'],
     'optional' => FALSE,
   ];
@@ -60,7 +60,7 @@ function webform_image_select_menu_local_tasks_alter(&$data, $route_name) {
 /******************************************************************************/
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for config translate add form.
  */
 function webform_image_select_form_config_translation_add_form_alter(&$form, FormStateInterface $form_state, $is_new = TRUE) {
   // Manually apply YAML editor to text field that store YAML data.
diff --git a/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/config/install/webform.webform.test_element_buttons.yml b/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/config/install/webform.webform.test_element_buttons.yml
index 1a1154cf77..5600870963 100644
--- a/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/config/install/webform.webform.test_element_buttons.yml
+++ b/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/config/install/webform.webform.test_element_buttons.yml
@@ -47,7 +47,7 @@ elements: |
     '#other__option_label': Other
     '#other__placeholder': 'What is this other option'
     '#other__description': 'Other button description'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -59,7 +59,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -89,6 +89,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -114,11 +119,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/webform_jqueryui_buttons_test.info.yml b/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/webform_jqueryui_buttons_test.info.yml
index af7a396cbf..20871efcea 100644
--- a/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/webform_jqueryui_buttons_test.info.yml
+++ b/web/modules/webform/modules/webform_jqueryui_buttons/tests/modules/webform_jqueryui_buttons_test/webform_jqueryui_buttons_test.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform jQueryUI Buttons Test'
+name: 'Webform jQueryUI Buttons test'
 type: module
-description: 'Support module for webform that provides buttons element working examples.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for jQuery UI buttons element testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_jqueryui_buttons'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_jqueryui_buttons/tests/src/Functional/WebformElementButtonsTest.php b/web/modules/webform/modules/webform_jqueryui_buttons/tests/src/Functional/WebformElementButtonsTest.php
index 97a97d1c71..cde6d8d3fc 100644
--- a/web/modules/webform/modules/webform_jqueryui_buttons/tests/src/Functional/WebformElementButtonsTest.php
+++ b/web/modules/webform/modules/webform_jqueryui_buttons/tests/src/Functional/WebformElementButtonsTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform element buttons.
  *
- * @group Webform
+ * @group webform_jqueryui_buttons
  */
 class WebformElementButtonsTest extends WebformElementBrowserTestBase {
 
@@ -41,7 +41,7 @@ public function testBuildingOtherElements() {
       'buttons_other_basic[buttons]' => '_other_',
       'buttons_other_basic[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_buttons', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_buttons', $edit, 'Submit');
     $this->assertRaw('buttons_other_basic field is required.');
 
     // Check buttons other not required when not checked.
@@ -49,7 +49,7 @@ public function testBuildingOtherElements() {
       'buttons_other_basic[buttons]' => 'One',
       'buttons_other_basic[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_buttons', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_buttons', $edit, 'Submit');
     $this->assertNoRaw('buttons_other_basic field is required.');
 
     // Check buttons other required validation.
@@ -57,7 +57,7 @@ public function testBuildingOtherElements() {
       'buttons_other_advanced[buttons]' => '_other_',
       'buttons_other_advanced[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_buttons', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_buttons', $edit, 'Submit');
     $this->assertRaw('buttons_other_advanced field is required.');
 
     // Check buttons other processing w/ other.
@@ -65,7 +65,7 @@ public function testBuildingOtherElements() {
       'buttons_other_advanced[buttons]' => '_other_',
       'buttons_other_advanced[other]' => 'Five',
     ];
-    $this->drupalPostForm('/webform/test_element_buttons', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_buttons', $edit, 'Submit');
     $this->assertRaw('buttons_other_advanced: Five');
 
     // Check buttons other processing w/o other.
@@ -74,7 +74,7 @@ public function testBuildingOtherElements() {
       // This value is ignored, because 'buttons_other_advanced[buttons]' is not set to '_other_'.
       'buttons_other_advanced[other]' => 'Five',
     ];
-    $this->drupalPostForm('/webform/test_element_buttons', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_buttons', $edit, 'Submit');
     $this->assertRaw('buttons_other_advanced: One');
     $this->assertNoRaw('buttons_other_advanced: Five');
   }
diff --git a/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.info.yml b/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.info.yml
index d17982f271..15017bc972 100644
--- a/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.info.yml
+++ b/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.info.yml
@@ -2,11 +2,11 @@ name: 'Webform jQueryUI Buttons'
 type: module
 description: 'Provides a group of multiple buttons used for selecting a value. jQueryUI is no longer maintained.'
 package: 'Webform [DEPRECATED]'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.libraries.yml b/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.libraries.yml
index d80c95da42..7bcf8c9f19 100644
--- a/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.libraries.yml
+++ b/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.libraries.yml
@@ -4,3 +4,4 @@ webform_jqueryui_buttons.element:
     js/webform_jqueryui_buttons.element.js: {}
   dependencies:
     - core/jquery.ui.checkboxradio
+  deprecated: The "%library_id%" asset library is deprecated. jQueryUI is no longer maintained. See https://www.drupal.org/node/3064015
diff --git a/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.module b/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.module
index fd08c0a2bb..a167a18675 100644
--- a/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.module
+++ b/web/modules/webform/modules/webform_jqueryui_buttons/webform_jqueryui_buttons.module
@@ -3,24 +3,6 @@
 /**
  * @file
  * Provides a group of multiple buttons used for selecting a value.
- */
-
-/**
- * Implements hook_library_info_alter().
  *
- * @todo Remove once Drupal 8.8.x is only supported.
+ * @todd This file will be deleted in Webform 6.x.
  */
-function webform_jqueryui_buttons_library_info_alter(&$libraries, $extension) {
-  // Issue #2906737: With the new jquery 3 checkboxradio and selectmenu error.
-  // @see https://www.drupal.org/node/2906737
-  if (floatval(\Drupal::VERSION) <= 8.7
-    && $extension == 'webform_jqueryui_buttons'
-    && isset($libraries['webform_jqueryui_buttons.element'])) {
-    $libraries['webform_jqueryui_buttons.element']['js'] = [
-      '/core/assets/vendor/jquery.ui/ui/form-reset-mixin-min.js' => ['minified' => TRUE],
-      '/core/assets/vendor/jquery.ui/ui/escape-selector-min.js' => ['minified' => TRUE],
-      '/core/assets/vendor/jquery.ui/ui/widgets/checkboxradio-min.js' => ['minified' => TRUE],
-      'js/webform_jqueryui_buttons.element.js' => [],
-    ];
-  }
-}
diff --git a/web/modules/webform/modules/webform_location_geocomplete/src/Plugin/WebformElement/WebformLocationGeocomplete.php b/web/modules/webform/modules/webform_location_geocomplete/src/Plugin/WebformElement/WebformLocationGeocomplete.php
index 54869ea380..b6ec423d6d 100644
--- a/web/modules/webform/modules/webform_location_geocomplete/src/Plugin/WebformElement/WebformLocationGeocomplete.php
+++ b/web/modules/webform/modules/webform_location_geocomplete/src/Plugin/WebformElement/WebformLocationGeocomplete.php
@@ -59,7 +59,7 @@ protected function formatHtmlItem(array $element, WebformSubmissionInterface $we
     }
 
     $format = $this->getItemFormat($element);
-    if ($format == 'map') {
+    if ($format === 'map') {
       $google_map_url = UrlGenerator::fromUri('http://maps.google.com/', ['query' => ['q' => $value['value']]]);
 
       $location = $value['location'];
diff --git a/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/config/install/webform.webform.test_element_loc_geocomplete.yml b/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/config/install/webform.webform.test_element_loc_geocomplete.yml
index c449b00a93..601251e32e 100644
--- a/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/config/install/webform.webform.test_element_loc_geocomplete.yml
+++ b/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/config/install/webform.webform.test_element_loc_geocomplete.yml
@@ -94,7 +94,7 @@ elements: |
     '#title': 'Location with geolocation and hidden'
     '#geolocation': true
     '#hidden': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -106,7 +106,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -136,6 +136,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -161,11 +166,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/webform_location_geocomplete_test.info.yml b/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/webform_location_geocomplete_test.info.yml
index 91a1aea7a3..80ae7bfa34 100644
--- a/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/webform_location_geocomplete_test.info.yml
+++ b/web/modules/webform/modules/webform_location_geocomplete/tests/modules/webform_location_geocomplete_test/webform_location_geocomplete_test.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform Location Geocomplete Test'
+name: 'Webform Location Geocomplete test'
 type: module
-description: 'Support module for webform that provides location geocomplete element working examples.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for location geocomplete element testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_location_geocomplete'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_location_geocomplete/tests/src/Functional/WebformLocationGeocompleteTest.php b/web/modules/webform/modules/webform_location_geocomplete/tests/src/Functional/WebformLocationGeocompleteTest.php
index 7be6b70c50..6636cf05f9 100644
--- a/web/modules/webform/modules/webform_location_geocomplete/tests/src/Functional/WebformLocationGeocompleteTest.php
+++ b/web/modules/webform/modules/webform_location_geocomplete/tests/src/Functional/WebformLocationGeocompleteTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for location geocomplete element.
  *
- * @group Webform
+ * @group webform_location_geocompleter
  */
 class WebformLocationGeocompleteTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.info.yml b/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.info.yml
index 667c883308..58e4330a79 100644
--- a/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.info.yml
+++ b/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Location Geocomplete'
 type: module
 description: 'Provides a form element to collect valid location information (address, longitude, latitude, geolocation) using Google Maps API''s Geocoding and Places Autocomplete. The jQuery: Geocoding and Places Autocomplete Plugin library is not being maintained.'
 package: 'Webform [DEPRECATED]'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.libraries.yml b/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.libraries.yml
index 576eacd4ef..e98fdf2168 100644
--- a/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.libraries.yml
+++ b/web/modules/webform/modules/webform_location_geocomplete/webform_location_geocomplete.libraries.yml
@@ -26,3 +26,4 @@ libraries.jquery.geocomplete:
     /libraries/geocomplete/jquery.geocomplete.min.js: { minified: true }
   dependencies:
     - core/jquery
+  deprecated: The "%library_id%" asset library is deprecated. This project is not maintained anymore. See https://github.com/ubilabs/geocomplete
diff --git a/web/modules/webform/modules/webform_node/src/Access/WebformNodeAccess.php b/web/modules/webform/modules/webform_node/src/Access/WebformNodeAccess.php
index c4cede6a6e..1ff83655ee 100644
--- a/web/modules/webform/modules/webform_node/src/Access/WebformNodeAccess.php
+++ b/web/modules/webform/modules/webform_node/src/Access/WebformNodeAccess.php
@@ -177,7 +177,7 @@ public static function checkWebformSubmissionAccess($operation, $entity_access,
    * @return \Drupal\Core\Access\AccessResultInterface
    *   The access result.
    */
-  protected static function checkAccess($operation, $entity_access, NodeInterface $node, WebformSubmissionInterface $webform_submission = NULL, AccountInterface $account = NULL) {
+  public static function checkAccess($operation, $entity_access, NodeInterface $node, WebformSubmissionInterface $webform_submission = NULL, AccountInterface $account = NULL) {
     /** @var \Drupal\webform\WebformEntityReferenceManagerInterface $entity_reference_manager */
     $entity_reference_manager = \Drupal::service('webform.entity_reference_manager');
 
diff --git a/web/modules/webform/modules/webform_node/src/Controller/WebformNodeReferencesListController.php b/web/modules/webform/modules/webform_node/src/Controller/WebformNodeReferencesListController.php
index f65f5e125b..36c6f0bf12 100644
--- a/web/modules/webform/modules/webform_node/src/Controller/WebformNodeReferencesListController.php
+++ b/web/modules/webform/modules/webform_node/src/Controller/WebformNodeReferencesListController.php
@@ -35,21 +35,21 @@ class WebformNodeReferencesListController extends EntityListBuilder implements C
   protected $dateFormatter;
 
   /**
-   * Webform submission storage.
+   * The webform submission storage.
    *
    * @var \Drupal\webform\WebformSubmissionStorageInterface
    */
   protected $submissionStorage;
 
   /**
-   * Node type storage.
+   * The node type storage.
    *
    * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
    */
   protected $nodeTypeStorage;
 
   /**
-   * Field config storage.
+   * The field config storage.
    *
    * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
    */
@@ -296,16 +296,16 @@ protected function getWebformStatus(EntityInterface $entity) {
       return NULL;
     }
 
-    if ($entity->$webform_field_name->target_id != $this->webform->id()) {
+    if ($entity->$webform_field_name->target_id !== $this->webform->id()) {
       return NULL;
     }
 
     $webform_field = $entity->$webform_field_name;
-    if ($webform_field->status == WebformInterface::STATUS_OPEN) {
+    if ($webform_field->status === WebformInterface::STATUS_OPEN) {
       return $this->t('Open');
     }
 
-    if ($webform_field->status == WebformInterface::STATUS_SCHEDULED) {
+    if ($webform_field->status === WebformInterface::STATUS_SCHEDULED) {
       $is_opened = TRUE;
       if ($webform_field->open && strtotime($webform_field->open) > time()) {
         $is_opened = FALSE;
@@ -361,6 +361,14 @@ public function getDefaultOperations(EntityInterface $entity) {
         'url' => Url::fromRoute('entity.node.webform.results_submissions', $route_parameters),
       ];
     }
+    if ($entity->access('update')
+      && $this->webform->getSetting('share_node', TRUE)
+      && $this->moduleHandler()->moduleExists('webform_share')) {
+      $operations['share'] = [
+        'title' => $this->t('Share'),
+        'url' => Url::fromRoute('entity.node.webform.share_embed', $route_parameters),
+      ];
+    }
     if ($entity->access('delete')) {
       $operations['delete'] = [
         'title' => $this->t('Delete'),
diff --git a/web/modules/webform/modules/webform_node/src/WebformNodeUninstallValidator.php b/web/modules/webform/modules/webform_node/src/WebformNodeUninstallValidator.php
index 8cfd2c4c6c..856f37d34d 100644
--- a/web/modules/webform/modules/webform_node/src/WebformNodeUninstallValidator.php
+++ b/web/modules/webform/modules/webform_node/src/WebformNodeUninstallValidator.php
@@ -39,7 +39,7 @@ public function __construct(EntityTypeManagerInterface $entity_type_manager, Tra
    */
   public function validate($module) {
     $reasons = [];
-    if ($module == 'webform_node') {
+    if ($module === 'webform_node') {
       // The webform node type is provided by the Webform node module. Prevent
       // uninstall if there are any nodes of that type.
       if ($this->hasWebformNodes()) {
diff --git a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_a.yml b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_a.yml
index 8b4508d08b..e506049254 100644
--- a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_a.yml
+++ b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_a.yml
@@ -18,7 +18,7 @@ elements: |
   textfield_a:
     '#title': textfield_a
     '#type': textfield
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_b.yml b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_b.yml
index 0c47366160..24c6a8cc7a 100644
--- a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_b.yml
+++ b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/config/install/webform.webform.webform_node_test_multiple_b.yml
@@ -18,7 +18,7 @@ elements: |
   textfield_b:
     '#title': textfield_b
     '#type': textfield
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/webform_node_test_multiple.info.yml b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/webform_node_test_multiple.info.yml
index 1b5d7bfd5e..f3e733f401 100644
--- a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/webform_node_test_multiple.info.yml
+++ b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_multiple/webform_node_test_multiple.info.yml
@@ -1,8 +1,8 @@
-name: 'Webform node module multiple tests'
+name: 'Webform Node Multiple test'
 type: module
-description: 'Support module for webform node that provides working examples multiple webforms attached to a single node.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform nodes with multiple webforms testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:field'
   - 'drupal:menu_ui'
@@ -13,7 +13,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_node'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/config/install/webform.webform.webform_node_test_translation.yml b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/config/install/webform.webform.webform_node_test_translation.yml
index 4354fd16ac..9c40d2acc4 100644
--- a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/config/install/webform.webform.webform_node_test_translation.yml
+++ b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/config/install/webform.webform.webform_node_test_translation.yml
@@ -7,7 +7,7 @@ dependencies:
 open: null
 close: null
 weight: 0
-uid: 1
+uid: 0
 template: false
 archive: false
 id: webform_node_test_translation
@@ -19,7 +19,7 @@ elements: |
     '#type': webform_computed_token
     '#title': computed_token
     '#value': '[webform_submission:node:title]'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -31,7 +31,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -61,6 +61,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -86,11 +91,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/webform_node_test_translation.info.yml b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/webform_node_test_translation.info.yml
index 534e438580..a248b67830 100644
--- a/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/webform_node_test_translation.info.yml
+++ b/web/modules/webform/modules/webform_node/tests/modules/webform_node_test_translation/webform_node_test_translation.info.yml
@@ -1,15 +1,15 @@
-name: 'Webform node module translation test'
+name: 'Webform Node Translation test'
 type: module
-description: 'Support module for webform node that enabled translations for webform content type.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform node translation testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
   - 'webform:webform_node'
   - 'webform:webform_test_translation'
   - 'drupal:content_translation'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_node/tests/src/Functional/Access/WebformNodeAccessPermissionsTest.php b/web/modules/webform/modules/webform_node/tests/src/Functional/Access/WebformNodeAccessPermissionsTest.php
index b64d65c70e..a32351b32a 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Functional/Access/WebformNodeAccessPermissionsTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Functional/Access/WebformNodeAccessPermissionsTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform node access permissions.
  *
- * @group WebformNode
+ * @group webform_node
  */
 class WebformNodeAccessPermissionsTest extends WebformNodeBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_node/tests/src/Functional/Access/WebformNodeAccessRulesTest.php b/web/modules/webform/modules/webform_node/tests/src/Functional/Access/WebformNodeAccessRulesTest.php
index fae3eabec9..2cc2c96f7b 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Functional/Access/WebformNodeAccessRulesTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Functional/Access/WebformNodeAccessRulesTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform node access rules.
  *
- * @group WebformNode
+ * @group webform_node
  */
 class WebformNodeAccessRulesTest extends WebformNodeBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeBrowserTestBaseTest.php b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeBrowserTestBaseTest.php
index 23f24a5c51..e3a63dc403 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeBrowserTestBaseTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeBrowserTestBaseTest.php
@@ -5,7 +5,7 @@
 /**
  * Test the webform node test base class.
  *
- * @group webform_browser
+ * @group webform_node
  */
 class WebformNodeBrowserTestBaseTest extends WebformNodeBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeEntityReferenceTest.php b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeEntityReferenceTest.php
index 4056b6dd79..50c8956db5 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeEntityReferenceTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeEntityReferenceTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform node entity references.
  *
- * @group WebformNode
+ * @group webform_node
  */
 class WebformNodeEntityReferenceTest extends WebformNodeBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeReferencesTest.php b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeReferencesTest.php
index e6cf35dc7e..ffe1edc264 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeReferencesTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeReferencesTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform node references.
  *
- * @group WebformNode
+ * @group webform_node
  */
 class WebformNodeReferencesTest extends WebformNodeBrowserTestBase {
 
@@ -75,7 +75,7 @@ public function testReferences() {
       'webform_default_data[letter]' => 'a',
       'webform_default_data[number]' => '1',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_variant_multiple/references/add', $edit, t('Create content'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_variant_multiple/references/add', $edit, 'Create content');
     $this->assertFieldByName('title[0][value]', 'Testing 123');
     $this->assertOptionSelected('edit-webform-0-target-id', 'test_variant_multiple');
     $this->assertRaw('>letter: a
diff --git a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeResultsTest.php b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeResultsTest.php
index 7d36495c97..4bacfc3b0b 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeResultsTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeResultsTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform node results.
  *
- * @group WebformNode
+ * @group webform_node
  */
 class WebformNodeResultsTest extends WebformNodeBrowserTestBase {
 
@@ -24,7 +24,7 @@ class WebformNodeResultsTest extends WebformNodeBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Place blocks.
@@ -136,7 +136,7 @@ public function testResults() {
       'subject' => "Node draft subject",
       'message' => "Node draft message",
     ];
-    $this->drupalPostForm('/node/' . $node->id(), $edit, t('Save Draft'));
+    $this->drupalPostForm('/node/' . $node->id(), $edit, 'Save Draft');
     $this->drupalGet('/node/' . $node->id());
     $this->assertRaw('A partially-completed form was found. Please complete the remaining portions.');
     $this->drupalGet('/webform/contact');
@@ -168,7 +168,7 @@ public function testResults() {
       'limit' => 20,
       'default' => TRUE,
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/submissions/custom', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/submissions/custom', $edit, 'Save');
     $this->assertRaw('The customized table has been saved.');
 
     // Check that the webform node's results table is now customized.
@@ -216,7 +216,7 @@ public function testResults() {
     }
 
     // Check deleting webform node results.
-    $this->drupalPostForm('/node/' . $node->id() . '/webform/results/clear', ['confirm' => TRUE], t('Clear'));
+    $this->drupalPostForm('/node/' . $node->id() . '/webform/results/clear', ['confirm' => TRUE], 'Clear');
     $this->assertEqual($submission_storage->getTotal($webform, $node), 0);
     $this->assertEqual($submission_storage->getTotal($webform), 3);
   }
diff --git a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTest.php b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTest.php
index b49645b2f0..ff87dbd261 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform node.
  *
- * @group WebformNode
+ * @group webform_node
  */
 class WebformNodeTest extends WebformNodeBrowserTestBase {
 
@@ -31,7 +31,7 @@ class WebformNodeTest extends WebformNodeBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Place webform test blocks.
@@ -293,7 +293,7 @@ public function testNode() {
       'subject' => 'subject',
       'message' => 'message',
     ];
-    $this->drupalPostForm('/webform/contact', $edit, t('Send message'), $source_entity_options);
+    $this->drupalPostForm('/webform/contact', $edit, 'Send message', $source_entity_options);
     $sid = $this->getLastSubmissionId($webform_contact);
     $submission = WebformSubmission::load($sid);
     $this->assertNotNull($submission->getSourceEntity());
diff --git a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTranslationTest.php b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTranslationTest.php
index 46f800284b..e574eb2ce5 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTranslationTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeTranslationTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform node translation.
  *
- * @group WebformNode
+ * @group webform_node
  */
 class WebformNodeTranslationTest extends WebformNodeBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeVariantTest.php b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeVariantTest.php
index e9947ae9cc..bcbddf1ea4 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeVariantTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Functional/WebformNodeVariantTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform node variants.
  *
- * @group WebformNode
+ * @group webform_node
  */
 class WebformNodeVariantTest extends WebformNodeBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_node/tests/src/Unit/WebformNodeUninstallValidatorTest.php b/web/modules/webform/modules/webform_node/tests/src/Unit/WebformNodeUninstallValidatorTest.php
index 1d6e781f5f..0483361db4 100644
--- a/web/modules/webform/modules/webform_node/tests/src/Unit/WebformNodeUninstallValidatorTest.php
+++ b/web/modules/webform/modules/webform_node/tests/src/Unit/WebformNodeUninstallValidatorTest.php
@@ -7,7 +7,7 @@
 
 /**
  * @coversDefaultClass \Drupal\webform_node\WebformNodeUninstallValidator
- * @group webform
+ * @group webform_node
  */
 class WebformNodeUninstallValidatorTest extends UnitTestCase {
 
diff --git a/web/modules/webform/modules/webform_node/webform_node.info.yml b/web/modules/webform/modules/webform_node/webform_node.info.yml
index b8f636d0fa..ea7e1856b1 100644
--- a/web/modules/webform/modules/webform_node/webform_node.info.yml
+++ b/web/modules/webform/modules/webform_node/webform_node.info.yml
@@ -2,7 +2,7 @@ name: 'Webform Node'
 type: module
 description: 'Provides a Webform content type which allows webforms to be integrated into a website as nodes.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:field'
   - 'drupal:node'
@@ -11,7 +11,7 @@ dependencies:
   - 'drupal:user'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_node/webform_node.install b/web/modules/webform/modules/webform_node/webform_node.install
index 525018072e..c8a144b7e0 100644
--- a/web/modules/webform/modules/webform_node/webform_node.install
+++ b/web/modules/webform/modules/webform_node/webform_node.install
@@ -13,11 +13,12 @@ function webform_node_requirements($phase) {
   // Throw error if Webform (webform) content type is already exists which will
   // happen during a D7 to D8 content migration.
   // @see https://www.drupal.org/node/2856599
-  if ($phase == 'install') {
+  if ($phase === 'install') {
     $manager = \Drupal::entityTypeManager();
     if ($manager->hasDefinition('node_type') && ($node_type = $manager->getStorage('node_type')->load('webform'))) {
       $requirements['webform_node'] = [
         'title' => t('Webform Node'),
+        'value' => t('%title content type already exists', ['%title' => $node_type->label()]),
         'description' => t('%title content type already exists, please delete the %title content type before installing the Webform node module.', ['%title' => $node_type->label()]),
         'severity' => REQUIREMENT_ERROR,
       ];
diff --git a/web/modules/webform/modules/webform_node/webform_node.module b/web/modules/webform/modules/webform_node/webform_node.module
index e7cd092ebf..9b1234a242 100644
--- a/web/modules/webform/modules/webform_node/webform_node.module
+++ b/web/modules/webform/modules/webform_node/webform_node.module
@@ -8,6 +8,7 @@
 use Drupal\Core\Serialization\Yaml;
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Database\Query\AlterableInterface;
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Url;
@@ -15,6 +16,7 @@
 use Drupal\node\NodeInterface;
 use Drupal\webform\Element\WebformMessage;
 use Drupal\webform\Entity\Webform;
+use Drupal\webform\WebformInterface;
 
 /**
  * Implements hook_entity_type_alter().
@@ -27,6 +29,22 @@ function webform_node_entity_type_alter(array &$entity_types) {
   }
 }
 
+/**
+ * Implements hook_entity_operation().
+ */
+function webform_node_entity_operation(EntityInterface $entity) {
+  $operations = [];
+  if ($entity instanceof WebformInterface
+    && $entity->access('update')) {
+    $operations['references'] = [
+      'title' => t('References'),
+      'url' => $entity->toUrl('references'),
+      'weight' => 40,
+    ];
+  }
+  return $operations;
+}
+
 /**
  * Implements hook_node_access().
  */
diff --git a/web/modules/webform/modules/webform_node/webform_node.tokens.inc b/web/modules/webform/modules/webform_node/webform_node.tokens.inc
index be2aa115fa..eeda6475f2 100644
--- a/web/modules/webform/modules/webform_node/webform_node.tokens.inc
+++ b/web/modules/webform/modules/webform_node/webform_node.tokens.inc
@@ -39,7 +39,7 @@ function webform_node_tokens($type, $tokens, array $data, array $options, Bubble
 
   $replacements = [];
 
-  if ($type == 'webform_submission' && !empty($data['webform_submission'])) {
+  if ($type === 'webform_submission' && !empty($data['webform_submission'])) {
     /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
     $webform_submission = $data['webform_submission'];
     $source_entity = $webform_submission->getSourceEntity(TRUE);
diff --git a/web/modules/webform/modules/webform_options_custom/config/install/webform.webform.example_options_custom.yml b/web/modules/webform/modules/webform_options_custom/config/install/webform.webform.example_options_custom.yml
index 2b5ce41791..bc4a73db17 100644
--- a/web/modules/webform/modules/webform_options_custom/config/install/webform.webform.example_options_custom.yml
+++ b/web/modules/webform/modules/webform_options_custom/config/install/webform.webform.example_options_custom.yml
@@ -27,7 +27,7 @@ elements: |
       one: One -- This is the number 1.
       two: Two -- This is the number 2.
       three:  Three -- This is the number 3.
-  
+
 css: ''
 javascript: ''
 settings:
@@ -39,7 +39,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -69,6 +69,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -94,11 +99,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_options_custom/js/webform_options_custom.element.js b/web/modules/webform/modules/webform_options_custom/js/webform_options_custom.element.js
index c9dfcc634a..abf55478c7 100644
--- a/web/modules/webform/modules/webform_options_custom/js/webform_options_custom.element.js
+++ b/web/modules/webform/modules/webform_options_custom/js/webform_options_custom.element.js
@@ -336,7 +336,7 @@
             content += '<div class="webform-options-custom-tooltip--description">' + option.description + '</div>';
           }
 
-          if (typeof $.ui.tooltip != 'undefined') {
+          if (typeof $.ui.tooltip !== 'undefined') {
             // jQuery UI tooltip support.
             var tooltipOptions = $.extend({
               content: content,
@@ -353,7 +353,7 @@
 
             $templateOption.tooltip(tooltipOptions);
           }
-          else if ((typeof $.fn.tooltip) != 'undefined') {
+          else if ((typeof $.fn.tooltip) !== 'undefined') {
             // Bootstrap tooltip support.
             var options = $.extend({
               html: true,
diff --git a/web/modules/webform/modules/webform_options_custom/src/Entity/WebformOptionsCustom.php b/web/modules/webform/modules/webform_options_custom/src/Entity/WebformOptionsCustom.php
index dd252c72ac..d95a3a428f 100644
--- a/web/modules/webform/modules/webform_options_custom/src/Entity/WebformOptionsCustom.php
+++ b/web/modules/webform/modules/webform_options_custom/src/Entity/WebformOptionsCustom.php
@@ -262,12 +262,12 @@ public function setOptions(array $options) {
    */
   public function getTemplate() {
     switch ($this->type) {
-      case static::TYPE_URL:
+      case WebformOptionsCustomInterface::TYPE_URL:
         $url = $this->getUrl();
         return ($url) ? file_get_contents($url) : '';
 
       default:
-      case static::TYPE_TEMPLATE:
+      case WebformOptionsCustomInterface::TYPE_TEMPLATE:
         return $this->template;
     }
   }
diff --git a/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomDeleteForm.php b/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomDeleteForm.php
index 597790a176..f006ba4f5a 100644
--- a/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomDeleteForm.php
+++ b/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomDeleteForm.php
@@ -39,7 +39,7 @@ public function getDetails() {
 
     $t_args = [
       '%label' => $this->getEntity()->label(),
-      '@entity-type' => $this->getEntity()->getEntityType()->getLowercaseLabel(),
+      '@entity-type' => $this->getEntity()->getEntityType()->getSingularLabel(),
     ];
 
     $details = [];
diff --git a/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomForm.php b/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomForm.php
index 939bd93318..3f8e692e14 100644
--- a/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomForm.php
+++ b/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomForm.php
@@ -46,7 +46,7 @@ public static function create(ContainerInterface $container) {
    * {@inheritdoc}
    */
   protected function prepareEntity() {
-    if ($this->operation == 'duplicate') {
+    if ($this->operation === 'duplicate') {
       $this->setEntity($this->getEntity()->createDuplicate());
     }
 
diff --git a/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomListBuilder.php b/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomListBuilder.php
index c7400ed848..efd66a891e 100644
--- a/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomListBuilder.php
+++ b/web/modules/webform/modules/webform_options_custom/src/WebformOptionsCustomListBuilder.php
@@ -197,7 +197,7 @@ public function getDefaultOperations(EntityInterface $entity, $type = 'edit') {
   protected function buildOptions(WebformOptionsCustomInterface $entity) {
     $options = $entity->getTemplateOptions();
     foreach ($options as $key => &$value) {
-      if ($key != $value) {
+      if ($key !== $value) {
         $value .= ' (' . $key . ')';
       }
     }
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/config/install/webform.webform.test_element_options_custom_ent.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/config/install/webform.webform.test_element_options_custom_ent.yml
index 4785e0f89b..06cfd37760 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/config/install/webform.webform.test_element_options_custom_ent.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/config/install/webform.webform.test_element_options_custom_ent.yml
@@ -27,7 +27,7 @@ elements: |
     '#selection_settings':
       target_bundles:
         page: page
-  
+
 css: ''
 javascript: ''
 settings:
@@ -39,7 +39,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -69,6 +69,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -94,11 +99,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/webform_options_custom_entity_test.info.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/webform_options_custom_entity_test.info.yml
index 2edd099293..4eff688f62 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/webform_options_custom_entity_test.info.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_entity_test/webform_options_custom_entity_test.info.yml
@@ -1,14 +1,14 @@
-name: 'Webform Custom Options Entity Reference Test'
+name: 'Webform Custom Options Entity Reference test'
 type: module
-description: 'Support module for webform that provides custom options entity reference element working examples.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform custom options entity reference element testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:node'
   - 'webform:webform_options_limit'
   - 'webform:webform_options_custom'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_html.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_html.yml
index 4e1a279a59..7bda41c3c6 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_html.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_html.yml
@@ -48,7 +48,7 @@ elements: |
     '#select2': true
     '#options':
       c: 'C -- This is the letter C. [element#options]'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -60,7 +60,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -90,6 +90,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -115,11 +120,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_imap.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_imap.yml
index eeabcb767d..9290afcc17 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_imap.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_imap.yml
@@ -18,7 +18,7 @@ elements: |
   webform_options_custom_image_map:
     '#type': 'webform_options_custom:test_image_map'
     '#title': webform_options_custom_image_map
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_svg.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_svg.yml
index 92f7e763c4..d8570be23c 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_svg.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_svg.yml
@@ -24,7 +24,7 @@ elements: |
     '#type': 'webform_options_custom:test_ballroom'
     '#title': webform_options_custom_url_ballroom
     '#required': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -36,7 +36,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -66,6 +66,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -91,11 +96,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_twig.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_twig.yml
index 62b486013a..267cc50c45 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_twig.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform.webform.test_element_options_custom_twig.yml
@@ -22,7 +22,7 @@ elements: |
     '#options':
       4: '4 -- Four'
       5: '5 -- Five'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -34,7 +34,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -64,6 +64,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -89,11 +94,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform_options_custom.webform_options_custom.test_image_map.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform_options_custom.webform_options_custom.test_image_map.yml
index 0b96e135f6..ff2e08223e 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform_options_custom.webform_options_custom.test_image_map.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/config/install/webform_options_custom.webform_options_custom.test_image_map.yml
@@ -8,12 +8,12 @@ help: 'An image map'
 category: Test
 type: template
 template: |
-  <img src="https://www.w3schools.com/tags/planets.gif" width="145" height="126" alt="Planets" usemap="#planetmap">
+  <img src="https://interactive-examples.mdn.mozilla.net/media/examples/mdn-info2.png" width="260" height="232" alt="MDN Infographic" usemap="#infographic">
 
-  <map name="planetmap">
-    <area shape="rect" coords="0,0,82,126" data-id="sun" alt="Sun" href="#">
-    <area shape="circle" coords="90,58,3" data-id="mercury" alt="Mercury" href="#">
-    <area shape="circle" coords="124,58,8" data-id="venus" alt="Venus" href="#">
+  <map name="infographic">
+    <area shape="poly" coords="130,147,200,107,254,219,130,228" href="https://developer.mozilla.org/docs/Web/HTML" target="_blank" data-id="html"  alt="HTML" />
+    <area shape="poly" coords="130,147,130,228,6,219,59,107" href="https://developer.mozilla.org/docs/Web/CSS" target="_blank" data-id="css" alt="CSS" />
+    <area shape="poly" coords="130,147,200,107,130,4,59,107" href="https://developer.mozilla.org/docs/Web/JavaScript" target="_blank" data-id="javascript" alt="JavaScript" />
   </map>
 url: ''
 css: ''
@@ -24,6 +24,6 @@ text_attributes: alt
 fill: false
 zoom: false
 tooltip: false
-show_select: false
+show_select: true
 element: true
 entity_reference: false
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.info.yml b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.info.yml
index 1c73548344..6da05c4e2e 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.info.yml
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform Custom Options Test'
+name: 'Webform Custom Options test'
 type: module
-description: 'Support module for webform that provides custom options element working examples.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform custom options element testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_options_custom'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.module b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.module
index e50c5ac757..89ca4cf3b1 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.module
+++ b/web/modules/webform/modules/webform_options_custom/tests/modules/webform_options_custom_test/webform_options_custom_test.module
@@ -6,7 +6,7 @@
  */
 
 /**
- * Implements hook_ENTITY_TYPE_load().
+ * Implements hook_ENTITY_TYPE_load() for webform entities.
  */
 function webform_options_custom_test_webform_load(array $entities) {
   if (!isset($entities['test_element_options_custom'])) {
diff --git a/web/modules/webform/modules/webform_options_custom/tests/src/Functional/WebformOptionsCustomEntityTest.php b/web/modules/webform/modules/webform_options_custom/tests/src/Functional/WebformOptionsCustomEntityTest.php
index 8608f06445..d2ddc0a87c 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/src/Functional/WebformOptionsCustomEntityTest.php
+++ b/web/modules/webform/modules/webform_options_custom/tests/src/Functional/WebformOptionsCustomEntityTest.php
@@ -9,7 +9,7 @@
 /**
  * Webform options custom entity test.
  *
- * @group webform_browser
+ * @group webform_options_custom
  */
 class WebformOptionsCustomEntityTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_options_custom/tests/src/Functional/WebformOptionsCustomTest.php b/web/modules/webform/modules/webform_options_custom/tests/src/Functional/WebformOptionsCustomTest.php
index 007f51df6a..7a2f28e96e 100644
--- a/web/modules/webform/modules/webform_options_custom/tests/src/Functional/WebformOptionsCustomTest.php
+++ b/web/modules/webform/modules/webform_options_custom/tests/src/Functional/WebformOptionsCustomTest.php
@@ -9,7 +9,7 @@
 /**
  * Webform options custom test.
  *
- * @group webform_browser
+ * @group webform_options_custom
  */
 class WebformOptionsCustomTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_options_custom/webform_options_custom.info.yml b/web/modules/webform/modules/webform_options_custom/webform_options_custom.info.yml
index d6f1369d9e..5b47f0b413 100644
--- a/web/modules/webform/modules/webform_options_custom/webform_options_custom.info.yml
+++ b/web/modules/webform/modules/webform_options_custom/webform_options_custom.info.yml
@@ -1,13 +1,12 @@
 name: 'Webform Custom Options [EXPERIMENTAL]'
 type: module
 description: 'Provides a webform element for converting HTML or SVG markup into a selectable single or multiple options input.'
-experimental: true
-package: 'Webform [EXPERIMENTAL]'
-core_version_requirement: ^8.7.7 || ^9
+package: 'Webform'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_options_limit/src/Controller/WebformOptionsLimitController.php b/web/modules/webform/modules/webform_options_limit/src/Controller/WebformOptionsLimitController.php
index 420087dc16..c9e5aba64e 100644
--- a/web/modules/webform/modules/webform_options_limit/src/Controller/WebformOptionsLimitController.php
+++ b/web/modules/webform/modules/webform_options_limit/src/Controller/WebformOptionsLimitController.php
@@ -20,7 +20,7 @@
 class WebformOptionsLimitController extends ControllerBase implements ContainerInjectionInterface {
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformHandler/OptionsLimitWebformHandler.php b/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformHandler/OptionsLimitWebformHandler.php
index 4640630d71..0679a2eb4d 100644
--- a/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformHandler/OptionsLimitWebformHandler.php
+++ b/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformHandler/OptionsLimitWebformHandler.php
@@ -44,66 +44,6 @@ class OptionsLimitWebformHandler extends WebformHandlerBase implements WebformOp
 
   use WebformAjaxElementTrait;
 
-  /**
-   * Default option value.
-   */
-  const DEFAULT_LIMIT = '_default_';
-
-  /**
-   * Option limit single remaining.
-   */
-  const LIMIT_STATUS_SINGLE = 'single';
-
-  /**
-   * Option limit multiple remaining.
-   */
-  const LIMIT_STATUS_MULTIPLE = 'multiple';
-
-  /**
-   * Option limit none remaining.
-   */
-  const LIMIT_STATUS_NONE = 'none';
-
-  /**
-   * Option limit unlimited.
-   */
-  const LIMIT_STATUS_UNLIMITED = 'unlimited';
-
-  /**
-   * Option limit eror.
-   */
-  const LIMIT_STATUS_ERROR = 'error';
-
-  /**
-   * Option limit action disable.
-   */
-  const LIMIT_ACTION_DISABLE = 'disable';
-
-  /**
-   * Option limit action remove.
-   */
-  const LIMIT_ACTION_REMOVE = 'remove';
-
-  /**
-   * Option limit action none.
-   */
-  const LIMIT_ACTION_NONE = 'none';
-
-  /**
-   * Option message label.
-   */
-  const MESSAGE_DISPLAY_LABEL = 'label';
-
-  /**
-   * Option message none.
-   */
-  const MESSAGE_DISPLAY_DESCRIPTION = 'description';
-
-  /**
-   * Option message none.
-   */
-  const MESSAGE_DISPLAY_NONE = 'none';
-
   /**
    * The database object.
    *
@@ -119,7 +59,7 @@ class OptionsLimitWebformHandler extends WebformHandlerBase implements WebformOp
   protected $tokenManager;
 
   /**
-   * A webform element plugin manager.
+   * The webform element plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
@@ -312,7 +252,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
 
       if ($this->isOptionsElement()) {
         $element_options = $this->getElementOptions() + [
-          static::DEFAULT_LIMIT => $this->t('Default (Used when option has no limit)'),
+          WebformOptionsLimitHandlerInterface::DEFAULT_LIMIT => $this->t('Default (Used when option has no limit)'),
         ];
         $form['element_settings']['options_container']['limits'] = [
           '#type' => 'webform_mapping',
@@ -388,7 +328,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#states' => [
         'visible' => [
           ':input[name="settings[limit_user]"]' => ['checked' => TRUE],
-        ]
+        ],
       ],
     ];
     // Option settings.
@@ -400,9 +340,9 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#type' => 'select',
       '#title' => $this->t('Limit reached behavior'),
       '#options' => [
-        static::LIMIT_ACTION_DISABLE => $this->t('Disable the option/checkbox'),
-        static::LIMIT_ACTION_REMOVE => $this->t('Remove the option/checkbox'),
-        static::LIMIT_ACTION_NONE => $this->t('Do not alter the option/checkbox'),
+        WebformOptionsLimitHandlerInterface::LIMIT_ACTION_DISABLE => $this->t('Disable the option/checkbox'),
+        WebformOptionsLimitHandlerInterface::LIMIT_ACTION_REMOVE => $this->t('Remove the option/checkbox'),
+        WebformOptionsLimitHandlerInterface::LIMIT_ACTION_NONE => $this->t('Do not alter the option/checkbox'),
       ],
       '#default_value' => $this->configuration['option_none_action'],
     ];
@@ -410,9 +350,9 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#type' => 'select',
       '#title' => $this->t('Message display'),
       '#options' => [
-        static::MESSAGE_DISPLAY_LABEL => $this->t("Append message to the option/checkbox's text"),
-        static::MESSAGE_DISPLAY_DESCRIPTION => $this->t("Append message to the option/checkbox's description"),
-        static::MESSAGE_DISPLAY_NONE => $this->t("Do not display a message"),
+        WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_LABEL => $this->t("Append message to the option/checkbox's text"),
+        WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_DESCRIPTION => $this->t("Append message to the option/checkbox's description"),
+        WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_NONE => $this->t("Do not display a message"),
       ],
       '#default_value' => $this->configuration['option_message_display'],
     ];
@@ -478,7 +418,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
         '#default_value' => $this->configuration['tableselect_header'],
         '#states' => [
           'visible' => [
-            ':input[name="settings[option_message_display]"]' => ['value' => static::MESSAGE_DISPLAY_DESCRIPTION],
+            ':input[name="settings[option_message_display]"]' => ['value' => WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_DESCRIPTION],
             $tableselect_states,
           ],
         ],
@@ -555,7 +495,7 @@ public function alterElement(array &$element, FormStateInterface $form_state, ar
       // Set table select description in header.
       if ($this->isTableSelectElement()) {
         $message_display = $this->configuration['option_message_display'];
-        if ($message_display === static::MESSAGE_DISPLAY_DESCRIPTION) {
+        if ($message_display === WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_DESCRIPTION) {
           $element['#header']['webform_options_limit'] = $this->configuration['tableselect_header'] ?: '';
         }
       }
@@ -696,11 +636,11 @@ protected function alterOptionsElement(array &$element, array $limits, array $re
     // Disable or remove reached options.
     if ($reached) {
       switch ($this->configuration['option_none_action']) {
-        case static::LIMIT_ACTION_DISABLE:
+        case WebformOptionsLimitHandlerInterface::LIMIT_ACTION_DISABLE:
           $this->disableOptionsElement($element, $reached);
           break;
 
-        case static::LIMIT_ACTION_REMOVE:
+        case WebformOptionsLimitHandlerInterface::LIMIT_ACTION_REMOVE:
           $this->removeOptionsElement($element, $reached);
           break;
       }
@@ -732,13 +672,13 @@ protected function alterOptionsElementLabels(array &$options, array $limits) {
           $message_display = $this->configuration['option_message_display'];
           $option =& $options[$option_value][0];
           switch ($message_display) {
-            case static::MESSAGE_DISPLAY_DESCRIPTION:
+            case WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_DESCRIPTION:
               list(
                 $option['value'],
                 $option['webform_options_limit']) = explode(' --', $label);
               break;
 
-            case static::MESSAGE_DISPLAY_LABEL:
+            case WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_LABEL:
               $option['value'] = $label;
               break;
           }
@@ -857,8 +797,8 @@ public function validateOptionsElement(array $element, FormStateInterface $form_
       if (in_array($value, $original_values)) {
         continue;
       }
-      if ($limit['status'] === static::LIMIT_STATUS_NONE) {
-        $message = $this->getElementLimitStatusMessage(static::LIMIT_STATUS_ERROR, $limit);
+      if ($limit['status'] === WebformOptionsLimitHandlerInterface::LIMIT_STATUS_NONE) {
+        $message = $this->getElementLimitStatusMessage(WebformOptionsLimitHandlerInterface::LIMIT_STATUS_ERROR, $limit);
         $form_state->setError($element, $message);
       }
     }
@@ -880,7 +820,7 @@ public function validateOptionsElement(array $element, FormStateInterface $form_
    */
   protected function setBooleanElementDefaultValue(array &$element, array $limit, $operation) {
     if ($operation === 'test') {
-      if ($limit['status'] === static::LIMIT_STATUS_NONE) {
+      if ($limit['status'] === WebformOptionsLimitHandlerInterface::LIMIT_STATUS_NONE) {
         unset($element['#default_value']);
       }
     }
@@ -888,7 +828,7 @@ protected function setBooleanElementDefaultValue(array &$element, array $limit,
       $element_key = $this->configuration['element_key'];
       $webform_submission = $this->getWebformSubmission();
       $original_value = $webform_submission->getElementOriginalData($element_key);
-      if ($limit['status'] === static::LIMIT_STATUS_NONE && !$original_value) {
+      if ($limit['status'] === WebformOptionsLimitHandlerInterface::LIMIT_STATUS_NONE && !$original_value) {
         unset($element['#default_value']);
       }
     }
@@ -905,11 +845,11 @@ protected function setBooleanElementDefaultValue(array &$element, array $limit,
   protected function alterBooleanElement(array &$element, array $limit) {
     // Set message.
     $message_display = $this->configuration['option_message_display'];
-    if ($message_display !== static::MESSAGE_DISPLAY_NONE) {
+    if ($message_display !== WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_NONE) {
       $message = $this->getElementLimitStatusMessage($limit['status'], $limit);
       if ($message) {
         switch ($message_display) {
-          case static::MESSAGE_DISPLAY_LABEL:
+          case WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_LABEL:
             $t_args = [
               '@label' => $element['#title'],
               '@message' => $message,
@@ -917,7 +857,7 @@ protected function alterBooleanElement(array &$element, array $limit) {
             $element['#title'] = $this->t('@label @message', $t_args);
             break;
 
-          case static::MESSAGE_DISPLAY_DESCRIPTION:
+          case WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_DESCRIPTION:
             $element += ['#description' => ''];
             $element['#description'] .= ($element['#description']) ? '<br/>' . $message : $message;
             break;
@@ -929,13 +869,13 @@ protected function alterBooleanElement(array &$element, array $limit) {
     $element_key = $this->configuration['element_key'];
     $webform_submission = $this->getWebformSubmission();
     $boolean_value = (boolean) ($webform_submission->getElementOriginalData($element_key) ?: FALSE);
-    if ($limit['status'] === static::LIMIT_STATUS_NONE && !$boolean_value) {
+    if ($limit['status'] === WebformOptionsLimitHandlerInterface::LIMIT_STATUS_NONE && !$boolean_value) {
       switch ($this->configuration['option_none_action']) {
-        case static::LIMIT_ACTION_DISABLE:
+        case WebformOptionsLimitHandlerInterface::LIMIT_ACTION_DISABLE:
           $element['#disabled'] = TRUE;
           break;
 
-        case static::LIMIT_ACTION_REMOVE:
+        case WebformOptionsLimitHandlerInterface::LIMIT_ACTION_REMOVE:
           $element['#access'] = FALSE;
           break;
       }
@@ -980,7 +920,7 @@ public function validateBooleanElement(array $element, FormStateInterface $form_
     $total = $this->getBooleanTotal();
     if ($total >= $limit) {
       $limits = $this->getBooleanLimits();
-      $message = $this->getElementLimitStatusMessage(static::LIMIT_STATUS_ERROR, reset($limits));
+      $message = $this->getElementLimitStatusMessage(WebformOptionsLimitHandlerInterface::LIMIT_STATUS_ERROR, reset($limits));
       $form_state->setError($element, $message);
     }
   }
@@ -1235,8 +1175,8 @@ protected function getElementOptions() {
    *   including the option's limit, total, remaining, and status.
    */
   protected function getOptionsLimits(array $values = []) {
-    $default_limit = isset($this->configuration['limits'][static::DEFAULT_LIMIT])
-      ? $this->configuration['limits'][static::DEFAULT_LIMIT]
+    $default_limit = isset($this->configuration['limits'][WebformOptionsLimitHandlerInterface::DEFAULT_LIMIT])
+      ? $this->configuration['limits'][WebformOptionsLimitHandlerInterface::DEFAULT_LIMIT]
       : NULL;
 
     $totals = $this->getOptionsTotals($values);
@@ -1295,16 +1235,16 @@ protected function getLimitInformation($label, $limit, $total) {
     $remaining = ($limit) ? $limit - $total : NULL;
 
     if (empty($limit)) {
-      $status = static::LIMIT_STATUS_UNLIMITED;
+      $status = WebformOptionsLimitHandlerInterface::LIMIT_STATUS_UNLIMITED;
     }
     elseif ($remaining <= 0) {
-      $status = static::LIMIT_STATUS_NONE;
+      $status = WebformOptionsLimitHandlerInterface::LIMIT_STATUS_NONE;
     }
     elseif ($remaining === 1) {
-      $status = static::LIMIT_STATUS_SINGLE;
+      $status = WebformOptionsLimitHandlerInterface::LIMIT_STATUS_SINGLE;
     }
     else {
-      $status = static::LIMIT_STATUS_MULTIPLE;
+      $status = WebformOptionsLimitHandlerInterface::LIMIT_STATUS_MULTIPLE;
     }
 
     return [
@@ -1334,7 +1274,7 @@ protected function getOptionsReached(array $limits) {
       if ($element_values && in_array($option_value, $element_values)) {
         continue;
       }
-      if ($limit['status'] === static::LIMIT_STATUS_NONE) {
+      if ($limit['status'] === WebformOptionsLimitHandlerInterface::LIMIT_STATUS_NONE) {
         $reached[$option_value] = $option_value;
       }
     }
@@ -1472,7 +1412,7 @@ protected function getElementLimitStatusMessage($type, array $limit) {
    */
   protected function getOptionsLimitLabel($label, array $limit) {
     $message_display = $this->configuration['option_message_display'];
-    if ($message_display === static::MESSAGE_DISPLAY_NONE) {
+    if ($message_display === WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_NONE) {
       return $label;
     }
 
@@ -1482,11 +1422,11 @@ protected function getOptionsLimitLabel($label, array $limit) {
     }
 
     switch ($message_display) {
-      case static::MESSAGE_DISPLAY_LABEL:
+      case WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_LABEL:
         $t_args = ['@label' => $label, '@message' => $message];
         return $this->t('@label @message', $t_args);
 
-      case static::MESSAGE_DISPLAY_DESCRIPTION:
+      case WebformOptionsLimitHandlerInterface::MESSAGE_DISPLAY_DESCRIPTION:
         return $label
           . (strpos($label, WebformOptionsHelper::DESCRIPTION_DELIMITER) === FALSE ? WebformOptionsHelper::DESCRIPTION_DELIMITER : '')
           . $message;
diff --git a/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformOptionsLimitHandlerInterface.php b/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformOptionsLimitHandlerInterface.php
index aff4afbce4..f01356fd8e 100644
--- a/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformOptionsLimitHandlerInterface.php
+++ b/web/modules/webform/modules/webform_options_limit/src/Plugin/WebformOptionsLimitHandlerInterface.php
@@ -10,6 +10,66 @@
  */
 interface WebformOptionsLimitHandlerInterface extends WebformHandlerInterface {
 
+  /**
+   * Default option value.
+   */
+  const DEFAULT_LIMIT = '_default_';
+
+  /**
+   * Option limit single remaining.
+   */
+  const LIMIT_STATUS_SINGLE = 'single';
+
+  /**
+   * Option limit multiple remaining.
+   */
+  const LIMIT_STATUS_MULTIPLE = 'multiple';
+
+  /**
+   * Option limit none remaining.
+   */
+  const LIMIT_STATUS_NONE = 'none';
+
+  /**
+   * Option limit unlimited.
+   */
+  const LIMIT_STATUS_UNLIMITED = 'unlimited';
+
+  /**
+   * Option limit eror.
+   */
+  const LIMIT_STATUS_ERROR = 'error';
+
+  /**
+   * Option limit action disable.
+   */
+  const LIMIT_ACTION_DISABLE = 'disable';
+
+  /**
+   * Option limit action remove.
+   */
+  const LIMIT_ACTION_REMOVE = 'remove';
+
+  /**
+   * Option limit action none.
+   */
+  const LIMIT_ACTION_NONE = 'none';
+
+  /**
+   * Option message label.
+   */
+  const MESSAGE_DISPLAY_LABEL = 'label';
+
+  /**
+   * Option message none.
+   */
+  const MESSAGE_DISPLAY_DESCRIPTION = 'description';
+
+  /**
+   * Option message none.
+   */
+  const MESSAGE_DISPLAY_NONE = 'none';
+
   /**
    * Set the webform source entity.
    *
diff --git a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_boolean_limit.yml b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_boolean_limit.yml
index 3fb731c774..c5cce92c08 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_boolean_limit.yml
+++ b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_boolean_limit.yml
@@ -29,7 +29,7 @@ elements: |
     '#type': checkbox
     '#title': boolean_limit_remove
     '#default_value': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -41,7 +41,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -71,6 +71,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: true
   submission_views: {  }
@@ -96,11 +101,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit.yml b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit.yml
index fdc48f5b93..ad44708fa4 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit.yml
+++ b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit.yml
@@ -111,6 +111,7 @@ elements: |
       Y: Y
       Z: Z
     '#default_value': X
+
 css: ''
 javascript: ''
 settings:
@@ -122,7 +123,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -152,6 +153,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: true
   submission_views: {  }
@@ -177,11 +183,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -448,7 +460,7 @@ handlers:
       element_key: options_limit_tableselect_single
       limits:
         X: 1
-        Y: 2
+        'Y': 2
       limit_reached_message: '@name is not available.'
       limit_source_entity: true
       limit_user: false
@@ -459,5 +471,5 @@ handlers:
       option_none_message: '[@remaining remaining]'
       option_unlimited_message: '[Unlimited]'
       option_error_message: '@name: @label is unavailable.'
-      tableselect_header: 'Limits'
+      tableselect_header: Limits
 variants: {  }
diff --git a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_ent.yml b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_ent.yml
index efb23c681e..08129b6f36 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_ent.yml
+++ b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_ent.yml
@@ -38,7 +38,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -68,6 +68,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: true
   submission_views: {  }
@@ -93,11 +98,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_user.yml b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_user.yml
index b7b9ad61c7..1edb4062ec 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_user.yml
+++ b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/config/install/webform.webform.test_handler_options_limit_user.yml
@@ -40,7 +40,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -70,6 +70,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: true
   submission_views: {  }
@@ -95,11 +100,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/webform_options_limit_test.info.yml b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/webform_options_limit_test.info.yml
index a91d20e99e..e61d85ece4 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/webform_options_limit_test.info.yml
+++ b/web/modules/webform/modules/webform_options_limit/tests/modules/webform_options_limit_test/webform_options_limit_test.info.yml
@@ -1,13 +1,13 @@
-name: 'Webform options limit module tests'
+name: 'Webform Options Limit test'
 type: module
-description: 'Support module for webform options limit that provides test forms.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform options limit testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
   - 'webform:webform_options_limit'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitAccessTest.php b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitAccessTest.php
index 8eb32705ac..8173d1ca81 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitAccessTest.php
+++ b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitAccessTest.php
@@ -8,7 +8,7 @@
 /**
  * Webform options limit test.
  *
- * @group webform_browser
+ * @group webform_options_limit
  */
 class WebformOptionsLimitAccessTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitBooleanTest.php b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitBooleanTest.php
index e06edbe68b..08393bdf16 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitBooleanTest.php
+++ b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitBooleanTest.php
@@ -8,7 +8,7 @@
 /**
  * Webform boolean limit test.
  *
- * @group webform_browser
+ * @group webform_options_limit
  */
 class WebformOptionsLimitBooleanTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitEntityReferenceTest.php b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitEntityReferenceTest.php
index 4499242989..c45466fd48 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitEntityReferenceTest.php
+++ b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitEntityReferenceTest.php
@@ -8,7 +8,7 @@
 /**
  * Webform options entity reference limit test.
  *
- * @group webform_browser
+ * @group webform_options_limit
  */
 class WebformOptionsLimitEntityReferenceTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitSourceEntityTest.php b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitSourceEntityTest.php
index 0b9d8af02e..7a02a97f3d 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitSourceEntityTest.php
+++ b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitSourceEntityTest.php
@@ -8,7 +8,7 @@
 /**
  * Webform options limit source entity test.
  *
- * @group webform_browser
+ * @group webform_options_limit
  */
 class WebformOptionsLimitSourceEntityTest extends WebformNodeBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitTest.php b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitTest.php
index 98dce40588..c62dcddd8e 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitTest.php
+++ b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitTest.php
@@ -8,7 +8,7 @@
 /**
  * Webform options limit test.
  *
- * @group webform_browser
+ * @group webform_options_limit
  */
 class WebformOptionsLimitTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitUserTest.php b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitUserTest.php
index 19235a5c01..21abae99c4 100644
--- a/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitUserTest.php
+++ b/web/modules/webform/modules/webform_options_limit/tests/src/Functional/WebformOptionsLimitUserTest.php
@@ -8,7 +8,7 @@
 /**
  * Webform options limit test.
  *
- * @group webform_browser
+ * @group webform_options_limit
  */
 class WebformOptionsLimitUserTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_options_limit/webform_options_limit.info.yml b/web/modules/webform/modules/webform_options_limit/webform_options_limit.info.yml
index 67af9cf440..b93c788080 100644
--- a/web/modules/webform/modules/webform_options_limit/webform_options_limit.info.yml
+++ b/web/modules/webform/modules/webform_options_limit/webform_options_limit.info.yml
@@ -1,13 +1,12 @@
 name: 'Webform Options Limit [EXPERIMENTAL]'
 type: module
 description: 'Allows elements with options (i.e. select, checkboxes, and radios) to have option specific submission limits.'
-experimental: true
-package: 'Webform [EXPERIMENTAL]'
-core_version_requirement: ^8.7.7 || ^9
+package: 'Webform'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_options_limit/webform_options_limit.module b/web/modules/webform/modules/webform_options_limit/webform_options_limit.module
index 6e29e0e95c..42a7c15d2a 100644
--- a/web/modules/webform/modules/webform_options_limit/webform_options_limit.module
+++ b/web/modules/webform/modules/webform_options_limit/webform_options_limit.module
@@ -9,6 +9,7 @@
  * Implements hook_webform_help_info().
  */
 function webform_options_limit_webform_help_info() {
+  $help = [];
   $help['webform_options_limit'] = [
     'group' => 'forms',
     'title' => t('Options limit'),
@@ -20,7 +21,6 @@ function webform_options_limit_webform_help_info() {
       'entity.node.webform_options_limit.summary',
     ],
   ];
-
   return $help;
 }
 
diff --git a/web/modules/webform/modules/webform_scheduled_email/src/Plugin/WebformHandler/ScheduleEmailWebformHandler.php b/web/modules/webform/modules/webform_scheduled_email/src/Plugin/WebformHandler/ScheduleEmailWebformHandler.php
index f37a65559f..d0ddec96d1 100644
--- a/web/modules/webform/modules/webform_scheduled_email/src/Plugin/WebformHandler/ScheduleEmailWebformHandler.php
+++ b/web/modules/webform/modules/webform_scheduled_email/src/Plugin/WebformHandler/ScheduleEmailWebformHandler.php
@@ -80,7 +80,7 @@ public function getSummary() {
         '#message_type' => $status_messages[$type]['type'],
       ];
 
-      if ($status_messages[$type]['type'] == 'warning') {
+      if ($status_messages[$type]['type'] === 'warning') {
         $cron_link = TRUE;
       }
     }
diff --git a/web/modules/webform/modules/webform_scheduled_email/src/WebformScheduledEmailManager.php b/web/modules/webform/modules/webform_scheduled_email/src/WebformScheduledEmailManager.php
index d77ef1ff47..a9375e4729 100644
--- a/web/modules/webform/modules/webform_scheduled_email/src/WebformScheduledEmailManager.php
+++ b/web/modules/webform/modules/webform_scheduled_email/src/WebformScheduledEmailManager.php
@@ -60,14 +60,14 @@ class WebformScheduledEmailManager implements WebformScheduledEmailManagerInterf
   protected $configFactory;
 
   /**
-   * Webform storage.
+   * The webform storage.
    *
    * @var \Drupal\webform\WebformEntityStorageInterface
    */
   protected $webformStorage;
 
   /**
-   * Webform submission storage.
+   * The webform submission storage.
    *
    * @var \Drupal\webform\WebformSubmissionStorageInterface
    */
@@ -222,7 +222,7 @@ public function schedule(EntityInterface $entity, $handler_id) {
       $send_iso_date = $this->getSendDate($webform_submission, $handler_id);
       if ($send_iso_date === FALSE) {
         $this->unschedule($webform_submission, $handler_id);
-        return self::EMAIL_UNSCHEDULED;
+        return WebformScheduledEmailManagerInterface::EMAIL_UNSCHEDULED;
       }
       $send_timestamp = strtotime($send_iso_date);
 
@@ -230,19 +230,19 @@ public function schedule(EntityInterface $entity, $handler_id) {
       $state = $webform_submission->getState();
       if (!in_array($state, $handler_configuration['settings']['states']) && $handler_configuration['settings']['unschedule']) {
         $this->unschedule($webform_submission, $handler_id);
-        return self::EMAIL_UNSCHEDULED;
+        return WebformScheduledEmailManagerInterface::EMAIL_UNSCHEDULED;
       }
 
       // Check if action should be triggered in the past.
       if (!empty($handler_configuration['settings']['ignore_past']) && $send_timestamp < $this->time->getRequestTime()) {
         $this->unschedule($webform_submission, $handler_id);
-        return self::EMAIL_IGNORED;
+        return WebformScheduledEmailManagerInterface::EMAIL_IGNORED;
       }
 
       // Check recipient.
       if (!$handler->hasRecipient($webform_submission, $handler->getMessage($webform_submission))) {
         $this->unschedule($webform_submission, $handler_id);
-        return self::EMAIL_UNSCHEDULED;
+        return WebformScheduledEmailManagerInterface::EMAIL_UNSCHEDULED;
       }
 
       // See if there is already a scheduled email.
@@ -252,19 +252,19 @@ public function schedule(EntityInterface $entity, $handler_id) {
       if (!$scheduled_email) {
         $query = $this->database->insert('webform_scheduled_email');
         $action = $this->t('scheduled');
-        $status = self::EMAIL_SCHEDULED;
+        $status = WebformScheduledEmailManagerInterface::EMAIL_SCHEDULED;
       }
       else {
         $query = $this->database->update('webform_scheduled_email');
         $query->condition('eid', $scheduled_email->eid);
 
-        if ($scheduled_email->send != $send_timestamp) {
+        if ($scheduled_email->send !== $send_timestamp) {
           $action = $this->t('rescheduled');
-          $status = self::EMAIL_RESCHEDULED;
+          $status = WebformScheduledEmailManagerInterface::EMAIL_RESCHEDULED;
         }
         else {
           $action = NULL;
-          $status = self::EMAIL_ALREADY_SCHEDULED;
+          $status = WebformScheduledEmailManagerInterface::EMAIL_ALREADY_SCHEDULED;
         }
       }
 
@@ -274,12 +274,12 @@ public function schedule(EntityInterface $entity, $handler_id) {
         'entity_type' => $webform_submission->entity_type->value,
         'entity_id' => $webform_submission->entity_id->value,
         'handler_id' => $handler_id,
-        'state' => self::SUBMISSION_SEND,
+        'state' => WebformScheduledEmailManagerInterface::SUBMISSION_SEND,
         'send' => $send_timestamp,
       ])->execute();
 
       // If email is alread scheduled when don't need to log anything.
-      if ($status === self::EMAIL_ALREADY_SCHEDULED) {
+      if ($status === WebformScheduledEmailManagerInterface::EMAIL_ALREADY_SCHEDULED) {
         return $status;
       }
 
@@ -303,7 +303,7 @@ public function schedule(EntityInterface $entity, $handler_id) {
 
       // Set all existing submissions reviewed.
       $this->database->update('webform_scheduled_email')
-        ->fields(['state' => self::SUBMISSION_SCHEDULE])
+        ->fields(['state' => WebformScheduledEmailManagerInterface::SUBMISSION_SCHEDULE])
         ->condition('webform_id', $webform->id())
         ->condition('handler_id', $handler_id)
         ->execute();
@@ -320,7 +320,7 @@ public function schedule(EntityInterface $entity, $handler_id) {
       $query = $this->database->select('webform_submission', 'w');
       $query->fields('w', ['webform_id', 'entity_type', 'entity_id', 'sid']);
       $query->addExpression("'$handler_id'", 'handler_id');
-      $query->addExpression("'" . self::SUBMISSION_SCHEDULE . "'", 'state');
+      $query->addExpression("'" . WebformScheduledEmailManagerInterface::SUBMISSION_SCHEDULE . "'", 'state');
       $query->condition('webform_id', $webform->id());
       if ($sids) {
         $query->condition('sid', $sids, 'NOT IN');
@@ -370,7 +370,7 @@ public function unschedule(EntityInterface $entity, $handler_id = NULL) {
     elseif ($entity instanceof WebformInterface) {
       $webform = $entity;
       $query = $this->database->update('webform_scheduled_email')
-        ->fields(['state' => self::SUBMISSION_UNSCHEDULE])
+        ->fields(['state' => WebformScheduledEmailManagerInterface::SUBMISSION_UNSCHEDULE])
         ->condition('webform_id', $webform->id());
       if ($handler_id) {
         $query->condition('handler_id', $handler_id);
@@ -381,7 +381,7 @@ public function unschedule(EntityInterface $entity, $handler_id = NULL) {
     // Since webform and submissions can also be used as a source entity,
     // include them in unscheduling.
     $query = $this->database->update('webform_scheduled_email')
-      ->fields(['state' => self::SUBMISSION_UNSCHEDULE])
+      ->fields(['state' => WebformScheduledEmailManagerInterface::SUBMISSION_UNSCHEDULE])
       ->condition('entity_type', $entity->getEntityTypeId())
       ->condition('entity_id', $entity->id());
     if ($handler_id) {
@@ -397,7 +397,7 @@ public function reschedule(EntityInterface $entity, $handler_id = NULL) {
     if ($entity instanceof WebformSubmissionInterface) {
       $webform_submission = $entity;
       $query = $this->database->update('webform_scheduled_email')
-        ->fields(['state' => self::SUBMISSION_RESCHEDULE])
+        ->fields(['state' => WebformScheduledEmailManagerInterface::SUBMISSION_RESCHEDULE])
         ->condition('sid', $webform_submission->id());
       if ($handler_id) {
         $query->condition('handler_id', $handler_id);
@@ -407,7 +407,7 @@ public function reschedule(EntityInterface $entity, $handler_id = NULL) {
     elseif ($entity instanceof WebformInterface) {
       $webform = $entity;
       $query = $this->database->update('webform_scheduled_email')
-        ->fields(['state' => self::SUBMISSION_RESCHEDULE])
+        ->fields(['state' => WebformScheduledEmailManagerInterface::SUBMISSION_RESCHEDULE])
         ->condition('webform_id', $webform->id());
       if ($handler_id) {
         $query->condition('handler_id', $handler_id);
@@ -418,7 +418,7 @@ public function reschedule(EntityInterface $entity, $handler_id = NULL) {
     // Since webform and submissions can also be used as a source entity,
     // include them in rescheduling.
     $query = $this->database->update('webform_scheduled_email')
-      ->fields(['state' => self::SUBMISSION_RESCHEDULE])
+      ->fields(['state' => WebformScheduledEmailManagerInterface::SUBMISSION_RESCHEDULE])
       ->condition('entity_type', $entity->getEntityTypeId())
       ->condition('entity_id', $entity->id());
     if ($handler_id) {
@@ -469,13 +469,13 @@ public function cron(EntityInterface $entity = NULL, $handler_id = NULL, $schedu
 
     // Build summary.
     $labels = [
-      self::EMAIL_SCHEDULED => $this->t('scheduled'),
-      self::EMAIL_RESCHEDULED => $this->t('rescheduled'),
-      self::EMAIL_ALREADY_SCHEDULED => $this->t('already scheduled'),
-      self::EMAIL_UNSCHEDULED => $this->t('unscheduled'),
-      self::EMAIL_SENT => $this->t('sent'),
-      self::EMAIL_NOT_SENT => $this->t('not sent'),
-      self::EMAIL_SKIPPED => $this->t('skipped'),
+      WebformScheduledEmailManagerInterface::EMAIL_SCHEDULED => $this->t('scheduled'),
+      WebformScheduledEmailManagerInterface::EMAIL_RESCHEDULED => $this->t('rescheduled'),
+      WebformScheduledEmailManagerInterface::EMAIL_ALREADY_SCHEDULED => $this->t('already scheduled'),
+      WebformScheduledEmailManagerInterface::EMAIL_UNSCHEDULED => $this->t('unscheduled'),
+      WebformScheduledEmailManagerInterface::EMAIL_SENT => $this->t('sent'),
+      WebformScheduledEmailManagerInterface::EMAIL_NOT_SENT => $this->t('not sent'),
+      WebformScheduledEmailManagerInterface::EMAIL_SKIPPED => $this->t('skipped'),
     ];
     $summary = [];
     foreach ($stats as $type => $total) {
@@ -518,10 +518,10 @@ public function cron(EntityInterface $entity = NULL, $handler_id = NULL, $schedu
    */
   protected function cronSchedule(EntityInterface $entity = NULL, $handler_id = NULL, $limit = 1000) {
     $stats = [
-      self::EMAIL_SCHEDULED => 0,
-      self::EMAIL_RESCHEDULED => 0,
-      self::EMAIL_UNSCHEDULED => 0,
-      self::EMAIL_ALREADY_SCHEDULED => 0,
+      WebformScheduledEmailManagerInterface::EMAIL_SCHEDULED => 0,
+      WebformScheduledEmailManagerInterface::EMAIL_RESCHEDULED => 0,
+      WebformScheduledEmailManagerInterface::EMAIL_UNSCHEDULED => 0,
+      WebformScheduledEmailManagerInterface::EMAIL_ALREADY_SCHEDULED => 0,
     ];
 
     if (empty($limit)) {
@@ -532,7 +532,7 @@ protected function cronSchedule(EntityInterface $entity = NULL, $handler_id = NU
 
     $query = $this->database->select('webform_scheduled_email', 'w')
       ->fields('w', ['eid', 'sid', 'webform_id', 'entity_type', 'entity_id', 'handler_id', 'state', 'send'])
-      ->condition('w.state', [self::SUBMISSION_SCHEDULE, self::SUBMISSION_UNSCHEDULE, self::SUBMISSION_RESCHEDULE], 'IN')
+      ->condition('w.state', [WebformScheduledEmailManagerInterface::SUBMISSION_SCHEDULE, WebformScheduledEmailManagerInterface::SUBMISSION_UNSCHEDULE, WebformScheduledEmailManagerInterface::SUBMISSION_RESCHEDULE], 'IN')
       ->orderBy('w.send')
       ->orderBy('w.sid')
       ->range(0, $limit);
@@ -576,15 +576,15 @@ protected function cronSchedule(EntityInterface $entity = NULL, $handler_id = NU
       $webform_submission = $webform_submissions[$record->sid];
       $handler_id = $record->handler_id;
       switch ($record->state) {
-        case self::SUBMISSION_SCHEDULE:
-        case self::SUBMISSION_RESCHEDULE:
+        case WebformScheduledEmailManagerInterface::SUBMISSION_SCHEDULE:
+        case WebformScheduledEmailManagerInterface::SUBMISSION_RESCHEDULE:
           $email_status = $this->schedule($webform_submission, $handler_id);
           $stats[$email_status]++;
           break;
 
-        case self::SUBMISSION_UNSCHEDULE:
+        case WebformScheduledEmailManagerInterface::SUBMISSION_UNSCHEDULE:
           $this->unschedule($webform_submission, $handler_id);
-          $stats[self::EMAIL_UNSCHEDULED]++;
+          $stats[WebformScheduledEmailManagerInterface::EMAIL_UNSCHEDULED]++;
           break;
       }
     }
@@ -607,9 +607,9 @@ protected function cronSchedule(EntityInterface $entity = NULL, $handler_id = NU
    */
   protected function cronSend(EntityInterface $entity = NULL, $handler_id = NULL, $limit = 500) {
     $stats = [
-      self::EMAIL_SENT => 0,
-      self::EMAIL_NOT_SENT => 0,
-      self::EMAIL_SKIPPED => 0,
+      WebformScheduledEmailManagerInterface::EMAIL_SENT => 0,
+      WebformScheduledEmailManagerInterface::EMAIL_NOT_SENT => 0,
+      WebformScheduledEmailManagerInterface::EMAIL_SKIPPED => 0,
     ];
     if (empty($limit)) {
       return $stats;
@@ -621,7 +621,7 @@ protected function cronSend(EntityInterface $entity = NULL, $handler_id = NULL,
     // be sent.
     $query = $this->database->select('webform_scheduled_email', 'w')
       ->fields('w', ['eid', 'sid', 'webform_id', 'entity_type', 'entity_id', 'handler_id', 'send'])
-      ->condition('w.state', self::SUBMISSION_SEND)
+      ->condition('w.state', WebformScheduledEmailManagerInterface::SUBMISSION_SEND)
       ->condition('w.send', time(), '<')
       ->orderBy('w.send')
       ->range(0, $limit);
@@ -664,7 +664,7 @@ protected function cronSend(EntityInterface $entity = NULL, $handler_id = NULL,
         // Skip sending email.
         $action = $this->t('skipped (conditions not met)');
         $operation = 'scheduled email skipped';
-        $stat = self::EMAIL_SKIPPED;
+        $stat = WebformScheduledEmailManagerInterface::EMAIL_SKIPPED;
       }
       else {
         // Switch to submission language.
@@ -699,7 +699,7 @@ protected function cronSend(EntityInterface $entity = NULL, $handler_id = NULL,
 
         $action = ($status) ? $this->t('sent') : $this->t('not sent');
         $operation = ($status) ? $this->t('scheduled email sent') : $this->t('scheduled email not sent');
-        $stat = ($status) ? self::EMAIL_SENT : self::EMAIL_NOT_SENT;
+        $stat = ($status) ? WebformScheduledEmailManagerInterface::EMAIL_SENT : WebformScheduledEmailManagerInterface::EMAIL_NOT_SENT;
       }
 
       $channel = ($webform->hasSubmissionLog()) ? 'webform_submission' : 'webform';
@@ -737,10 +737,10 @@ protected function cronSend(EntityInterface $entity = NULL, $handler_id = NULL,
    */
   public function stats(EntityInterface $entity = NULL, $handler_id = NULL) {
     return [
-      self::SUBMISSION_WAITING => $this->waiting($entity, $handler_id),
-      self::SUBMISSION_QUEUED => $this->queued($entity, $handler_id),
-      self::SUBMISSION_READY => $this->ready($entity, $handler_id),
-      self::SUBMISSION_TOTAL => $this->total($entity, $handler_id),
+      WebformScheduledEmailManagerInterface::SUBMISSION_WAITING => $this->waiting($entity, $handler_id),
+      WebformScheduledEmailManagerInterface::SUBMISSION_QUEUED => $this->queued($entity, $handler_id),
+      WebformScheduledEmailManagerInterface::SUBMISSION_READY => $this->ready($entity, $handler_id),
+      WebformScheduledEmailManagerInterface::SUBMISSION_TOTAL => $this->total($entity, $handler_id),
     ];
   }
 
@@ -748,21 +748,21 @@ public function stats(EntityInterface $entity = NULL, $handler_id = NULL) {
    * {@inheritdoc}
    */
   public function waiting(EntityInterface $entity = NULL, $handler_id = NULL) {
-    return $this->total($entity, $handler_id, self::SUBMISSION_WAITING);
+    return $this->total($entity, $handler_id, WebformScheduledEmailManagerInterface::SUBMISSION_WAITING);
   }
 
   /**
    * {@inheritdoc}
    */
   public function queued(EntityInterface $entity = NULL, $handler_id = NULL) {
-    return $this->total($entity, $handler_id, self::SUBMISSION_QUEUED);
+    return $this->total($entity, $handler_id, WebformScheduledEmailManagerInterface::SUBMISSION_QUEUED);
   }
 
   /**
    * {@inheritdoc}
    */
   public function ready(EntityInterface $entity = NULL, $handler_id = NULL) {
-    return $this->total($entity, $handler_id, self::SUBMISSION_READY);
+    return $this->total($entity, $handler_id, WebformScheduledEmailManagerInterface::SUBMISSION_READY);
   }
 
   /**
@@ -862,23 +862,23 @@ protected function addQueryConditions($query, WebformInterface $webform = NULL,
     }
 
     switch ($state) {
-      case self::SUBMISSION_SCHEDULE:
-      case self::SUBMISSION_UNSCHEDULE:
-      case self::SUBMISSION_RESCHEDULE:
-      case self::SUBMISSION_SEND:
+      case WebformScheduledEmailManagerInterface::SUBMISSION_SCHEDULE:
+      case WebformScheduledEmailManagerInterface::SUBMISSION_UNSCHEDULE:
+      case WebformScheduledEmailManagerInterface::SUBMISSION_RESCHEDULE:
+      case WebformScheduledEmailManagerInterface::SUBMISSION_SEND:
         $query->condition($prefix . 'state', $state);
         break;
 
-      case self::SUBMISSION_WAITING:
-        $query->condition($prefix . 'state', self::SUBMISSION_SEND, '<>');
+      case WebformScheduledEmailManagerInterface::SUBMISSION_WAITING:
+        $query->condition($prefix . 'state', WebformScheduledEmailManagerInterface::SUBMISSION_SEND, '<>');
         break;
 
-      case self::SUBMISSION_QUEUED:
-      case self::SUBMISSION_READY:
-        $query->condition($prefix . 'state', self::SUBMISSION_SEND);
+      case WebformScheduledEmailManagerInterface::SUBMISSION_QUEUED:
+      case WebformScheduledEmailManagerInterface::SUBMISSION_READY:
+        $query->condition($prefix . 'state', WebformScheduledEmailManagerInterface::SUBMISSION_SEND);
         $query->isNotNull($prefix . 'send');
-        $query->condition($prefix . 'send', time(), ($state === self::SUBMISSION_QUEUED) ? '>=' : '<');
-        $query->condition($prefix . 'state', self::SUBMISSION_SEND);
+        $query->condition($prefix . 'send', time(), ($state === WebformScheduledEmailManagerInterface::SUBMISSION_QUEUED) ? '>=' : '<');
+        $query->condition($prefix . 'state', WebformScheduledEmailManagerInterface::SUBMISSION_SEND);
         break;
     }
   }
diff --git a/web/modules/webform/modules/webform_scheduled_email/src/WebformScheduledEmailManagerInterface.php b/web/modules/webform/modules/webform_scheduled_email/src/WebformScheduledEmailManagerInterface.php
index 748d687cb3..24e82ef51f 100644
--- a/web/modules/webform/modules/webform_scheduled_email/src/WebformScheduledEmailManagerInterface.php
+++ b/web/modules/webform/modules/webform_scheduled_email/src/WebformScheduledEmailManagerInterface.php
@@ -283,11 +283,11 @@ public function delete(EntityInterface $entity);
    * @return array
    *   An associative array containing cron task stats.
    *   Includes:
-   *   - self::EMAIL_SCHEDULED
-   *   - self::EMAIL_RESCHEDULED
-   *   - self::EMAIL_ALREADY_SCHEDULED
-   *   - self::EMAIL_UNSCHEDULED
-   *   - self::EMAIL_SENT
+   *   - WebformScheduledEmailManagerInterface::EMAIL_SCHEDULED
+   *   - WebformScheduledEmailManagerInterface::EMAIL_RESCHEDULED
+   *   - WebformScheduledEmailManagerInterface::EMAIL_ALREADY_SCHEDULED
+   *   - WebformScheduledEmailManagerInterface::EMAIL_UNSCHEDULED
+   *   - WebformScheduledEmailManagerInterface::EMAIL_SENT
    */
   public function cron(EntityInterface $entity = NULL, $handler_id = NULL, $schedule_limit = 1000, $send_limit = NULL);
 
diff --git a/web/modules/webform/modules/webform_scheduled_email/templates/webform-handler-scheduled-email-summary.html.twig b/web/modules/webform/modules/webform_scheduled_email/templates/webform-handler-scheduled-email-summary.html.twig
index 04f8b47e19..b55d1ca89f 100644
--- a/web/modules/webform/modules/webform_scheduled_email/templates/webform-handler-scheduled-email-summary.html.twig
+++ b/web/modules/webform/modules/webform_scheduled_email/templates/webform-handler-scheduled-email-summary.html.twig
@@ -15,7 +15,6 @@
  * @ingroup themeable
  */
 #}
-
 <b>{{ 'Send on:'|t }}</b> {{ settings.send }}{% if settings.days %} {{ settings.days > 0 ? '+' : ''}}{{ settings.days }} {{ 'days'|t }}{% endif %}<br />
 <b>{{ 'Unschedule:'|t }}</b> {{ settings.unschedule ? 'Yes'|t : 'No'|t }}<br />
 <b>{{ 'Ignore past:'|t }}</b> {{ settings.ignore_past ? 'Yes'|t : 'No'|t }}<br />
diff --git a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml
index cda99a4449..caf44ae734 100644
--- a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml
+++ b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/config/install/webform.webform.test_handler_scheduled_email.yml
@@ -39,7 +39,7 @@ elements: |
       visible:
         ':input[name="send"]':
           value: other
-  
+
 css: ''
 javascript: ''
 settings:
@@ -51,7 +51,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -81,6 +81,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: true
   submission_views: {  }
@@ -106,11 +111,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/webform_scheduled_email_test.info.yml b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/webform_scheduled_email_test.info.yml
index abf7893a9b..6391cbd3c7 100644
--- a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/webform_scheduled_email_test.info.yml
+++ b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test/webform_scheduled_email_test.info.yml
@@ -1,13 +1,13 @@
-name: 'Webform scheduled email module tests'
+name: 'Webform Scheduled Email test'
 type: module
-description: 'Support module for webform schedule email that provides test forms.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform schedule email testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
   - 'webform:webform_scheduled_email'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/config/install/webform.webform.test_handler_scheduled_translate.yml b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/config/install/webform.webform.test_handler_scheduled_translate.yml
index c966044801..4341d6910c 100644
--- a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/config/install/webform.webform.test_handler_scheduled_translate.yml
+++ b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/config/install/webform.webform.test_handler_scheduled_translate.yml
@@ -20,7 +20,7 @@ elements: |
   value:
     '#type': textfield
     '#title': value
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: true
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/webform_scheduled_email_test_translation.info.yml b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/webform_scheduled_email_test_translation.info.yml
index 15d458f73e..c31398584f 100644
--- a/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/webform_scheduled_email_test_translation.info.yml
+++ b/web/modules/webform/modules/webform_scheduled_email/tests/modules/webform_scheduled_email_test_translation/webform_scheduled_email_test_translation.info.yml
@@ -1,8 +1,8 @@
-name: 'Webform scheduled email module translation tests'
+name: 'Webform Scheduled Email Translation test'
 type: module
-description: 'Support module for webform schedule email translation that provides test forms.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform schedule email translation testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:config_translation'
   - 'drupal:language'
@@ -10,7 +10,7 @@ dependencies:
   - 'webform:webform'
   - 'webform:webform_scheduled_email'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_scheduled_email/tests/src/Functional/WebformScheduledEmailTest.php b/web/modules/webform/modules/webform_scheduled_email/tests/src/Functional/WebformScheduledEmailTest.php
index 0562334dcc..e994985bb8 100644
--- a/web/modules/webform/modules/webform_scheduled_email/tests/src/Functional/WebformScheduledEmailTest.php
+++ b/web/modules/webform/modules/webform_scheduled_email/tests/src/Functional/WebformScheduledEmailTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform scheduled email handler.
  *
- * @group WebformScheduledEmail
+ * @group webform_scheduled_email
  */
 class WebformScheduledEmailTest extends WebformNodeBrowserTestBase {
 
@@ -338,7 +338,7 @@ public function testWebformScheduledEmail() {
     $this->assertRaw('The <em class="placeholder">Other</em> email will be sent immediately upon submission.');
 
     // Check 'Other' email is sent immediately via testing.
-    $this->drupalPostForm('/webform/test_handler_scheduled_email/test', ['send' => 'other', 'date[date]' => '2101-01-01'], t('Submit'));
+    $this->drupalPostForm('/webform/test_handler_scheduled_email/test', ['send' => 'other', 'date[date]' => '2101-01-01'], 'Submit');
     $this->assertEqual($scheduled_manager->total(), 0);
     $this->assertRaw('Webform submission from: Test: Handler: Test scheduled email</em> sent to <em class="placeholder">simpletest@example.com</em> from <em class="placeholder">Drupal</em> [<em class="placeholder">simpletest@example.com</em>');
     $this->assertRaw('Debug: Email: Other');
diff --git a/web/modules/webform/modules/webform_scheduled_email/tests/src/Functional/WebformScheduledEmailTranslationTest.php b/web/modules/webform/modules/webform_scheduled_email/tests/src/Functional/WebformScheduledEmailTranslationTest.php
index e241aa6d5b..9bc93eb5cd 100644
--- a/web/modules/webform/modules/webform_scheduled_email/tests/src/Functional/WebformScheduledEmailTranslationTest.php
+++ b/web/modules/webform/modules/webform_scheduled_email/tests/src/Functional/WebformScheduledEmailTranslationTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform scheduled email handler translation.
  *
- * @group WebformScheduledEmail
+ * @group webform_scheduled_email
  */
 class WebformScheduledEmailTranslationTest extends WebformNodeBrowserTestBase {
 
@@ -31,7 +31,7 @@ public function testWebformScheduledEmailTranslation() {
     /**************************************************************************/
 
     // Scheduled English email.
-    $this->drupalPostForm('/webform/' . $webform_schedule->id(), [], t('Submit'));
+    $this->drupalPostForm('/webform/' . $webform_schedule->id(), [], 'Submit');
 
     // Send email.
     $scheduled_manager->cron();
@@ -42,7 +42,7 @@ public function testWebformScheduledEmailTranslation() {
     $this->assertEqual($sent_email['body'], 'English Body' . PHP_EOL);
 
     // Scheduled Spanish email.
-    $this->drupalPostForm('/es/webform/' . $webform_schedule->id(), [], t('Submit'));
+    $this->drupalPostForm('/es/webform/' . $webform_schedule->id(), [], 'Submit');
 
     // Send email.
     $scheduled_manager->cron();
diff --git a/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.info.yml b/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.info.yml
index 082cbde487..6319809853 100644
--- a/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.info.yml
+++ b/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.info.yml
@@ -1,12 +1,12 @@
 name: 'Webform Scheduled Email Handler'
 type: module
-description: 'Extends the Webform email handler to allow emails to be scheduled.'
+description: 'Extends the Webform module''s email handler to allow emails to be scheduled.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.module b/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.module
index 883b39cd63..2f2e208d53 100644
--- a/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.module
+++ b/web/modules/webform/modules/webform_scheduled_email/webform_scheduled_email.module
@@ -39,7 +39,7 @@ function webform_scheduled_email_entity_predelete(EntityInterface $entity) {
 }
 
 /**
- * Implements hook_ENTITY_TYPE_delete().
+ * Implements hook_ENTITY_TYPE_delete() for webform entities.
  */
 function webform_scheduled_email_webform_delete(WebformInterface $webform) {
   /** @var \Drupal\webform_scheduled_email\WebformScheduledEmailManagerInterface $webform_scheduled_email_manager */
@@ -48,7 +48,7 @@ function webform_scheduled_email_webform_delete(WebformInterface $webform) {
 }
 
 /**
- * Implements hook_ENTITY_TYPE_delete().
+ * Implements hook_ENTITY_TYPE_delete() for webform_submission entities.
  */
 function webform_scheduled_email_webform_submission_delete(WebformSubmissionInterface $webform_submission) {
   /** @var \Drupal\webform_scheduled_email\WebformScheduledEmailManagerInterface $webform_scheduled_email_manager */
@@ -77,7 +77,7 @@ function webform_scheduled_email_theme() {
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for webform admin config handlers form.
  */
 function webform_scheduled_email_form_webform_admin_config_handlers_form_alter(&$form, FormStateInterface $form_state) {
   $form['webform_scheduled_email'] = [
diff --git a/web/modules/webform/modules/webform_share/css/webform_share.admin.css b/web/modules/webform/modules/webform_share/css/webform_share.admin.css
new file mode 100644
index 0000000000..e61ccb61c2
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/css/webform_share.admin.css
@@ -0,0 +1,18 @@
+/**
+ * @file
+ * Webform share admin styling.
+ */
+
+.webform-share-iframe-container {
+  border: 1px solid #ccc;
+  background-color: #eee;
+}
+
+.webform-share-admin-copy-message {
+  display: none;
+}
+
+.webform-share-admin-copy-message:before {
+  content: '✓';
+  font-size: 2em;
+}
diff --git a/web/modules/webform/modules/webform_share/css/webform_share.page.css b/web/modules/webform/modules/webform_share/css/webform_share.page.css
new file mode 100644
index 0000000000..6006030fda
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/css/webform_share.page.css
@@ -0,0 +1,33 @@
+/**
+ * @file
+ * Webform share (iframe source) page styling.
+ *
+ * @see page--webform-share.html.twig
+ */
+
+/**
+ * Fix IFrame not downsizing.
+ * @see http://davidjbradshaw.github.io/iframe-resizer/#iframe-not-downsizing
+ */
+html.webform-share-page-html {
+  height: auto !important; /** Ensure iframe resizing works as expected **/
+}
+
+/**
+ * Make sure the page is using a transparent background with margins.
+ */
+body.webform-share-page-body,
+[dir] body.webform-share-page-body {
+  background-color: transparent;
+  background-image: none;
+  margin: 0;
+  padding: 1em;
+}
+
+/**
+ * Make sure the page title is the default font color.
+ */
+body.webform-share-page-body .page-title {
+  margin-top: 0;
+  color: inherit;
+}
diff --git a/web/modules/webform/modules/webform_share/js/webform_share.admin.js b/web/modules/webform/modules/webform_share/js/webform_share.admin.js
new file mode 100644
index 0000000000..eaae5ec84e
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/js/webform_share.admin.js
@@ -0,0 +1,36 @@
+/**
+ * @file
+ * JavaScript behaviors for webform share admin.
+ */
+
+(function ($, Drupal) {
+
+  'use strict';
+
+  /**
+   * Webform share admin copy.
+   *
+   * @type {Drupal~behavior}
+   */
+  Drupal.behaviors.webformShareAdminCopy = {
+    attach: function (context) {
+      $(context).find('.js-webform-share-admin-copy').once('webform-share-admin-copy').each(function () {
+        var $container = $(this);
+        var $textarea = $container.find('textarea');
+        var $button = $container.find(':submit, :button');
+        var $message = $container.find('.webform-share-admin-copy-message');
+        // Copy code from textarea to the clipboard.
+        // @see https://stackoverflow.com/questions/37658524/copying-text-of-textarea-in-clipboard-when-button-is-clicked
+        $button.click(function () {
+          $textarea.select();
+          document.execCommand('copy');
+          $message.show().delay(1500).fadeOut('slow');
+          $button.focus();
+          Drupal.announce(Drupal.t('Code copied to clipboard…'));
+          return false;
+        });
+      });
+    }
+  };
+
+})(jQuery, Drupal);
diff --git a/web/modules/webform/modules/webform_share/src/Access/WebformShareAccess.php b/web/modules/webform/modules/webform_share/src/Access/WebformShareAccess.php
new file mode 100644
index 0000000000..899f4d4458
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/src/Access/WebformShareAccess.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Drupal\webform_share\Access;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\node\NodeInterface;
+use Drupal\webform\WebformInterface;
+use Drupal\webform_node\Access\WebformNodeAccess;
+
+/**
+ * Defines the custom access control handler for webform sharing.
+ */
+class WebformShareAccess {
+
+  /**
+   * Check whether the webform can be shared and it is not a template.
+   *
+   * @param \Drupal\webform\WebformInterface $webform
+   *   A webform.
+   *
+   * @return \Drupal\Core\Access\AccessResultInterface
+   *   The access result.
+   */
+  public static function checkAccess(WebformInterface $webform) {
+    $share = $webform->getSetting('share', TRUE);
+    $share_node = \Drupal::moduleHandler()->moduleExists('webform_node')
+      && $webform->getSetting('share_node', TRUE);
+    $template = $webform->isTemplate();
+    return AccessResult::allowedIf(($share || $share_node) && !$template)
+      ->addCacheTags(['config:webform.settings'])
+      ->addCacheableDependency($webform);
+  }
+
+  /**
+   * Check whether the webform node can be shared.
+   *
+   * @param string $operation
+   *   Operation being performed.
+   * @param string $entity_access
+   *   Entity access rule that needs to be checked.
+   * @param \Drupal\node\NodeInterface $node
+   *   A node.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   Run access checks for this account.
+   *
+   * @return \Drupal\Core\Access\AccessResultInterface
+   *   The access result.
+   */
+  public static function checkNodeAccess($operation, $entity_access, NodeInterface $node, AccountInterface $account) {
+    /** @var \Drupal\webform\WebformEntityReferenceManagerInterface $entity_reference_manager */
+    $entity_reference_manager = \Drupal::service('webform.entity_reference_manager');
+    $webform = $entity_reference_manager->getWebform($node);
+
+    // Check that the node has a valid webform reference.
+    if (!$webform) {
+      return AccessResult::forbidden()->addCacheableDependency($node);
+    }
+
+    $share = $webform->getSetting('share_node', TRUE);
+    if (!$share) {
+      return AccessResult::forbidden()
+        ->addCacheTags(['config:webform.settings'])
+        ->addCacheableDependency($node)
+        ->addCacheableDependency($webform);
+    }
+
+    return WebformNodeAccess::checkAccess($operation, $entity_access, $node, NULL, $account);
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/src/Controller/WebformShareController.php b/web/modules/webform/modules/webform_share/src/Controller/WebformShareController.php
new file mode 100644
index 0000000000..b7c5de8b15
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/src/Controller/WebformShareController.php
@@ -0,0 +1,231 @@
+<?php
+
+namespace Drupal\webform_share\Controller;
+
+use Drupal\Core\Cache\CacheableResponse;
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\Core\Url;
+use Drupal\webform\Element\WebformMessage;
+use Drupal\webform\WebformMessageManagerInterface;
+use Drupal\webform\WebformRequestInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Provides route responses for webform share page, script, and embed.
+ */
+class WebformShareController extends ControllerBase {
+
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * The webform message manager.
+   *
+   * @var \Drupal\webform\WebformMessageManagerInterface
+   */
+  protected $messageManager;
+
+  /**
+   * The webform request handler.
+   *
+   * @var \Drupal\webform\WebformRequestInterface
+   */
+  protected $requestHandler;
+
+  /**
+   * Constructs a WebformShareController object.
+   *
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
+   * @param \Drupal\webform\WebformMessageManagerInterface $message_manager
+   *   The webform message manager.
+   * @param \Drupal\webform\WebformRequestInterface $request_handler
+   *   The webform request handler.
+   */
+  public function __construct(RendererInterface $renderer, WebformMessageManagerInterface $message_manager, WebformRequestInterface $request_handler) {
+    $this->renderer = $renderer;
+    $this->messageManager = $message_manager;
+    $this->requestHandler = $request_handler;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('renderer'),
+      $container->get('webform.message_manager'),
+      $container->get('webform.request')
+    );
+  }
+
+  /**
+   * Returns a webform to be shared as the page of an iframe.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The current request object.
+   * @param string|null $library
+   *   The iframe JavaScript library.
+   * @param string|null $version
+   *   The iframe JavaScript library version.
+   *
+   * @return array
+   *   The webform rendered in a page template with only the content.
+   *
+   * @see \Drupal\webform_share\Theme\WebformShareThemeNegotiator
+   * @see page--webform-share.html.twig
+   * @see webform_share.libraries.yml
+   */
+  public function page(Request $request, $library = NULL, $version = NULL) {
+    $webform = $this->requestHandler->getCurrentWebform();
+    $source_entity = $this->requestHandler->getCurrentSourceEntity(['webform']);
+
+    $build = [];
+    // Webform.
+    $build['webform'] = [
+      '#type' => 'webform',
+      '#webform' => $webform,
+      '#source_entity' => $source_entity,
+      '#prefix' => '<div class="webform-share-submission-form">',
+      '#suffix' => '</div>',
+    ];
+    // Attachments.
+    $build['#attached']['library'][] = 'webform_share/webform_share.page';
+    if ($library && $version) {
+      $build['#attached']['library'][] = "webform_share/libraries.$library.$version";
+    }
+    // Add setting notifying AjaxCommand that this page is shared via an
+    // embeddded iframe.
+    // @see Drupal.AjaxCommands.prototype.webformRefresh
+    $build['#attached']['drupalSettings']['webform_share']['page'] = TRUE;
+    return $build;
+  }
+
+  /**
+   * Returns a webform to be shared using (java)script.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The current request object.
+   * @param string|null $library
+   *   The iframe JavaScript library.
+   * @param string|null $version
+   *   The iframe JavaScript library version.
+   *
+   * @return array
+   *   The webform rendered in a page template with only the content.
+   *
+   * @see \Drupal\webform_share\Theme\WebformShareThemeNegotiator
+   * @see page--webform-share.html.twig
+   * @see webform_share.libraries.yml
+   */
+  public function script(Request $request, $library = NULL, $version = NULL) {
+    $webform = $this->requestHandler->getCurrentWebform();
+    $source_entity = $this->requestHandler->getCurrentSourceEntity(['webform']);
+
+    $build = [
+      '#type' => 'webform_share_iframe',
+      '#webform' => $webform,
+      '#source_entity' => $source_entity,
+      '#javascript' => TRUE,
+      '#query' => $request->query->all(),
+    ];
+    $iframe = $this->renderer->renderPlain($build);
+
+    $content = 'document.write(' . json_encode($iframe) . ');';
+    return new CacheableResponse($content, 200, ['Content-Type' => 'text/javascript']);
+  }
+
+  /**
+   * Returns a preview of a webform to be shared.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The current request object.
+   *
+   * @return array
+   *   A render array containing a review of the webform to be shared.
+   */
+  public function preview(Request $request) {
+    $webform = $this->requestHandler->getCurrentWebform();
+    $source_entity = $this->requestHandler->getCurrentSourceEntity(['webform']);
+
+    $build = [];
+    if ($this->currentUser()->isAuthenticated()) {
+      $build['message'] = [
+        '#type' => 'webform_message',
+        '#message_message' => [
+          'message' => [
+            '#markup' => $this->t('To test anonymous user access to the below embedded webform, please log out or open the below link in a new private or incognito window.'),
+            '#suffix' => '<br/>',
+          ],
+          'link' => [
+            '#type' => 'link',
+            '#url' => Url::fromRoute('<current>'),
+            '#title' => Url::fromRoute('<current>')->setAbsolute()->toString(),
+          ],
+        ],
+        '#message_type' => 'info',
+        '#message_close' => TRUE,
+        '#message_storage' => WebformMessage::STORAGE_SESSION,
+      ];
+    }
+    $build['preview'] = [
+      '#type' => 'container',
+      '#attributes' => ['class' => ['webform-share-iframe-container']],
+    ];
+    $build['preview']['iframe'] = [
+      '#type' => 'webform_share_iframe',
+      '#webform' => $webform,
+      '#source_entity' => $source_entity,
+      '#javascript' => TRUE,
+      '#options' => ['log' => TRUE],
+      '#query' => $request->query->all(),
+    ];
+    $build['#attached']['library'][] = 'webform_share/webform_share.admin';
+    return $build;
+  }
+
+  /**
+   * Returns a test of a webform to be shared.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The current request object.
+   *
+   * @return array
+   *   A render array containing a review of the webform to be shared.
+   */
+  public function test(Request $request) {
+    $webform = $this->requestHandler->getCurrentWebform();
+    $source_entity = $this->requestHandler->getCurrentSourceEntity(['webform']);
+
+    $build = [];
+    $build['message'] = [
+      '#type' => 'webform_message',
+      '#message_message' => $this->messageManager->get(WebformMessageManagerInterface::SUBMISSION_TEST),
+      '#message_type' => 'warning',
+      '#message_close' => TRUE,
+      '#message_storage' => WebformMessage::STORAGE_SESSION,
+    ];
+    $build['test'] = [
+      '#type' => 'container',
+      '#attributes' => ['class' => ['webform-share-iframe-container']],
+    ];
+    $build['test']['iframe'] = [
+      '#type' => 'webform_share_iframe',
+      '#webform' => $webform,
+      '#source_entity' => $source_entity,
+      '#test' => TRUE,
+      '#javascript' => TRUE,
+      '#options' => ['log' => TRUE],
+      '#query' => $request->query->all(),
+    ];
+    $build['#attached']['library'][] = 'webform_share/webform_share.admin';
+    return $build;
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/src/Element/WebformShareIframe.php b/web/modules/webform/modules/webform_share/src/Element/WebformShareIframe.php
new file mode 100644
index 0000000000..a2ba6c7e09
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/src/Element/WebformShareIframe.php
@@ -0,0 +1,126 @@
+<?php
+
+namespace Drupal\webform_share\Element;
+
+use Drupal\Core\Render\Element\RenderElement;
+use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Url;
+use Drupal\webform\Plugin\WebformSourceEntity\QueryStringWebformSourceEntity;
+
+/**
+ * Provides a render element that createa an iframe to share a webform.
+ *
+ * @RenderElement("webform_share_iframe")
+ */
+class WebformShareIframe extends RenderElement implements TrustedCallbackInterface {
+
+  /**
+   * The JavaScript iframe library.
+   */
+  const LIBRARY = 'iframe-resizer';
+
+  /**
+   * The JavaScript iframe library version.
+   */
+  const VERSION = '4.2.10';
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInfo() {
+    $class = get_class($this);
+    return [
+      '#webform' => NULL,
+      '#source_entity' => NULL,
+      '#javascript' => FALSE,
+      '#script' => '//cdn.jsdelivr.net/gh/davidjbradshaw/iframe-resizer@' . static::VERSION . '/js/iframeResizer.min.js',
+      '#query' => [],
+      '#options' => [],
+      '#test' => [],
+      '#theme' => 'webform_share_iframe',
+      '#pre_render' => [
+        [$class, 'preRenderWebformShareIframe'],
+      ],
+    ];
+  }
+
+  /**
+   * Webform share iframe element pre render callback.
+   */
+  public static function preRenderWebformShareIframe($element) {
+    /** @var \Drupal\webform\WebformInterface $webform */
+    $webform = $element['#webform'];
+
+    /** @var \Drupal\Core\Entity\EntityInterface $source_entity */
+    $source_entity = $element['#source_entity'];
+
+    // Get iframe src route information and attributes.
+    if ($element['#javascript']) {
+      // Set JavaScript iframe.
+      // @see https://github.com/davidjbradshaw/iframe-resizer
+      $route_name = 'entity.webform.share_page.javascript';
+      $route_parameters = [
+        'webform' => $webform->id(),
+        'library' => static::LIBRARY,
+        'version' => static::VERSION,
+      ];
+      $attributes = [
+        'style' => 'width:1px;min-width:100%',
+      ];
+    }
+    else {
+      // Set static iframe.
+      $route_name = 'entity.webform.share_page';
+      $route_parameters = [
+        'webform' => $webform->id(),
+      ];
+      $attributes = [
+        'style' => 'width:100%;height:600px;border:none',
+      ];
+    }
+
+    $route_options = QueryStringWebformSourceEntity::getRouteOptionsQuery($source_entity);
+    $route_options += ['query' => []];
+    // Append prepopulate and variant query to route options.
+    if ($element['#query']) {
+      $route_options['query'] += $element['#query'];
+    }
+    // Append ?_webform_test={webform} to route options.
+    if ($element['#test']) {
+      $route_options['query']['_webform_test'] = $webform->id();
+    }
+    if (empty($route_options['query'])) {
+      unset($route_options['query']);
+    }
+
+    // Get iframe URL.
+    $url = Url::fromRoute($route_name, $route_parameters, $route_options);
+
+    // Get iframe src and title.
+    $src = preg_replace('#^https?:#', '', $url->setAbsolute()->toString());
+    $title = $webform->label() . ' | ' . \Drupal::config('system.site')->get('name');
+
+    $element += ['#attributes' => []];
+    $element['#attributes'] += [
+      'src' => $src,
+      'title' => $title,
+      'class' => [],
+      'frameborder' => '0',
+      'allow' => 'geolocation; microphone; camera',
+      'allowtransparency' => 'true',
+      'allowfullscreen' => 'true',
+    ] + $attributes;
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function trustedCallbacks() {
+    return [
+      'preRenderWebformShareIframe',
+    ];
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/src/Element/WebformShareScript.php b/web/modules/webform/modules/webform_share/src/Element/WebformShareScript.php
new file mode 100644
index 0000000000..6f256841df
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/src/Element/WebformShareScript.php
@@ -0,0 +1,67 @@
+<?php
+
+namespace Drupal\webform_share\Element;
+
+use Drupal\Core\Render\Element\RenderElement;
+use Drupal\Core\Security\TrustedCallbackInterface;
+use Drupal\Core\Url;
+use Drupal\webform\Plugin\WebformSourceEntity\QueryStringWebformSourceEntity;
+
+/**
+ * Provides a render element that creates a <script> tag to share a webform.
+ *
+ * @RenderElement("webform_share_script")
+ */
+class WebformShareScript extends RenderElement implements TrustedCallbackInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getInfo() {
+    $class = get_class($this);
+    return [
+      '#webform' => NULL,
+      '#source_entity' => NULL,
+      '#query' => [],
+      '#theme' => 'webform_share_script',
+      '#pre_render' => [
+        [$class, 'preRenderWebformShareScript'],
+      ],
+    ];
+  }
+
+  /**
+   * Webform share iframe element pre render callback.
+   */
+  public static function preRenderWebformShareScript($element) {
+    /** @var \Drupal\webform\WebformInterface $webform */
+    $webform = $element['#webform'];
+
+    /** @var \Drupal\Core\Entity\EntityInterface $source_entity */
+    $source_entity = $element['#source_entity'];
+
+    $route_name = 'entity.webform.share_script';
+    $route_parameters = ['webform' => $webform->id()];
+    $route_options = QueryStringWebformSourceEntity::getRouteOptionsQuery($source_entity);
+    // Append prepopulate and variant query to route options.
+    if ($element['#query']) {
+      $route_options += ['query' => []];
+      $route_options['query'] += $element['#query'];
+    }
+    $url = Url::fromRoute($route_name, $route_parameters, $route_options);
+    $script = preg_replace('#^https?:#', '', $url->setAbsolute()->toString());
+    $element['#script'] = $script;
+
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function trustedCallbacks() {
+    return [
+      'preRenderWebformShareScript',
+    ];
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/src/EventSubscriber/WebformShareEventSubscriber.php b/web/modules/webform/modules/webform_share/src/EventSubscriber/WebformShareEventSubscriber.php
new file mode 100644
index 0000000000..5f7fc22066
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/src/EventSubscriber/WebformShareEventSubscriber.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Drupal\webform_share\EventSubscriber;
+
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\webform_share\WebformShareHelper;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+/**
+ * Event subscriber to allow webform to be shared via an iframe.
+ */
+class WebformShareEventSubscriber implements EventSubscriberInterface {
+
+  /**
+   * The current route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
+   * Constructs a WebformShareEventSubscriber object.
+   *
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The current route match.
+   */
+  public function __construct(RouteMatchInterface $route_match) {
+    $this->routeMatch = $route_match;
+  }
+
+  /**
+   * Remove 'X-Frame-Options' from the response header for shared webforms.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
+   *   The response event.
+   */
+  public function onResponse(FilterResponseEvent $event) {
+    if (!WebformShareHelper::isPage($this->routeMatch)) {
+      return;
+    }
+
+    $response = $event->getResponse();
+    $response->headers->remove('X-Frame-Options');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[KernelEvents::RESPONSE] = ['onResponse'];
+    return $events;
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/src/Form/WebformShareEmbedForm.php b/web/modules/webform/modules/webform_share/src/Form/WebformShareEmbedForm.php
new file mode 100644
index 0000000000..7252ec1340
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/src/Form/WebformShareEmbedForm.php
@@ -0,0 +1,159 @@
+<?php
+
+namespace Drupal\webform_share\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\webform\Element\WebformMessage;
+use Drupal\webform\WebformRequestInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Webform share embed form.
+ */
+class WebformShareEmbedForm extends FormBase {
+
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * Webform request handler.
+   *
+   * @var \Drupal\webform\WebformRequestInterface
+   */
+  protected $requestHandler;
+
+  /**
+   * WebformEntityReferenceLinkFormatter constructor.
+   *
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
+   * @param \Drupal\webform\WebformRequestInterface $request_handler
+   *   The webform request handler.
+   */
+  public function __construct(RendererInterface $renderer, WebformRequestInterface $request_handler) {
+    $this->renderer = $renderer;
+    $this->requestHandler = $request_handler;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('renderer'),
+      $container->get('webform.request')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId() {
+    return 'webform_share_embed_form';
+  }
+
+  /**
+   * Form constructor.
+   *
+   * @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 array
+   *   The form structure.
+   */
+  public function buildForm(array $form, FormStateInterface $form_state) {
+    $webform = $this->requestHandler->getCurrentWebform();
+    $source_entity = $this->requestHandler->getCurrentSourceEntity(['webform']);
+
+    $form['info'] = [
+      '#type' => 'webform_message',
+      '#message_message' => $this->t('Choose how you want to embed the webform and then copy-n-paste the below code snippet directly into the HTML source of any webpage.'),
+      '#message_type' => 'info',
+      '#message_close' => TRUE,
+      '#message_storage' => WebformMessage::STORAGE_SESSION,
+    ];
+    $form['type'] = [
+      '#type' => 'radios',
+      '#title' => $this->t('Embed type'),
+      '#title_display' => 'invisible',
+      '#options' => [
+        'script' => $this->t('JavaScript -- The embedded webform will be inserted using JavaScript.'),
+        'resizing' => $this->t('Resizing iframe -- The embedded webform will be responsive and adjusted to fit within the page using an iframe and JavaScript.'),
+        'fixed' => $this->t('Fixed iframe -- The embedded webform will be a fixed size on the page using an iframe with a scrollbar.'),
+      ],
+      '#options_display' => 'buttons',
+      '#options_description_display' => 'help',
+      '#default_value' => 'script',
+    ];
+    $types = [
+      'script' => [
+        'type' => 'script',
+        'title' => $this->t('JavaScript code'),
+      ],
+      'resizing' => [
+        'type' => 'iframe',
+        'title' => $this->t('Resizing iframe code'),
+        'javascript' => TRUE,
+      ],
+      'fixed' => [
+        'type' => 'iframe',
+        'title' => $this->t('Fixed iframe code'),
+      ],
+    ];
+    foreach ($types as $type => $item) {
+      $build = [
+        '#type' => 'webform_share_' . $item['type'],
+        '#webform' => $webform,
+        '#source_entity' => $source_entity,
+        '#query' => $this->getRequest()->query->all(),
+      ];
+      if (!empty($item['javascript'])) {
+        $build['#javascript'] = $item['javascript'];
+      }
+      $code = trim((string) $this->renderer->renderPlain($build));
+
+      $form[$type] = [
+        '#type' => 'container',
+        '#attributes' => ['class' => ['js-webform-share-admin-copy']],
+        '#states' => [
+          'visible' => [':input[name="type"]' => ['value' => $type]],
+        ],
+      ];
+      $form[$type]['code'] = [
+        '#type' => 'webform_codemirror',
+        '#title' => $item['title'],
+        '#mode' => 'html',
+        '#default_value' => $code,
+      ];
+      $form[$type]['copy'] = [
+        '#type' => 'button',
+        '#value' => $this->t('Copy code'),
+      ];
+      $form[$type]['message'] = [
+        '#markup' => $this->t('Code copied to clipboard…'),
+        '#prefix' => '<strong class="webform-share-admin-copy-message">',
+        '#suffix' => '</strong>',
+      ];
+    }
+
+    $form['#attached']['library'][] = 'webform_share/webform_share.admin';
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state) {
+    // Do nothing.
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/src/Routing/WebformShareRouteSubscriber.php b/web/modules/webform/modules/webform_share/src/Routing/WebformShareRouteSubscriber.php
new file mode 100644
index 0000000000..478297104d
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/src/Routing/WebformShareRouteSubscriber.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Drupal\webform_share\Routing;
+
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Routing\RouteSubscriberBase;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * Remove webform share routes.
+ */
+class WebformShareRouteSubscriber extends RouteSubscriberBase {
+
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * Constructs a WebformShareRouteSubscriber object.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   */
+  public function __construct(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function alterRoutes(RouteCollection $collection) {
+    if (!$this->moduleHandler->moduleExists('webform_node')) {
+      $collection->remove('entity.node.webform.share_embed');
+      $collection->remove('entity.node.webform.share_preview');
+      $collection->remove('entity.node.webform.share_test');
+    }
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/src/Theme/WebformShareThemeNegotiator.php b/web/modules/webform/modules/webform_share/src/Theme/WebformShareThemeNegotiator.php
new file mode 100644
index 0000000000..2e36e42754
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/src/Theme/WebformShareThemeNegotiator.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Drupal\webform_share\Theme;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
+use Drupal\Core\Theme\ThemeNegotiatorInterface;
+use Drupal\webform_share\WebformShareHelper;
+
+/**
+ * Sets the theme for the webform share page.
+ *
+ * @see \Drupal\webform_share\Controller\WebformShareController::page
+ * @see page--webform-share.html.twig
+ */
+class WebformShareThemeNegotiator implements ThemeNegotiatorInterface {
+
+  /**
+   * The system theme config object.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * Constructs a WebformShareThemeNegotiator object.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory.
+   */
+  public function __construct(ConfigFactoryInterface $config_factory) {
+    $this->configFactory = $config_factory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applies(RouteMatchInterface $route_match) {
+    return WebformShareHelper::isPage($route_match);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function determineActiveTheme(RouteMatchInterface $route_match) {
+    /** @var \Drupal\webform\WebformInterface $webform */
+    $webform = $route_match->getParameter('webform');
+    return $webform->getSetting('share_theme_name', TRUE)
+      ?: $this->configFactory->get('system.theme')->get('default');
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/src/WebformShareHelper.php b/web/modules/webform/modules/webform_share/src/WebformShareHelper.php
new file mode 100644
index 0000000000..a3a99d59cd
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/src/WebformShareHelper.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Drupal\webform_share;
+
+use Drupal\Core\Routing\RouteMatchInterface;
+
+/**
+ * Webform share helper class.
+ */
+class WebformShareHelper {
+
+  /**
+   * Determine if the current page is a webform share page.
+   *
+   * @return bool
+   *   TRUE if the current page is a webform share page.
+   */
+  public static function isPage(RouteMatchInterface $route_match = NULL) {
+    $route_match = $route_match ?: \Drupal::routeMatch();
+    return (strpos($route_match->getRouteName(), 'entity.webform.share_page') === 0);
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/src/WebformSharePreRender.php b/web/modules/webform/modules/webform_share/src/WebformSharePreRender.php
new file mode 100644
index 0000000000..6f54c937f3
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/src/WebformSharePreRender.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Drupal\webform_share;
+
+use Drupal\Core\Security\TrustedCallbackInterface;
+
+/**
+ * Implements trusted prerender callbacks for the Webform share module.
+ *
+ * @internal
+ */
+class WebformSharePreRender implements TrustedCallbackInterface {
+
+  /**
+   * Prerender callback for page.
+   */
+  public static function page($element) {
+    if (!WebformShareHelper::isPage()) {
+      return $element;
+    }
+
+    // Remove all theme wrappers from the page template.
+    $element['#theme_wrappers'] = [];
+    return $element;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function trustedCallbacks() {
+    return ['page'];
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/templates/html--webform-share.html.twig b/web/modules/webform/modules/webform_share/templates/html--webform-share.html.twig
new file mode 100644
index 0000000000..0144785b2c
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/templates/html--webform-share.html.twig
@@ -0,0 +1,20 @@
+{#
+/**
+ * @file
+ * Webform share html template override.
+ */
+#}
+<!DOCTYPE html>
+<html{{ html_attributes }}>
+  <head>
+    <head-placeholder token="{{ placeholder_token }}">
+    <title>{{ head_title|safe_join(' | ') }}</title>
+    <css-placeholder token="{{ placeholder_token }}">
+    <js-placeholder token="{{ placeholder_token }}">
+  </head>
+  <body{{ attributes }}>
+    {{ page }}
+    <js-bottom-placeholder token="{{ placeholder_token }}">
+  </body>
+</html>
+
diff --git a/web/modules/webform/modules/webform_share/templates/page--webform-share.html.twig b/web/modules/webform/modules/webform_share/templates/page--webform-share.html.twig
new file mode 100644
index 0000000000..7ec0efb934
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/templates/page--webform-share.html.twig
@@ -0,0 +1,7 @@
+{#
+/**
+ * @file
+ * Webform share page template override.
+ */
+#}
+{{ page.content }}
diff --git a/web/modules/webform/modules/webform_share/templates/webform-share-iframe.html.twig b/web/modules/webform/modules/webform_share/templates/webform-share-iframe.html.twig
new file mode 100644
index 0000000000..6937d64436
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/templates/webform-share-iframe.html.twig
@@ -0,0 +1,25 @@
+{#
+/**
+ * @file
+ * Default theme implementation of an iframe used to share a webform.
+ *
+ * Available variables:
+ * - attributes: HTML attributes for the iframe element.
+ * - javascript: Flag to include JavaScript.
+ * - option: JavaScript options.
+ *
+ * @see template_preprocess_webform_share_iframe()
+ *
+ * @ingroup themeable
+ */
+#}
+{%
+  set classes = [
+    'webform-share-iframe',
+  ]
+%}
+<iframe{{ attributes.addClass(classes) }}></iframe>
+{% if javascript %}
+<script src="{{ script }}"></script>
+<script>iFrameResize({{ options }}, '.webform-share-iframe');</script>
+{% endif %}
diff --git a/web/modules/webform/modules/webform_share/templates/webform-share-script.html.twig b/web/modules/webform/modules/webform_share/templates/webform-share-script.html.twig
new file mode 100644
index 0000000000..1865cde024
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/templates/webform-share-script.html.twig
@@ -0,0 +1,12 @@
+{#
+/**
+ * @file
+ * Default theme implementation of a <script> tag used to share a webform.
+ *
+ * Available variables:
+ * - script: The URL of the JavaScript.
+ *
+ * @ingroup themeable
+ */
+#}
+<script src="{{ script }}"></script>
diff --git a/web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareNodeTest.php b/web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareNodeTest.php
new file mode 100644
index 0000000000..73b1a2d8d8
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareNodeTest.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace Drupal\Tests\webform_share\Functional;
+
+use Drupal\Tests\webform_node\Functional\WebformNodeBrowserTestBase;
+use Drupal\webform\Entity\Webform;
+
+/**
+ * Webform share node test.
+ *
+ * @group webform_share
+ */
+class WebformShareNodeTest extends WebformNodeBrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'webform',
+    'webform_node',
+    'webform_share',
+  ];
+
+  /**
+   * Test share.
+   */
+  public function testShare() {
+    global $base_url;
+
+    $config = \Drupal::configFactory()->getEditable('webform.settings');
+
+    /** @var \Drupal\webform\WebformInterface $webform */
+    $webform = Webform::load('contact');
+    $node = $this->createWebformNode('contact');
+    $nid = $node->id();
+
+    /** @var \Drupal\Core\Render\RendererInterface $render */
+    $renderer = \Drupal::service('renderer');
+
+    $this->drupalLogin($this->rootUser);
+
+    /**************************************************************************/
+
+    // Check share page access denied.
+    $this->drupalGet('/webform/contact/share');
+    $this->assertResponse(403);
+
+    // Check webform node share page access denied.
+    $this->drupalGet("/node/$nid/webform/share");
+    $this->assertResponse(403);
+
+    // Check webform node preview access denied.
+    $this->drupalGet("/node/$nid/webform/share/preview");
+    $this->assertResponse(403);
+
+    // Enable enable share for all webform node.
+    $config->set('settings.default_share_node', TRUE)->save();
+
+    // Check share enabled for all webform nodes.
+    $this->drupalGet('/webform/contact/share');
+    $this->assertResponse(200);
+    $this->drupalGet("/node/$nid/webform/share");
+    $this->assertResponse(200);
+    $this->drupalGet("/node/$nid/webform/share/preview");
+    $this->assertResponse(200);
+
+    // Enable disable share for all webform nodes.
+    $config->set('settings.default_share_node', FALSE)->save();
+
+    // Enable share for contact webform node.
+    $webform->setSetting('share_node', TRUE)->save();
+
+    // Check share enabled for a single webform.
+    $this->drupalGet('/webform/contact/share');
+    $this->assertResponse(200);
+    $this->drupalGet("/node/$nid/webform/share");
+    $this->assertResponse(200);
+    $this->drupalGet("/node/$nid/webform/share/preview");
+    $this->assertResponse(200);
+
+    // Check webform node script tag.
+    $build = [
+      '#type' => 'webform_share_script',
+      '#webform' => $webform,
+      '#source_entity' => $node,
+    ];
+    $actual_script_tag = $renderer->renderPlain($build);
+
+    $src = $base_url . "/webform/contact/share.js?source_entity_type=node&amp;source_entity_id=$nid";
+    $src = preg_replace('#^https?:#', '', $src);
+    $expected_script_tag = '<script src="' . $src . '"></script>' . PHP_EOL;
+
+    $this->assertEqual($expected_script_tag, $actual_script_tag);
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareTest.php b/web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareTest.php
new file mode 100644
index 0000000000..cbe1de5408
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareTest.php
@@ -0,0 +1,161 @@
+<?php
+
+namespace Drupal\Tests\webform_share\Functional;
+
+use Drupal\Tests\webform\Functional\WebformBrowserTestBase;
+use Drupal\webform\Entity\Webform;
+use Drupal\webform_share\Element\WebformShareIframe;
+
+/**
+ * Webform share test.
+ *
+ * @group webform_share
+ */
+class WebformShareTest extends WebformBrowserTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'webform',
+    'webform_share',
+  ];
+
+  /**
+   * Test share.
+   */
+  public function testShare() {
+    global $base_url;
+
+    $library = WebformShareIframe::LIBRARY;
+    $version = WebformShareIframe::VERSION;
+
+    $config = \Drupal::configFactory()->getEditable('webform.settings');
+
+    /** @var \Drupal\webform\WebformInterface $webform */
+    $webform = Webform::load('contact');
+
+    /** @var \Drupal\Core\Render\RendererInterface $render */
+    $renderer = \Drupal::service('renderer');
+
+    $this->drupalLogin($this->rootUser);
+
+    /**************************************************************************/
+
+    // Check share page access denied.
+    $this->drupalGet('/webform/contact/share');
+    $this->assertResponse(403);
+
+    // Check share script access denied.
+    $this->drupalGet('/webform/contact/share.js');
+    $this->assertResponse(403);
+
+    // Check share page with javascript access denied.
+    $this->drupalGet("/webform/contact/share/$library/$version");
+    $this->assertResponse(403);
+
+    // Check share preview access denied.
+    $this->drupalGet('/admin/structure/webform/manage/contact/share/preview');
+    $this->assertResponse(403);
+
+    // Enable enable share for all webforms.
+    $config->set('settings.default_share', TRUE)->save();
+
+    // Check share enabled for all webforms.
+    $this->drupalGet('/webform/contact/share');
+    $this->assertResponse(200);
+    $this->drupalGet('/webform/contact/share.js');
+    $this->assertResponse(200);
+    $this->drupalGet("/webform/contact/share/$library/$version");
+    $this->assertResponse(200);
+    $this->drupalGet('/admin/structure/webform/manage/contact/share/preview');
+    $this->assertResponse(200);
+
+    // Enable disable share for all webforms.
+    $config->set('settings.default_share', FALSE)->save();
+
+    // Enable share for contact webform.
+    $webform->setSetting('share', TRUE)->save();
+
+    // Check share enabled for a single webform.
+    $this->drupalGet('/webform/contact/share');
+    $this->assertResponse(200);
+    $this->drupalGet('/webform/contact/share.js');
+    $this->assertResponse(200);
+    $this->drupalGet("/webform/contact/share/$library/$version");
+    $this->assertResponse(200);
+    $this->drupalGet('/admin/structure/webform/manage/contact/share/preview');
+    $this->assertResponse(200);
+
+    // Check that query string parameters are included in embed/iframe code.
+    $this->drupalGet('/admin/structure/webform/manage/contact/share', ['query' => ['test' => '123']]);
+    $this->assertRaw("/webform/contact/share?test=123");
+    $this->assertRaw('/webform/contact/share.js?test=123');
+    $this->assertRaw("/webform/contact/share/$library/$version?test=123");
+
+    // Check that iframe page is using the default theme.
+    $this->drupalGet('/webform/contact/share');
+    $this->assertRaw('"theme":"' . \Drupal::config('system.theme')->get('default') . '"');
+
+    // Enable the bartik theme and apply to share page.
+    \Drupal::service('theme_installer')->install(['bartik']);
+    $webform->setSetting('share_theme_name', 'bartik')->save();
+
+    // Check that iframe page is using the bartik theme.
+    $this->drupalGet('/webform/contact/share');
+    $this->assertRaw('"theme":"bartik"');
+
+    // Get the share page.
+    $this->drupalGet('/webform/contact/share');
+
+    // Check iframe page html has .webform-share-page-html class.
+    $this->assertCssSelect('html.webform-share-page-html');
+
+    // Check iframe page body has .webform-share-page-body class.
+    $this->assertCssSelect('body.webform-share-page-body');
+
+    // Check page title.
+    $this->assertRaw('<h1 class="title page-title">Contact</h1>');
+
+    // Disable the bartik and add custom body attributes.
+    $webform
+      ->setSetting('share_theme_name', '')
+      ->setSetting('share_page_body_attributes', ['class' => ['my-custom-class']])
+      ->save();
+
+    // Check iframe page body custom attributes.
+    $this->drupalGet('/webform/contact/share');
+    $this->assertCssSelect('body.my-custom-class');
+
+    // Disable custom body attributes and hide page title.
+    $webform
+      ->setSetting('share_page_body_attributes', [])
+      ->setSetting('share_title', FALSE)
+      ->save();
+
+    // Check no page title.
+    $this->assertNoRaw('<h1 class="title page-title">Contact</h1>');
+
+    // Check iframe page iFrame-resizer script.
+    $this->drupalGet("/webform/contact/share/$library/$version");
+    $this->assertRaw('<script src="//cdn.jsdelivr.net/gh/davidjbradshaw/' . $library . '@v' . $version . '/js/iframeResizer.contentWindow.min.js"></script>');
+
+    // Check share.js.
+    $this->drupalGet("/webform/contact/share.js");
+    $this->assertRaw('document.write("');
+
+    // Check share script tag.
+    $build = [
+      '#type' => 'webform_share_script',
+      '#webform' => $webform,
+    ];
+    $actual_script_tag = $renderer->renderPlain($build);
+
+    $src = $base_url . "/webform/contact/share.js";
+    $src = preg_replace('#^https?:#', '', $src);
+    $expected_script_tag = '<script src="' . $src . '"></script>' . PHP_EOL;
+
+    $this->assertEqual($expected_script_tag, $actual_script_tag);
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareVariantTest.php b/web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareVariantTest.php
new file mode 100644
index 0000000000..062c55e66d
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/tests/src/Functional/WebformShareVariantTest.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace Drupal\Tests\webform_share\Functional;
+
+use Drupal\Tests\webform\Functional\WebformBrowserTestBase;
+use Drupal\webform_share\Element\WebformShareIframe;
+
+/**
+ * Webform share variant test.
+ *
+ * @group webform_share
+ */
+class WebformShareVariantTest extends WebformBrowserTestBase {
+
+  /**
+   * Webforms to load.
+   *
+   * @var array
+   */
+  protected static $testWebforms = [
+    'test_variant_multiple',
+    'test_variant_randomize',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = [
+    'webform',
+    'webform_share',
+  ];
+
+  /**
+   * Test variant.
+   */
+  public function testVariant() {
+    $library = WebformShareIframe::LIBRARY;
+    $version = WebformShareIframe::VERSION;
+
+    // Enable enable share for all webforms.
+    $config = \Drupal::configFactory()->getEditable('webform.settings');
+    $config->set('settings.default_share', TRUE)->save();
+
+    /**************************************************************************/
+
+    // Check default letter and number.
+    $this->drupalGet("/webform/test_variant_multiple/share/$library/$version");
+    $this->assertRaw('{X}');
+    $this->assertRaw('{0}');
+
+    // Check variant letter [A] and number [1].
+    $this->drupalGet("/webform/test_variant_multiple/share/$library/$version", ['query' => ['_webform_variant' => ['letter' => 'a', 'number' => 1]]]);
+    $this->assertNoRaw('{X}');
+    $this->assertNoRaw('{0}');
+    $this->assertRaw('[A]');
+    $this->assertRaw('[1]');
+
+    // Check variant letter [A] and number [1].
+    $this->drupalGet("/webform/test_variant_multiple/share/$library/$version", ['query' => ['letter' => 'a', 'number' => 1]]);
+    $this->assertNoRaw('{X}');
+    $this->assertNoRaw('{0}');
+    $this->assertRaw('[A]');
+    $this->assertRaw('[1]');
+
+    // Check variant randomize script is attached to shared page.
+    // @see _webform_page_attachments()
+    $this->drupalGet("/webform/test_variant_randomize/share/$library/$version");
+    $this->assertRaw('var variants = {"letter":["a","b"]};');
+  }
+
+}
diff --git a/web/modules/webform/modules/webform_share/webform_share.info.yml b/web/modules/webform/modules/webform_share/webform_share.info.yml
new file mode 100644
index 0000000000..20348a2ed3
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/webform_share.info.yml
@@ -0,0 +1,13 @@
+name: 'Webform Share [EXPERIMENTAL]'
+type: module
+description: 'Allows webforms to be shared on other websites using an iframe.'
+experimental: true
+package: 'Webform [EXPERIMENTAL]'
+core_version_requirement: ^8.8
+dependencies:
+  - 'webform:webform'
+
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
+project: 'webform'
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_share/webform_share.libraries.yml b/web/modules/webform/modules/webform_share/webform_share.libraries.yml
new file mode 100644
index 0000000000..1cf7eb1e5f
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/webform_share.libraries.yml
@@ -0,0 +1,42 @@
+webform_share.admin:
+  version: VERSION
+  css:
+    theme:
+      css/webform_share.admin.css: {}
+  js:
+    js/webform_share.admin.js: {}
+  dependencies:
+    - core/jquery
+    - core/drupal.announce
+
+webform_share.page:
+  version: VERSION
+  css:
+    theme:
+      css/webform_share.page.css: {}
+
+# Below is every version of the iFrame Resizer used by the webform share module.
+#
+# Including multiple versions of the iFrame Resizer ensures that any website
+# embedding an iframe with specific iFrame Resizer version will be able to
+# always access the older versions of the webform share page
+# (/webform/{webform}/share/{library}/{version}).
+#
+# When updating the iframe-resizer, please make sure to update
+# the below constants.
+#
+# @see \Drupal\webform_share\Element\WebformShareIframe::LIBRARY
+# @see \Drupal\webform_share\Element\WebformShareIframe::VERSION
+
+libraries.iframe-resizer.4.2.10:
+  # Inserting the iframe-resizer in the page's <head> provides the best
+  # UX because it allows the iframe to resize as the form is loaded.
+  header: true
+  remote: https://github.com/davidjbradshaw/iframe-resizer
+  version: '4.2.10'
+  license:
+    name: MIT
+    url: http://opensource.org/licenses/mit-license.php
+    gpl-compatible: true
+  js:
+    '//cdn.jsdelivr.net/gh/davidjbradshaw/iframe-resizer@v4.2.10/js/iframeResizer.contentWindow.min.js': { type: external, minified: true }
diff --git a/web/modules/webform/modules/webform_share/webform_share.links.task.yml b/web/modules/webform/modules/webform_share/webform_share.links.task.yml
new file mode 100644
index 0000000000..5b95536408
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/webform_share.links.task.yml
@@ -0,0 +1,46 @@
+entity.webform.share:
+  title: 'Share'
+  route_name: entity.webform.share_embed
+  base_route: entity.webform.canonical
+  weight: 50
+
+entity.webform.share_embed:
+  title: 'Embed'
+  route_name: entity.webform.share_embed
+  parent_id: entity.webform.share
+
+entity.webform.share_preview:
+  title: 'Preview'
+  route_name: entity.webform.share_preview
+  parent_id: entity.webform.share
+
+entity.webform.share_test:
+  title: 'Test'
+  route_name: entity.webform.share_test
+  parent_id: entity.webform.share
+
+
+# Webform share tasks.
+# These tasks will be removed if the webform_node.module is not installed.
+# @see webform_share_local_tasks_alter()
+
+entity.node.webform.share:
+  title: 'Share'
+  route_name: entity.node.webform.share_embed
+  base_route: entity.node.canonical
+  # No weight provided. @see node.links.task.yml
+
+entity.node.webform.share_embed:
+  title: 'Embed'
+  route_name: entity.node.webform.share_embed
+  parent_id: entity.node.webform.share
+
+entity.node.webform.share_preview:
+  title: 'Preview'
+  route_name: entity.node.webform.share_preview
+  parent_id: entity.node.webform.share
+
+entity.node.webform.share_test:
+  title: 'Test'
+  route_name: entity.node.webform.share_test
+  parent_id: entity.node.webform.share
diff --git a/web/modules/webform/modules/webform_share/webform_share.module b/web/modules/webform/modules/webform_share/webform_share.module
new file mode 100644
index 0000000000..8b1bddc718
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/webform_share.module
@@ -0,0 +1,325 @@
+<?php
+
+/**
+ * @file
+ * Allows webforms to be shared on other websites using an iframe.
+ */
+
+use Drupal\block\Entity\Block;
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Render\Markup;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\webform\WebformInterface;
+use Drupal\webform_share\WebformSharePreRender;
+use Drupal\webform_share\WebformShareHelper;
+
+/**
+ * Implements hook_webform_help_info().
+ */
+function webform_share_webform_help_info() {
+  $help = [];
+  $help['webform_share_embed'] = [
+    'group' => 'share',
+    'title' => t('Share embed'),
+    'content' => t("The <strong>Share embed</strong> page provides code snippets that are used to embedded a webform in any website, webpage, and application."),
+    'routes' => [
+      // @see /admin/structure/webform/manage/{webform}/share
+      'entity.webform.share_embed',
+      // @see /node/{node}/webform/share
+      'entity.node.webform.share_embed',
+    ],
+  ];
+  $help['webform_share_preview'] = [
+    'group' => 'share',
+    'title' => t('Share preview'),
+    'content' => t("The <strong>Share preview</strong> page allows site builders to preview an embedded webform."),
+    'routes' => [
+      // @see /admin/structure/webform/manage/{webform}/share/preview
+      'entity.webform.share_preview',
+      // @see /node/{node}/webform/share/preview
+      'entity.node.webform.share_preview',
+    ],
+  ];
+  $help['webform_share_test'] = [
+    'group' => 'share',
+    'title' => t('Share test'),
+    'content' => t("The <strong>Share test</strong> page allows site builders to test an embedded webform."),
+    'routes' => [
+      // @see /admin/structure/webform/manage/{webform}/share/test
+      'entity.webform.share_test',
+      // @see /node/{node}/webform/share/test
+      'entity.node.webform.share_test',
+    ],
+  ];
+  return $help;
+}
+
+/**
+ * Implements hook_local_tasks_alter().
+ */
+function webform_share_local_tasks_alter(&$local_tasks) {
+  // Remove webform share if the webform_node.module
+  // is not installed.
+  if (!\Drupal::moduleHandler()->moduleExists('webform_node')) {
+    unset(
+      $local_tasks['entity.node.webform.share'],
+      $local_tasks['entity.node.webform.share_embed'],
+      $local_tasks['entity.node.webform.share_preview'],
+      $local_tasks['entity.node.webform.share_test']
+    );
+  }
+}
+
+/**
+ * Implements hook_menu_local_tasks_alter().
+ */
+function webform_share_menu_local_tasks_alter(&$data, $route_name, RefinableCacheableDependencyInterface $cacheability) {
+  // Allow webform query string parameters to be transferred
+  // from canonical to test URL.
+  $route_names = [
+    'entity.webform.share_embed', 'entity.webform.share_preview', 'entity.webform.share_test',
+  ];
+  if (in_array($route_name, $route_names)) {
+    if ($query = \Drupal::request()->query->all()) {
+      foreach ($route_names as $route_name) {
+        if (isset($data['tabs'][1][$route_name])) {
+          $url =& $data['tabs'][1][$route_name]['#link']['url'];
+          $url->setOption('query', $query);
+        }
+      }
+    }
+
+    // Query string to cache context webform canonical and test routes.
+    $cacheability->addCacheContexts(['url.query_args']);
+  }
+}
+
+/**
+ * Implements hook_element_info_alter().
+ */
+function webform_share_element_info_alter(&$type) {
+  $type['page']['#pre_render'][] = [WebformSharePreRender::class, 'page'];
+}
+
+/**
+ * Implements hook_entity_type_alter().
+ */
+function webform_share_entity_type_alter(array &$entity_types) {
+  if (isset($entity_types['webform'])) {
+    /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $webform_entity_type */
+    $webform_entity_type = $entity_types['webform'];
+
+    // Add 'share-embed',  'share-preview', and 'share-test' to link templates.
+    $webform_entity_type->setLinkTemplate('share-embed', '/admin/structure/webform/manage/{webform}/share/embed');
+    $webform_entity_type->setLinkTemplate('share-preview', '/admin/structure/webform/manage/{webform}/share/preview');
+    $webform_entity_type->setLinkTemplate('share-test', '/admin/structure/webform/manage/{webform}/share/test');
+  }
+}
+
+/**
+ * Implements hook_entity_operation().
+ */
+function webform_share_entity_operation(EntityInterface $entity) {
+  $operations = [];
+  if ($entity instanceof WebformInterface
+    && $entity->access('update')
+    && $entity->getSetting('share', TRUE)) {
+    $operations['share'] = [
+      'title' => t('Share'),
+      'url' => $entity->toUrl('share-embed'),
+      'weight' => 80,
+    ];
+  }
+  return $operations;
+}
+
+/**
+ * Implements hook_block_access().
+ */
+function webform_share_block_access(Block $block, $operation, AccountInterface $account) {
+  if (!WebformShareHelper::isPage()) {
+    return AccessResult::neutral();
+  }
+
+  // Only adjust block view access.
+  if ($operation !== 'view') {
+    return AccessResult::neutral();
+  }
+
+  // Hide all blocks to improve the webform share page's performance.
+  return AccessResult::forbidden();
+}
+
+/**
+ * Implements hook_page_top().
+ */
+function webform_share_page_top(array &$page_top) {
+  if (!WebformShareHelper::isPage()) {
+    return;
+  }
+
+  // Remove the toolbar from the webform share page.
+  unset($page_top['toolbar']);
+}
+
+/******************************************************************************/
+// Theme functions.
+/******************************************************************************/
+
+/**
+ * Implements hook_theme().
+ */
+function webform_share_theme($existing, $type, $theme, $path) {
+  return [
+    // Using dedicated html and page template ensures the shared webforms
+    // output is as simple as possible.
+    'html__webform_share' => [
+      'render element' => 'html',
+    ],
+    'page__webform_share' => [
+      'render element' => 'page',
+    ],
+    'webform_share_iframe' => [
+      'render element' => 'element',
+    ],
+    'webform_share_script' => [
+      'render element' => 'element',
+    ],
+  ];
+}
+
+/**
+ * Implements hook_theme_suggestions_HOOK().
+ */
+function webform_share_theme_suggestions_html(array $variables) {
+  return (WebformShareHelper::isPage()) ? ['html__webform_share'] : [];
+}
+
+/**
+ * Implements hook_theme_suggestions_HOOK().
+ */
+function webform_share_theme_suggestions_page(array $variables) {
+  return (WebformShareHelper::isPage()) ? ['page__webform_share'] : [];
+}
+
+/**
+ * Prepares variables for the webform share page HTML templates.
+ */
+function template_preprocess_html__webform_share(&$variables) {
+  // Make sure the variables are preprocessed.
+  // @see template_preprocess_page()
+  if (!isset($variables['page'])) {
+    template_preprocess_html($variables);
+  }
+
+  /** @var \Drupal\webform\WebformInterface $webform */
+  $webform = \Drupal::routeMatch()->getParameter('webform');
+
+  // Add html.webform-share-page-html class.
+  $variables['html_attributes']->addClass('webform-share-page-html');
+
+  // Add body.webform-share-page-body class.
+  // @see webform_share.page.css
+  $variables['attributes'] += ['class' => []];
+  $variables['attributes']['class'][] = 'webform-share-page-body';
+
+  // Add custom page body attributes.
+  $body_attributes = $webform->getSetting('share_page_body_attributes');
+  if (isset($body_attributes['class'])) {
+    $variables['attributes']['class'] = array_merge($variables['attributes']['class'], $body_attributes['class']);
+    unset($body_attributes['class']);
+  }
+  $variables['attributes'] = $body_attributes + $variables['attributes'];
+
+  // Remove toolbar.module body classes.
+  // @see toolbar_preprocess_html()
+  if (\Drupal::currentUser()->hasPermission('access toolbar')) {
+    foreach ($variables['attributes']['class'] as $index => $class_name) {
+      if (strpos($class_name, 'toolbar-') === 0) {
+        unset($variables['attributes']['class'][$index]);
+      }
+    }
+    $variables['attributes']['class'] = array_values($variables['attributes']['class']);
+  }
+
+  // Prepend page title to the content because all blocks are hidden.
+  // @see webform_share_block_access()
+  // @see https://drupal.stackexchange.com/questions/112757/how-can-i-get-the-page-title/112758
+  if ($webform->getSetting('share_title')) {
+    $request = \Drupal::request();
+    $route_match = \Drupal::routeMatch();
+    $title = \Drupal::service('title_resolver')->getTitle($request, $route_match->getRouteObject());
+    $variables['page']['content']['page_title'] = [
+      '#type' => 'page_title',
+      '#title' => $title,
+      // Move page title before the message block (weight: 1000)
+      // @see \Drupal\block\Plugin\DisplayVariant\BlockPageVariant::build
+      '#weight' => -1001,
+    ];
+  }
+}
+
+/**
+ * Prepares variables for the webform share page templates.
+ */
+function template_preprocess_page__webform_share(&$variables) {
+  // Make sure the variables are preprocessed.
+  // @see template_preprocess_page()
+  if (!isset($variables['base_path'])) {
+    template_preprocess_page($variables);
+  }
+}
+
+/**
+ * Implements hook_preprocess_HOOK() for page title templates.
+ */
+function webform_share_preprocess_page_title(&$variables) {
+  if (!WebformShareHelper::isPage()) {
+    return;
+  }
+
+  // Remove shortcut widget from page title.
+  // @see shortcut_preprocess_page_title()
+  if (isset($variables['title_suffix'])) {
+    unset($variables['title_suffix']['add_or_remove_shortcut']);
+  }
+}
+
+/**
+ * Prepares variables for webform share iframe templates.
+ *
+ * Default template: webform-share-iframe.html.twig.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties of the element.
+ *     Properties used: #webform, #javascript, #options, and #attributes.
+ */
+function template_preprocess_webform_share_iframe(array &$variables) {
+  $element = $variables['element'];
+
+  // Set javascript.
+  $variables['javascript'] = $element['#javascript'];
+
+  // Set iframe-resizer script options.
+  $variables['script'] = $element['#script'];
+  $options = json_encode($element['#options'], JSON_FORCE_OBJECT);
+  $variables['options'] = Markup::create($options);
+}
+
+/**
+ * Prepares variables for webform share script templates.
+ *
+ * Default template: webform-share-script.html.twig.
+ *
+ * @param array $variables
+ *   An associative array containing:
+ *   - element: An associative array containing the properties of the element.
+ *     Properties used: #webform, #javascript, #options, and #attributes.
+ */
+function template_preprocess_webform_share_script(array &$variables) {
+  $element = $variables['element'];
+  $variables['script'] = $element['#script'];
+}
diff --git a/web/modules/webform/modules/webform_share/webform_share.routing.yml b/web/modules/webform/modules/webform_share/webform_share.routing.yml
new file mode 100644
index 0000000000..a5b07c9bd9
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/webform_share.routing.yml
@@ -0,0 +1,129 @@
+# Iframe embed page with and without JavaScript.
+
+entity.webform.share_page:
+  path: '/webform/{webform}/share'
+  defaults:
+    _controller: '\Drupal\webform_share\Controller\WebformShareController::page'
+    _title_callback: '\Drupal\webform\Controller\WebformEntityController::title'
+  options:
+    parameters:
+      webform:
+        type: 'entity:webform'
+  requirements:
+    _entity_access: 'webform.submission_create'
+    _custom_access: '\Drupal\webform_share\Access\WebformShareAccess::checkAccess'
+
+entity.webform.share_page.javascript:
+  path: '/webform/{webform}/share/{library}/{version}'
+  defaults:
+    _controller: '\Drupal\webform_share\Controller\WebformShareController::page'
+    _title_callback: '\Drupal\webform\Controller\WebformEntityController::title'
+  options:
+    parameters:
+      webform:
+        type: 'entity:webform'
+  requirements:
+    _entity_access: 'webform.submission_create'
+    _custom_access: '\Drupal\webform_share\Access\WebformShareAccess::checkAccess'
+
+entity.webform.share_script:
+  path: '/webform/{webform}/share.js'
+  defaults:
+    _controller: '\Drupal\webform_share\Controller\WebformShareController::script'
+  options:
+    parameters:
+      webform:
+        type: 'entity:webform'
+  requirements:
+    _entity_access: 'webform.submission_page'
+    _custom_access: '\Drupal\webform_share\Access\WebformShareAccess::checkAccess'
+
+# Share embed, preview, and test.
+
+entity.webform.share_embed:
+  path: '/admin/structure/webform/manage/{webform}/share'
+  defaults:
+    _form: '\Drupal\webform_share\Form\WebformShareEmbedForm'
+    _title_callback: '\Drupal\webform\Controller\WebformEntityController::title'
+  options:
+    parameters:
+      webform:
+        type: 'entity:webform'
+  requirements:
+    _entity_access: 'webform.update'
+    _custom_access: '\Drupal\webform_share\Access\WebformShareAccess::checkAccess'
+
+entity.webform.share_preview:
+  path: '/admin/structure/webform/manage/{webform}/share/preview'
+  defaults:
+    _controller: '\Drupal\webform_share\Controller\WebformShareController::preview'
+    _title_callback: '\Drupal\webform\Controller\WebformEntityController::title'
+  options:
+    parameters:
+      webform:
+        type: 'entity:webform'
+  requirements:
+    _entity_access: 'webform.submission_create'
+    _custom_access: '\Drupal\webform_share\Access\WebformShareAccess::checkAccess'
+
+entity.webform.share_test:
+  path: '/admin/structure/webform/manage/{webform}/share/test'
+  defaults:
+    _controller: '\Drupal\webform_share\Controller\WebformShareController::test'
+    _title_callback: '\Drupal\webform\Controller\WebformEntityController::title'
+  options:
+    parameters:
+      webform:
+        type: 'entity:webform'
+  requirements:
+    _entity_access: 'webform.test'
+    _custom_access: '\Drupal\webform_share\Access\WebformShareAccess::checkAccess'
+
+# Webform node routes.
+# These routes will be removed if the webform_node.module is not installed.
+# @see \Drupal\webform_options_limit\Routing\WebformOptionsLimitRouteSubscriber
+
+entity.node.webform.share_embed:
+  path: '/node/{node}/webform/share'
+  defaults:
+    _form: '\Drupal\webform_share\Form\WebformShareEmbedForm'
+    _title_callback: '\Drupal\Core\Entity\Controller\EntityController::title'
+    operation: webform_share
+    entity_access: 'webform.share'
+  options:
+    _admin_route: TRUE
+    parameters:
+      node:
+        type: 'entity:node'
+  requirements:
+    _custom_access: '\Drupal\webform_share\Access\WebformShareAccess::checkNodeAccess'
+
+entity.node.webform.share_preview:
+  path: '/node/{node}/webform/share/preview'
+  defaults:
+    _controller: '\Drupal\webform_share\Controller\WebformShareController::preview'
+    _title_callback: '\Drupal\Core\Entity\Controller\EntityController::title'
+    operation: webform_share_preview
+    entity_access: 'webform.submission_create'
+  options:
+    _admin_route: TRUE
+    parameters:
+      node:
+        type: 'entity:node'
+  requirements:
+    _custom_access: '\Drupal\webform_share\Access\WebformShareAccess::checkNodeAccess'
+
+entity.node.webform.share_test:
+  path: '/node/{node}/webform/share/test'
+  defaults:
+    _controller: '\Drupal\webform_share\Controller\WebformShareController::test'
+    _title_callback: '\Drupal\Core\Entity\Controller\EntityController::title'
+    operation: webform_share_test
+    entity_access: 'webform.test'
+  options:
+    _admin_route: TRUE
+    parameters:
+      node:
+        type: 'entity:node'
+  requirements:
+    _custom_access: '\Drupal\webform_share\Access\WebformShareAccess::checkNodeAccess'
diff --git a/web/modules/webform/modules/webform_share/webform_share.services.yml b/web/modules/webform/modules/webform_share/webform_share.services.yml
new file mode 100644
index 0000000000..c2ed68d658
--- /dev/null
+++ b/web/modules/webform/modules/webform_share/webform_share.services.yml
@@ -0,0 +1,16 @@
+services:
+  webform_share.event_subscriber:
+    class: Drupal\webform_share\EventSubscriber\WebformShareEventSubscriber
+    arguments: ['@current_route_match']
+    tags:
+      - { name: event_subscriber }
+  webform_share.route_subscriber:
+    class: Drupal\webform_share\Routing\WebformShareRouteSubscriber
+    arguments: ['@module_handler']
+    tags:
+      - { name: event_subscriber }
+  webform_share.theme_negotiator:
+    class: Drupal\webform_share\Theme\WebformShareThemeNegotiator
+    arguments: ['@config.factory']
+    tags:
+      - { name: theme_negotiator }
diff --git a/web/modules/webform/modules/webform_shortcuts/tests/src/Functional/WebformShortcutsFunctionalTest.php b/web/modules/webform/modules/webform_shortcuts/tests/src/Functional/WebformShortcutsFunctionalTest.php
index 39f11e6938..15283c1079 100644
--- a/web/modules/webform/modules/webform_shortcuts/tests/src/Functional/WebformShortcutsFunctionalTest.php
+++ b/web/modules/webform/modules/webform_shortcuts/tests/src/Functional/WebformShortcutsFunctionalTest.php
@@ -7,7 +7,7 @@
 /**
  * Webform shortcuts test.
  *
- * @group webform_browser
+ * @group webform_shortcuts
  */
 class WebformShortcutsFunctionalTest extends WebformBrowserTestBase {
 
@@ -24,7 +24,7 @@ class WebformShortcutsFunctionalTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
     $this->placeBlocks();
   }
@@ -44,7 +44,7 @@ public function testShortcuts() {
       'webform_shortcuts[add_element]' => 'crtl+z',
       'webform_shortcuts[toggle_weights]' => '',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config/advanced', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/advanced', $edit, 'Save configuration');
 
     // Check customized shortcuts.
     $this->drupalGet('/admin/structure/webform/manage/contact');
diff --git a/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.info.yml b/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.info.yml
index 19aea289bf..c476bb64d1 100644
--- a/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.info.yml
+++ b/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.info.yml
@@ -2,12 +2,12 @@ name: 'Webform Shortcuts'
 type: module
 description: 'Provides configurable keyboard shortcuts to create and save webform elements.'
 package: 'Webform'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
   - 'webform:webform_ui'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.module b/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.module
index a41597c1aa..74005fbbe1 100644
--- a/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.module
+++ b/web/modules/webform/modules/webform_shortcuts/webform_shortcuts.module
@@ -30,7 +30,7 @@ function webform_shortcuts_webform_libraries_info() {
  * Implements hook_preprocess_block().
  */
 function webform_shortcuts_preprocess_block(&$variables) {
-  if ($variables['plugin_id'] != 'local_actions_block') {
+  if ($variables['plugin_id'] !== 'local_actions_block') {
     return;
   }
 
@@ -84,6 +84,7 @@ function webform_shortcuts_preprocess_block(&$variables) {
     '#type' => 'webform_help',
     '#help_title' => t('Keyboard shortcuts'),
     '#help' => $items,
+    '#weight' => 100,
   ];
 
   $variables['content']['help']['#attached']['library'][] = 'webform_shortcuts/webform_shortcuts';
@@ -103,7 +104,7 @@ function webform_shortcuts_preprocess_block(&$variables) {
 }
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for admin config advanced form.
  */
 function webform_shortcuts_form_webform_admin_config_advanced_form_alter(&$form, FormStateInterface $form_state) {
   $config = \Drupal::config('webform_shortcuts.settings');
diff --git a/web/modules/webform/modules/webform_submission_export_import/src/Controller/WebformSubmissionExportImportController.php b/web/modules/webform/modules/webform_submission_export_import/src/Controller/WebformSubmissionExportImportController.php
index 39a35ad21f..874870543e 100644
--- a/web/modules/webform/modules/webform_submission_export_import/src/Controller/WebformSubmissionExportImportController.php
+++ b/web/modules/webform/modules/webform_submission_export_import/src/Controller/WebformSubmissionExportImportController.php
@@ -32,7 +32,7 @@ class WebformSubmissionExportImportController extends ControllerBase implements
   protected $webformSubmissionStorage;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/modules/webform_submission_export_import/src/Form/WebformSubmissionExportImportUploadForm.php b/web/modules/webform/modules/webform_submission_export_import/src/Form/WebformSubmissionExportImportUploadForm.php
index 2c0dabf2f5..e84c31481c 100644
--- a/web/modules/webform/modules/webform_submission_export_import/src/Form/WebformSubmissionExportImportUploadForm.php
+++ b/web/modules/webform/modules/webform_submission_export_import/src/Form/WebformSubmissionExportImportUploadForm.php
@@ -31,7 +31,7 @@ class WebformSubmissionExportImportUploadForm extends ConfirmFormBase {
   protected $dateFormatter;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
@@ -275,7 +275,7 @@ public function submitUploadForm(array &$form, FormStateInterface $form_state) {
 
       case 'url':
         $import_url = $form_state->getValue('import_url');
-        $file_path = tempnam(file_directory_temp(), 'webform_submission_export_import_') . '.csv';
+        $file_path = tempnam(\Drupal::service('file_system')->getTempDirectory(), 'webform_submission_export_import_') . '.csv';
         file_put_contents($file_path, file_get_contents($import_url));
 
         $form_field_name = $this->t('Submission CSV (Comma Separated Values) file');
@@ -631,7 +631,7 @@ public static function batchProcess(WebformInterface $webform, EntityInterface $
     $context['message'] = t('Imported @count of @total submissions…', ['@count' => $context['sandbox']['progress'], '@total' => $context['sandbox']['max']]);
 
     // Track finished.
-    if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
+    if ($context['sandbox']['progress'] !== $context['sandbox']['max']) {
       $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
     }
 
diff --git a/web/modules/webform/modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php b/web/modules/webform/modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php
index e434fd2cbb..6abd22173f 100644
--- a/web/modules/webform/modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php
+++ b/web/modules/webform/modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php
@@ -51,14 +51,14 @@ class WebformSubmissionExportImportImporter implements WebformSubmissionExportIm
   protected $entityTypeManager;
 
   /**
-   * Webform submission storage.
+   * The webform submission storage.
    *
    * @var \Drupal\webform\WebformSubmissionStorageInterface
    */
   protected $entityStorage;
 
   /**
-   * Webform element manager.
+   * The webform element manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
@@ -416,7 +416,7 @@ public function import($offset = 0, $limit = NULL) {
       // Get CSV values.
       $values = fgetcsv($handle);
       // Complete ignored empty rows.
-      if (empty($values) || $values == ['']) {
+      if (empty($values) || $values === ['']) {
         continue;
       }
       $index++;
@@ -766,7 +766,7 @@ protected function importManageFileElement(array $element, $value, WebformSubmis
 
       // Check URL status code.
       $file_headers = @get_headers($new_file_uri);
-      if (!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
+      if (!$file_headers || $file_headers[0] === 'HTTP/1.1 404 Not Found') {
         $errors[] = $this->t('[@element_key] URL (@url) returns 404 file not found.', $t_args);
         continue;
       }
diff --git a/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/config/install/webform.webform.test_submission_export_import.yml b/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/config/install/webform.webform.test_submission_export_import.yml
index b56564c521..b4540b8c70 100644
--- a/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/config/install/webform.webform.test_submission_export_import.yml
+++ b/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/config/install/webform.webform.test_submission_export_import.yml
@@ -75,7 +75,7 @@ elements: |
     '#selection_handler': 'default:user'
     '#selection_settings':
       include_anonymous: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -87,7 +87,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: both
   form_submit_once: false
   form_exception_message: ''
@@ -117,6 +117,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -142,11 +147,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.info.yml b/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.info.yml
index d850504cf5..216f551af0 100644
--- a/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.info.yml
+++ b/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.info.yml
@@ -1,13 +1,13 @@
-name: 'Webform Submission Export/Import Test'
+name: 'Webform Submission Export/Import test'
 type: module
-description: 'Support module for webform submission export/import.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform submission export/import testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_submission_export_import'
   - 'webform:webform_image_select'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.module b/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.module
index 429c0943e5..9b9e16ef0e 100644
--- a/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.module
+++ b/web/modules/webform/modules/webform_submission_export_import/tests/modules/webform_submission_export_import_test/webform_submission_export_import_test.module
@@ -10,7 +10,7 @@
 use Drupal\user\Entity\User;
 
 /**
- * Implements hook_form_FORM_ID_alter().
+ * Implements hook_form_FORM_ID_alter() for webform submission export import upload form.
  *
  * Make testing the CSV import a little easier by using and prepopulating
  * external Google Sheet CSV.
diff --git a/web/modules/webform/modules/webform_submission_export_import/tests/src/Functional/WebformSubmissionImportExportFunctionalTest.php b/web/modules/webform/modules/webform_submission_export_import/tests/src/Functional/WebformSubmissionImportExportFunctionalTest.php
index 48f92c73cb..80490b05d4 100644
--- a/web/modules/webform/modules/webform_submission_export_import/tests/src/Functional/WebformSubmissionImportExportFunctionalTest.php
+++ b/web/modules/webform/modules/webform_submission_export_import/tests/src/Functional/WebformSubmissionImportExportFunctionalTest.php
@@ -11,7 +11,7 @@
 /**
  * Webform submission export/import test.
  *
- * @group webform_browser
+ * @group webform_submission_import_export
  */
 class WebformSubmissionImportExportFunctionalTest extends WebformBrowserTestBase {
 
@@ -50,7 +50,7 @@ public function testSubmissionExport() {
     ];
 
     // Create CSV export.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_submission_export_import/results/download', ['exporter' => 'webform_submission_export_import'], t('Download'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_submission_export_import/results/download', ['exporter' => 'webform_submission_export_import'], 'Download');
     file_put_contents($export_csv_uri, $this->getRawContent());
 
     /**************************************************************************/
@@ -167,7 +167,7 @@ public function testSubmissionImport() {
     $this->drupalPostForm(
       '/admin/structure/webform/manage/test_submission_export_import/results/upload',
       ['import_url' => $webform_csv_url],
-      t('Continue')
+      'Continue'
     );
 
     // Check submission count.
@@ -177,7 +177,7 @@ public function testSubmissionImport() {
     $this->drupalPostForm(
       NULL,
       ['import_options[treat_warnings_as_errors]' => TRUE, 'confirm' => TRUE],
-      t('Import')
+      'Import'
     );
 
     // Check import stats.
@@ -364,7 +364,7 @@ public function testSubmissionImport() {
     $this->drupalPostForm(
       '/admin/structure/webform/manage/test_submission_export_import/results/upload',
       ['import_url' => $webform_csv_url],
-      t('Continue')
+      'Continue'
     );
 
     $this->drupalPostForm(
@@ -374,7 +374,7 @@ public function testSubmissionImport() {
         'import_options[mapping][not_mapped]' => 'summary',
         'confirm' => TRUE,
       ],
-      t('Import')
+      'Import'
     );
 
     // Check that submission summary now is set to not mapped.
@@ -385,14 +385,14 @@ public function testSubmissionImport() {
     $this->drupalPostForm(
       '/admin/structure/webform/manage/test_submission_export_import/results/upload',
       ['import_url' => $external_csv_url],
-      t('Continue')
+      'Continue'
     );
 
     // Check that UUID warning is displayed.
     $this->assertRaw('No UUID or token was found in the source (CSV). A unique hash will be generated for the each CSV record. Any changes to already an imported record in the source (CSV) will create a new submission.');
 
     // Import the external.csv.
-    $this->drupalPostForm(NULL, ['confirm' => TRUE], t('Import'));
+    $this->drupalPostForm(NULL, ['confirm' => TRUE], 'Import');
 
     // Check that 1 external submission created.
     $this->assertRaw('Submission import completed. (total: 1; created: 1; updated: 0; skipped: 0)');
@@ -405,11 +405,11 @@ public function testSubmissionImport() {
     $this->drupalPostForm(
       '/admin/structure/webform/manage/test_submission_export_import/results/upload',
       ['import_url' => $external_csv_url],
-      t('Continue')
+      'Continue'
     );
 
     // Re-import the external.csv.
-    $this->drupalPostForm(NULL, ['confirm' => TRUE], t('Import'));
+    $this->drupalPostForm(NULL, ['confirm' => TRUE], 'Import');
 
     // Check that 1 external submission updated.
     $this->assertRaw('Submission import completed. (total: 1; created: 0; updated: 1; skipped: 0)');
diff --git a/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.info.yml b/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.info.yml
index eaf04cff30..e92841e688 100644
--- a/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.info.yml
+++ b/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.info.yml
@@ -1,13 +1,12 @@
 name: 'Webform Submission Export/Import [EXPERIMENTAL]'
 type: module
 description: 'Provides the ability to export and import submissions.'
-experimental: true
-package: 'Webform [EXPERIMENTAL]'
-core_version_requirement: ^8.7.7 || ^9
+package: 'Webform'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.module b/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.module
index fd4e8b4bae..39cf3c158d 100644
--- a/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.module
+++ b/web/modules/webform/modules/webform_submission_export_import/webform_submission_export_import.module
@@ -13,6 +13,7 @@
  * Implements hook_webform_help_info().
  */
 function webform_submission_export_import_webform_help_info() {
+  $help = [];
   $help['webform_submission_export_import'] = [
     'group' => 'forms',
     'title' => t('Upload'),
@@ -25,7 +26,6 @@ function webform_submission_export_import_webform_help_info() {
       'entity.node.webform_submission_export_import.results_import',
     ],
   ];
-
   return $help;
 }
 
@@ -80,6 +80,9 @@ function _webform_submission_export_import_file_save_upload_single(\SplFileInfo
   $file_system = \Drupal::service('file_system');
   $current_user = \Drupal::currentUser();
 
+  /** @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager */
+  $stream_wrapper_manager = \Drupal::service('stream_wrapper_manager');
+
   // Check for file upload errors and return FALSE for this file if a lower
   // level system error occurred. For a complete list of errors:
   // See http://php.net/manual/features.file-upload.errors.php.
@@ -156,7 +159,7 @@ function _webform_submission_export_import_file_save_upload_single(\SplFileInfo
   // rename filename.php.foo and filename.php to filename.php.foo.txt and
   // filename.php.txt, respectively). Don't rename if 'allow_insecure_uploads'
   // evaluates to TRUE.
-  if (!\Drupal::config('system.file')->get('allow_insecure_uploads') && preg_match(FILE_INSECURE_EXTENSION_REGEX, $file->getFilename()) && (substr($file->getFilename(), -4) != '.txt')) {
+  if (!\Drupal::config('system.file')->get('allow_insecure_uploads') && preg_match(FILE_INSECURE_EXTENSION_REGEX, $file->getFilename()) && (substr($file->getFilename(), -4) !== '.txt')) {
     $file->setMimeType('text/plain');
     // The destination filename will also later be used to create the URI.
     $file->setFilename($file->getFilename() . '.txt');
@@ -174,15 +177,15 @@ function _webform_submission_export_import_file_save_upload_single(\SplFileInfo
   }
 
   // Assert that the destination contains a valid stream.
-  $destination_scheme = $file_system->uriScheme($destination);
-  if (!$file_system->validScheme($destination_scheme)) {
+  $destination_scheme = $stream_wrapper_manager->getScheme($destination);
+  if (!$stream_wrapper_manager->isValidScheme($destination_scheme)) {
     \Drupal::messenger()->addError(t('The file could not be uploaded because the destination %destination is invalid.', ['%destination' => $destination]));
     return FALSE;
   }
 
   $file->source = $form_field_name;
   // A file URI may already have a trailing slash or look like "public://".
-  if (substr($destination, -1) != '/') {
+  if (substr($destination, -1) !== '/') {
     $destination .= '/';
   }
   $file->destination = \Drupal::service('file_system')->getDestinationFilename($destination . $file->getFilename(), $replace);
@@ -233,9 +236,9 @@ function _webform_submission_export_import_file_save_upload_single(\SplFileInfo
   $file_system->chmod($file->getFileUri());
 
   // If we are replacing an existing file re-use its database record.
-  // @todo Do not create a new entity in order to update it. See
-  //   https://www.drupal.org/node/2241865.
-  if ($replace == FileSystemInterface::EXISTS_REPLACE) {
+  // @todo Do not create a new entity in order to update it.
+  // @see https://www.drupal.org/node/2241865.
+  if ($replace === FileSystemInterface::EXISTS_REPLACE) {
     $existing_files = \Drupal::entityTypeManager()
       ->getStorage('file')
       ->loadByProperties(['uri' => $file->getFileUri()]);
diff --git a/web/modules/webform/modules/webform_submission_log/src/Controller/WebformSubmissionLogController.php b/web/modules/webform/modules/webform_submission_log/src/Controller/WebformSubmissionLogController.php
index dcf251c756..5c9f5949bd 100644
--- a/web/modules/webform/modules/webform_submission_log/src/Controller/WebformSubmissionLogController.php
+++ b/web/modules/webform/modules/webform_submission_log/src/Controller/WebformSubmissionLogController.php
@@ -56,7 +56,7 @@ class WebformSubmissionLogController extends ControllerBase {
   protected $webformSubmissionStorage;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/modules/webform_submission_log/src/WebformSubmissionLogManager.php b/web/modules/webform/modules/webform_submission_log/src/WebformSubmissionLogManager.php
index 1e145b2b90..afc69b6a60 100644
--- a/web/modules/webform/modules/webform_submission_log/src/WebformSubmissionLogManager.php
+++ b/web/modules/webform/modules/webform_submission_log/src/WebformSubmissionLogManager.php
@@ -16,11 +16,6 @@ class WebformSubmissionLogManager implements WebformSubmissionLogManagerInterfac
 
   use DependencySerializationTrait;
 
-  /**
-   * Name of the table where log entries are stored.
-   */
-  const TABLE = 'webform_submission_log';
-
   /**
    * The database service.
    *
@@ -31,11 +26,11 @@ class WebformSubmissionLogManager implements WebformSubmissionLogManagerInterfac
   /**
    * WebformSubmissionLogManager constructor.
    *
-   * @param \Drupal\Core\Database\Connection $datababse
+   * @param \Drupal\Core\Database\Connection $database
    *   The database service.
    */
-  public function __construct(Connection $datababse) {
-    $this->database = $datababse;
+  public function __construct(Connection $database) {
+    $this->database = $database;
   }
 
   /**
@@ -53,7 +48,7 @@ public function insert(array $fields) {
       'data' => serialize([]),
       'timestamp' => '',
     ];
-    $this->database->insert(self::TABLE)
+    $this->database->insert(WebformSubmissionLogManagerInterface::TABLE)
       ->fields($fields)
       ->execute();
   }
@@ -68,7 +63,7 @@ public function getQuery(EntityInterface $webform_entity = NULL, EntityInterface
       'limit' => NULL,
     ];
 
-    $query = $this->database->select(static::TABLE, 'log');
+    $query = $this->database->select(WebformSubmissionLogManagerInterface::TABLE, 'log');
 
     // Log fields.
     $query->fields('log', [
diff --git a/web/modules/webform/modules/webform_submission_log/src/WebformSubmissionLogManagerInterface.php b/web/modules/webform/modules/webform_submission_log/src/WebformSubmissionLogManagerInterface.php
index 1ed2cd5188..609bdba560 100644
--- a/web/modules/webform/modules/webform_submission_log/src/WebformSubmissionLogManagerInterface.php
+++ b/web/modules/webform/modules/webform_submission_log/src/WebformSubmissionLogManagerInterface.php
@@ -10,6 +10,11 @@
  */
 interface WebformSubmissionLogManagerInterface {
 
+  /**
+   * Name of the table where log entries are stored.
+   */
+  const TABLE = 'webform_submission_log';
+
   /**
    * Insert submission log.
    *
diff --git a/web/modules/webform/modules/webform_submission_log/tests/src/Functional/WebformSubmissionLogNodeTest.php b/web/modules/webform/modules/webform_submission_log/tests/src/Functional/WebformSubmissionLogNodeTest.php
index fddcaf37cd..a5c7a4d33b 100644
--- a/web/modules/webform/modules/webform_submission_log/tests/src/Functional/WebformSubmissionLogNodeTest.php
+++ b/web/modules/webform/modules/webform_submission_log/tests/src/Functional/WebformSubmissionLogNodeTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform node submission log.
  *
- * @group WebformSubmissionLog
+ * @group webform_submission_log
  */
 class WebformSubmissionLogNodeTest extends WebformNodeBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_submission_log/tests/src/Functional/WebformSubmissionLogTest.php b/web/modules/webform/modules/webform_submission_log/tests/src/Functional/WebformSubmissionLogTest.php
index 905fb9db7d..7c5f7df1ae 100644
--- a/web/modules/webform/modules/webform_submission_log/tests/src/Functional/WebformSubmissionLogTest.php
+++ b/web/modules/webform/modules/webform_submission_log/tests/src/Functional/WebformSubmissionLogTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform submission log.
  *
- * @group WebformSubmissionLog
+ * @group webform_submission_log
  */
 class WebformSubmissionLogTest extends WebformBrowserTestBase {
 
@@ -60,7 +60,7 @@ public function testSubmissionLog() {
     $this->assertNull($log->entity_id);
 
     // Check submission draft created.
-    $sid_2 = $this->postSubmission($webform, ['value' => 'Test'], t('Save Draft'));
+    $sid_2 = $this->postSubmission($webform, ['value' => 'Test'], 'Save Draft');
     $log = $this->getLastSubmissionLog();
     $this->assertEqual($log->lid, 2);
     $this->assertEqual($log->sid, 2);
@@ -74,7 +74,7 @@ public function testSubmissionLog() {
     $this->assertNull($log->entity_id);
 
     // Check submission draft updated.
-    $this->postSubmission($webform, ['value' => 'Test'], t('Save Draft'));
+    $this->postSubmission($webform, ['value' => 'Test'], 'Save Draft');
     $log = $this->getLastSubmissionLog();
     $this->assertEqual($log->lid, 3);
     $this->assertEqual($log->sid, 2);
@@ -125,7 +125,7 @@ public function testSubmissionLog() {
     $this->assertEqual($log->variables, ['@title' => 'Test: Submission: Logging: Submission #1', '@user' => $admin_user->label()]);
 
     // Check submission updated.
-    $this->drupalPostForm("admin/structure/webform/manage/test_submission_log/submission/$sid_2/edit", [], t('Save'));
+    $this->drupalPostForm("admin/structure/webform/manage/test_submission_log/submission/$sid_2/edit", [], 'Save');
     $log = $this->getLastSubmissionLog();
     $this->assertEqual($log->lid, 7);
     $this->assertEqual($log->sid, 2);
@@ -140,8 +140,8 @@ public function testSubmissionLog() {
     $this->assertNull($log->entity_id);
 
     // Check submission deleted removes all log entries for this sid.
-    $this->drupalPostForm("admin/structure/webform/manage/test_submission_log/submission/$sid_1/delete", [], t('Delete'));
-    $this->drupalPostForm("admin/structure/webform/manage/test_submission_log/submission/$sid_2/delete", [], t('Delete'));
+    $this->drupalPostForm("admin/structure/webform/manage/test_submission_log/submission/$sid_1/delete", [], 'Delete');
+    $this->drupalPostForm("admin/structure/webform/manage/test_submission_log/submission/$sid_2/delete", [], 'Delete');
     $log = $this->getLastSubmissionLog();
     $this->assertFalse($log);
 
diff --git a/web/modules/webform/modules/webform_submission_log/webform_submission_log.info.yml b/web/modules/webform/modules/webform_submission_log/webform_submission_log.info.yml
index 517a12396b..a100eca2ce 100644
--- a/web/modules/webform/modules/webform_submission_log/webform_submission_log.info.yml
+++ b/web/modules/webform/modules/webform_submission_log/webform_submission_log.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Submission Log'
 type: module
 description: 'Dedicated logging and reporting for webform submissions.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_contact.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_contact.yml
index 84bf76431b..a59fbd0335 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_contact.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_contact.yml
@@ -35,7 +35,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send message'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -47,7 +47,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -77,6 +77,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -102,11 +107,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml
index 96f2071d8f..85ea628238 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_employee_evaluation.yml
@@ -82,7 +82,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Apply
-  
+
 css: ''
 javascript: ''
 settings:
@@ -94,7 +94,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -124,6 +124,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -149,11 +154,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_feedback.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_feedback.yml
index 8fad7b6e96..3abe8af274 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_feedback.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_feedback.yml
@@ -40,7 +40,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Submit feedback'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -52,7 +52,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -82,6 +82,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -107,11 +112,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_issue.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_issue.yml
index 34b084db8e..0349e4dc38 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_issue.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_issue.yml
@@ -123,7 +123,7 @@ elements: |
       '#type': managed_file
       '#title': Files
       '#multiple': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -135,7 +135,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -165,6 +165,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -190,11 +195,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_application.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_application.yml
index d0f855d044..1edb4d21af 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_application.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_application.yml
@@ -83,7 +83,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Apply
-  
+
 css: ''
 javascript: ''
 settings:
@@ -95,7 +95,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -125,6 +125,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -150,11 +155,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml
index f414071d7d..ea658166f4 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_job_seeker_profile.yml
@@ -23,7 +23,7 @@ elements: |
       <li>Providing more information gives a better picture to employers</li>
       <li>Salary requirements, location preferences and skill level are all important factors in the hiring decision</li>
       </ul>
-  
+
   information:
     '#title': 'Job Seeker Information'
     '#type': webform_section
@@ -83,7 +83,7 @@ elements: |
       '#type': url
       '#title': Website
       '#description': 'Enter your existing profile/resume/portfolio link.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -95,7 +95,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -125,6 +125,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -150,11 +155,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_medical_appointment.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_medical_appointment.yml
index 2f7d7953f7..c2fa3ec692 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_medical_appointment.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_medical_appointment.yml
@@ -205,7 +205,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send Request'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -217,7 +217,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -247,6 +247,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -272,11 +277,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_registration.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_registration.yml
index da68524bc4..2868a5a4eb 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_registration.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_registration.yml
@@ -52,7 +52,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Register
-  
+
 css: ''
 javascript: ''
 settings:
@@ -64,7 +64,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -94,6 +94,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -119,11 +124,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml
index f66b9adfc6..4674ce4076 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_session_evaluation.yml
@@ -44,7 +44,7 @@ elements: |
     '#type': textarea
     '#title': Comments
     '#description': 'What did you like most? What would you change? Advice for the speaker to make this session better?'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -56,7 +56,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -86,6 +86,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -111,11 +116,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_subscribe.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_subscribe.yml
index 329e0c09fc..bb9d45f2f6 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_subscribe.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_subscribe.yml
@@ -31,7 +31,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Subscribe
-  
+
 css: ''
 javascript: ''
 settings:
@@ -43,7 +43,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -73,6 +73,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -98,11 +103,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_user_profile.yml b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_user_profile.yml
index 3da2438bfe..d81a4f5208 100644
--- a/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_user_profile.yml
+++ b/web/modules/webform/modules/webform_templates/config/install/webform.webform.template_user_profile.yml
@@ -125,7 +125,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Register
-  
+
 css: ''
 javascript: ''
 settings:
@@ -137,7 +137,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -167,6 +167,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -192,11 +197,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_templates/tests/src/Functional/WebformTemplatesTest.php b/web/modules/webform/modules/webform_templates/tests/src/Functional/WebformTemplatesTest.php
index 39433f8a3e..5f75bfa59f 100644
--- a/web/modules/webform/modules/webform_templates/tests/src/Functional/WebformTemplatesTest.php
+++ b/web/modules/webform/modules/webform_templates/tests/src/Functional/WebformTemplatesTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform submission webform settings.
  *
- * @group WebformTemplates
+ * @group webform_templates
  */
 class WebformTemplatesTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_templates/webform_templates.info.yml b/web/modules/webform/modules/webform_templates/webform_templates.info.yml
index 01acd100c8..c49ca87ffb 100644
--- a/web/modules/webform/modules/webform_templates/webform_templates.info.yml
+++ b/web/modules/webform/modules/webform_templates/webform_templates.info.yml
@@ -2,11 +2,11 @@ name: 'Webform Templates'
 type: module
 description: 'Provides starter templates that can be used to create new webforms.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_templates/webform_templates.module b/web/modules/webform/modules/webform_templates/webform_templates.module
index 6a15b08124..a6c9bb56c0 100644
--- a/web/modules/webform/modules/webform_templates/webform_templates.module
+++ b/web/modules/webform/modules/webform_templates/webform_templates.module
@@ -22,6 +22,7 @@ function webform_templates_entity_type_alter(array &$entity_types) {
  * Implements hook_webform_help_info().
  */
 function webform_templates_webform_help_info() {
+  $help = [];
   $help['webform_templates'] = [
     'group' => 'forms',
     'title' => t('Templates'),
@@ -32,6 +33,5 @@ function webform_templates_webform_help_info() {
       'entity.webform.templates',
     ],
   ];
-
   return $help;
 }
diff --git a/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/config/install/webform.webform.test_element_toggles.yml b/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/config/install/webform.webform.test_element_toggles.yml
index b565344e17..aef1311481 100644
--- a/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/config/install/webform.webform.test_element_toggles.yml
+++ b/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/config/install/webform.webform.test_element_toggles.yml
@@ -49,7 +49,7 @@ elements: |
         one: One
         two: Two
         three: Three
-  
+
 css: ''
 javascript: ''
 settings:
@@ -61,7 +61,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -91,6 +91,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -116,11 +121,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/webform_toggles_test.info.yml b/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/webform_toggles_test.info.yml
index 42aef3c159..1bf80787b1 100644
--- a/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/webform_toggles_test.info.yml
+++ b/web/modules/webform/modules/webform_toggles/tests/modules/webform_toggles_test/webform_toggles_test.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform Toggles Test'
+name: 'Webform Toggles test'
 type: module
-description: 'Support module for webform that provides toggles element working examples.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform toggles element testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform_toggles'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_toggles/tests/src/Functional/WebformTogglesElementTest.php b/web/modules/webform/modules/webform_toggles/tests/src/Functional/WebformTogglesElementTest.php
index b92549cd26..a0b9d70010 100644
--- a/web/modules/webform/modules/webform_toggles/tests/src/Functional/WebformTogglesElementTest.php
+++ b/web/modules/webform/modules/webform_toggles/tests/src/Functional/WebformTogglesElementTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for toggles element.
  *
- * @group Webform
+ * @group webform_toggles
  */
 class WebformTogglesElementTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/modules/webform_toggles/webform_toggles.info.yml b/web/modules/webform/modules/webform_toggles/webform_toggles.info.yml
index ab0d22fa01..114a8a6189 100644
--- a/web/modules/webform/modules/webform_toggles/webform_toggles.info.yml
+++ b/web/modules/webform/modules/webform_toggles/webform_toggles.info.yml
@@ -1,12 +1,12 @@
 name: 'Webform Toggles'
 type: module
-description: 'Provides a form element for toggling a single on/off state. The Toogles library is not being maintained and has major accessibility issues.'
+description: 'Provides a webform element for toggling a single on/off state. The Toogles library is not being maintained and has major accessibility issues.'
 package: 'Webform [DEPRECATED]'
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_toggles/webform_toggles.libraries.yml b/web/modules/webform/modules/webform_toggles/webform_toggles.libraries.yml
index 008cc9aeb1..a4a1802796 100644
--- a/web/modules/webform/modules/webform_toggles/webform_toggles.libraries.yml
+++ b/web/modules/webform/modules/webform_toggles/webform_toggles.libraries.yml
@@ -28,3 +28,4 @@ libraries.jquery.toggles:
     /libraries/jquery.toggles/toggles.min.js: { minified: true }
   dependencies:
     - core/jquery
+  deprecated: The "%library_id%" asset library is deprecated. This project is not maintained anymore. See https://github.com/simontabor/jquery-toggles/
diff --git a/web/modules/webform/modules/webform_ui/css/webform_ui.module.css b/web/modules/webform/modules/webform_ui/css/webform_ui.module.css
index 362aa55923..a6867d1834 100644
--- a/web/modules/webform/modules/webform_ui/css/webform_ui.module.css
+++ b/web/modules/webform/modules/webform_ui/css/webform_ui.module.css
@@ -221,3 +221,7 @@ thead th .dropbutton {
 .form--inline.webform-ui-element-form-inline--input .form-item input[type="number"] {
   width: 140px;
 }
+
+.form--inline.webform-ui-element-form-inline--input .form-item input.webform-ui-element-form-inline--input-double-width {
+  width: 300px;
+}
diff --git a/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementDeleteForm.php b/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementDeleteForm.php
index 20b4827516..3e990dd4a8 100644
--- a/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementDeleteForm.php
+++ b/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementDeleteForm.php
@@ -26,14 +26,14 @@ class WebformUiElementDeleteForm extends WebformDeleteFormBase {
   protected $renderer;
 
   /**
-   * Webform element manager.
+   * The webform element manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
   protected $elementManager;
 
   /**
-   * Webform element validator.
+   * The webform element validator.
    *
    * @var \Drupal\webform\WebformEntityElementsValidatorInterface
    */
diff --git a/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementFormBase.php b/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementFormBase.php
index 98a71c5f06..e5f0773ba5 100644
--- a/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementFormBase.php
+++ b/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementFormBase.php
@@ -58,14 +58,14 @@ abstract class WebformUiElementFormBase extends FormBase implements WebformUiEle
   protected $entityFieldManager;
 
   /**
-   * Webform element manager.
+   * The webform element manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
   protected $elementManager;
 
   /**
-   * Webform element validator.
+   * The webform element validator.
    *
    * @var \Drupal\webform\WebformEntityElementsValidatorInterface
    */
@@ -451,7 +451,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $this->messenger()->addStatus($this->t('%title has been @action.', $t_args));
 
     // Determine add element parent key.
-    $save_and_add_element = ($op == (string) $this->t('Save + Add element')) ? TRUE : FALSE;
+    $save_and_add_element = ($op === (string) $this->t('Save + Add element')) ? TRUE : FALSE;
     $add_element = ($element_plugin->isContainer($this->getElement())) ? $key : $parent_key;
     $add_element = $add_element ? Html::getClass($add_element) : '_root_';
 
@@ -466,7 +466,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
     // Still set the redirect URL just to be safe.
     // Variants require the entire page to be reloaded so that Variants tab
-    // is made visible,
+    // is made visible.
     if ($this->getWebformElementPlugin() instanceof WebformElementVariantInterface) {
       $query = ['reload' => 'true'];
     }
@@ -543,7 +543,7 @@ protected function isParentElementFlexbox($key = NULL, $parent_key = NULL) {
 
     // Check the parent element #type.
     if ($parent_key && isset($elements[$parent_key]) && isset($elements[$parent_key]['#type'])) {
-      return ($elements[$parent_key]['#type'] == 'webform_flexbox') ? TRUE : FALSE;
+      return ($elements[$parent_key]['#type'] === 'webform_flexbox') ? TRUE : FALSE;
     }
 
     return FALSE;
diff --git a/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementTypeFormBase.php b/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementTypeFormBase.php
index 7dc9a63856..85b00c36b5 100644
--- a/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementTypeFormBase.php
+++ b/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementTypeFormBase.php
@@ -271,7 +271,7 @@ protected function buildRow(WebformElementInterface $webform_element, Url $url,
     // modal, then clicking the image button opens another modal,
     // which closes the original modal.
     // @todo Remove the below workaround once this issue is resolved.
-    if ($webform_element->getTypeName() == 'processed_text' && !WebformDialogHelper::useOffCanvas()) {
+    if ($webform_element->getTypeName() === 'processed_text' && !WebformDialogHelper::useOffCanvas()) {
       unset($row['type']['#attributes']);
       unset($row['operation']['#attributes']);
       if (isset($row['operation'])) {
diff --git a/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementTypeSelectForm.php b/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementTypeSelectForm.php
index 5279403d70..77a97437f1 100644
--- a/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementTypeSelectForm.php
+++ b/web/modules/webform/modules/webform_ui/src/Form/WebformUiElementTypeSelectForm.php
@@ -4,7 +4,6 @@
 
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Url;
-use Drupal\webform\Plugin\WebformElementWizardPageInterface;
 use Drupal\webform\WebformInterface;
 
 /**
@@ -47,11 +46,6 @@ public function buildForm(array $form, FormStateInterface $form_state, WebformIn
         continue;
       }
 
-      // Skip wizard-type pages, which have a dedicated URL.
-      if ($webform_element instanceof WebformElementWizardPageInterface) {
-        continue;
-      }
-
       $category_name = (string) $webform_element->getPluginCategory();
       if (!isset($categories[$category_name])) {
         $categories[$category_name] = $category_index++;
diff --git a/web/modules/webform/modules/webform_ui/src/WebformUiEntityElementsForm.php b/web/modules/webform/modules/webform_ui/src/WebformUiEntityElementsForm.php
index f60d8998d8..466d5f8c9c 100644
--- a/web/modules/webform/modules/webform_ui/src/WebformUiEntityElementsForm.php
+++ b/web/modules/webform/modules/webform_ui/src/WebformUiEntityElementsForm.php
@@ -48,21 +48,21 @@ class WebformUiEntityElementsForm extends BundleEntityFormBase {
   protected $renderer;
 
   /**
-   * Element info manager.
+   * The element info manager.
    *
    * @var \Drupal\Core\Render\ElementInfoManagerInterface
    */
   protected $elementInfo;
 
   /**
-   * Webform element manager.
+   * The webform element manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
   protected $elementManager;
 
   /**
-   * Webform element validator.
+   * The webform element validator.
    *
    * @var \Drupal\webform\WebformEntityElementsValidatorInterface
    */
@@ -502,8 +502,9 @@ protected function getElementRow(array $element, $delta, array $parent_options)
       $row_class[] = 'webform-ui-element-disabled';
     }
 
-    // Add element key.
+    // Add element key and type.
     $row['#attributes']['data-webform-key'] = $element['#webform_key'];
+    $row['#attributes']['data-webform-type'] = (isset($element['#type'])) ? $element['#type'] : '';
 
     $row['#attributes']['class'] = $row_class;
 
@@ -683,7 +684,7 @@ protected function getElementRow(array $element, $delta, array $parent_options)
     // modal, then clicking the image button opens another modal,
     // which closes the original modal.
     // @todo Remove the below workaround once this issue is resolved.
-    if ($webform_element->getPluginId() == 'processed_text' && !WebformDialogHelper::useOffCanvas()) {
+    if ($webform_element->getPluginId() === 'processed_text' && !WebformDialogHelper::useOffCanvas()) {
       unset($row['operations']['#links']['edit']['attributes']);
     }
     if (!$is_container) {
diff --git a/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementActionsTest.php b/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementActionsTest.php
index c63a14ddd5..0d9807fa18 100644
--- a/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementActionsTest.php
+++ b/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementActionsTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform UI actions element.
  *
- * @group WebformUi
+ * @group webform_ui
  */
 class WebformUiElementActionsTest extends WebformBrowserTestBase {
 
@@ -33,7 +33,7 @@ public function testActionsElements() {
     ];
     $this->createWebform($values, $elements);
 
-    // Confirm submit buttons are customizable.
+    // Check that submit buttons are customizable.
     $this->drupalGet('/admin/structure/webform/manage/test');
     $this->assertLink('Customize');
 
@@ -42,7 +42,7 @@ public function testActionsElements() {
       ->set('element.excluded_elements.webform_actions', 'webform_actions')
       ->save();
 
-    // Confirm submit buttons are not customizable.
+    // Check that submit buttons are not customizable.
     $this->drupalGet('/admin/structure/webform/manage/test');
     $this->assertNoLink('Customize');
   }
diff --git a/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementDefaultValueTest.php b/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementDefaultValueTest.php
index 35b844e1e5..2d65eed0d4 100644
--- a/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementDefaultValueTest.php
+++ b/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementDefaultValueTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform UI element.
  *
- * @group WebformUi
+ * @group webform_ui
  */
 class WebformUiElementDefaultValueTest extends WebformBrowserTestBase {
 
@@ -30,7 +30,7 @@ public function testElementDefaultValue() {
     /**************************************************************************/
 
     // Check validation when trying to set default value.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', [], t('Set default value'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', [], 'Set default value');
     $this->assertRaw('Key field is required.');
     $this->assertRaw('Title field is required.');
 
@@ -39,12 +39,12 @@ public function testElementDefaultValue() {
       'key' => 'textfield',
       'properties[title]' => 'textfield',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', $edit, t('Set default value'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', $edit, 'Set default value');
     $this->assertRaw('<label for="edit-default-value">textfield</label>');
     $this->assertFieldByName('default_value', '');
 
     // Check setting the text field's default value.
-    $this->drupalPostForm(NULL, ['default_value' => '{default value}'], t('Update default value'));
+    $this->drupalPostForm(NULL, ['default_value' => '{default value}'], 'Update default value');
     $this->assertFieldByName('properties[default_value]', '{default value}');
 
     /**************************************************************************/
@@ -57,11 +57,11 @@ public function testElementDefaultValue() {
       'properties[title]' => 'textfield',
       'properties[multiple][container][cardinality]' => '-1',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', $edit, t('Set default value'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', $edit, 'Set default value');
     $this->assertFieldByName('default_value[items][0][_item_]', '');
 
     // Check setting the text field's default value.
-    $this->drupalPostForm(NULL, ['default_value[items][0][_item_]' => '{default value}'], t('Update default value'));
+    $this->drupalPostForm(NULL, ['default_value[items][0][_item_]' => '{default value}'], 'Update default value');
     $this->assertFieldByName('properties[default_value]', '{default value}');
 
     /**************************************************************************/
@@ -73,7 +73,7 @@ public function testElementDefaultValue() {
       'key' => 'address',
       'properties[title]' => 'address',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/webform_address', $edit, t('Set default value'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/webform_address', $edit, 'Set default value');
     $this->assertFieldByName('default_value[address]', '');
     $this->assertFieldByName('default_value[address_2]', '');
 
@@ -82,7 +82,7 @@ public function testElementDefaultValue() {
       'default_value[address]' => '{address}',
       'default_value[address_2]' => '{address_2}',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Update default value'));
+    $this->drupalPostForm(NULL, $edit, 'Update default value');
     $this->assertRaw('address: &#039;{address}&#039;
 address_2: &#039;{address_2}&#039;
 city: &#039;&#039;
@@ -91,7 +91,7 @@ public function testElementDefaultValue() {
 country: &#039;&#039;');
 
     // Check default value is passed set default value form.
-    $this->drupalPostForm(NULL, [], t('Set default value'));
+    $this->drupalPostForm(NULL, [], 'Set default value');
     $this->assertFieldByName('default_value[address]', '{address}');
     $this->assertFieldByName('default_value[address_2]', '{address_2}');
   }
diff --git a/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementPropertiesTest.php b/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementPropertiesTest.php
index df4cb18e61..8016d712c0 100644
--- a/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementPropertiesTest.php
+++ b/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementPropertiesTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform UI element properties.
  *
- * @group WebformUi
+ * @group webform_ui
  */
 class WebformUiElementPropertiesTest extends WebformBrowserTestBase {
 
@@ -37,7 +37,7 @@ class WebformUiElementPropertiesTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create filters.
@@ -59,7 +59,7 @@ public function testElementProperties() {
       $webform_elements = Webform::load($webform_id);
       $original_elements = $webform_elements->getElementsDecodedAndFlattened();
       foreach ($original_elements as $key => $original_element) {
-        $this->drupalPostForm('/admin/structure/webform/manage/' . $webform_elements->id() . '/element/' . $key . '/edit', [], t('Save'));
+        $this->drupalPostForm('/admin/structure/webform/manage/' . $webform_elements->id() . '/element/' . $key . '/edit', [], 'Save');
 
         // Must reset the webform entity cache so that the update elements can
         // be loaded.
diff --git a/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementTest.php b/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementTest.php
index c40611013c..3feb18d788 100644
--- a/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementTest.php
+++ b/web/modules/webform/modules/webform_ui/tests/src/Functional/WebformUiElementTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform UI element.
  *
- * @group WebformUi
+ * @group webform_ui
  */
 class WebformUiElementTest extends WebformBrowserTestBase {
 
@@ -29,7 +29,7 @@ class WebformUiElementTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
     // Disable description help icon.
     $this->config('webform.settings')->set('ui.description_help', FALSE)->save();
@@ -76,7 +76,7 @@ public function testElements() {
       'webform_ui_elements[email][weight]' => 2,
       'webform_ui_elements[name][weight]' => 3,
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact', $edit, t('Save elements'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact', $edit, 'Save elements');
 
     \Drupal::entityTypeManager()->getStorage('webform_submission')->resetCache();
     \Drupal::entityTypeManager()->getStorage('webform')->resetCache();
@@ -114,7 +114,7 @@ public function testElements() {
     $edit = [
       'webform_ui_elements[details_01][parent_key]' => 'details_01',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test', $edit, t('Save elements'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test', $edit, 'Save elements');
     $this->assertRaw('Parent <em class="placeholder">details_01</em> key is not valid.');
 
     // Check setting containers to one another displays an error.
@@ -122,7 +122,7 @@ public function testElements() {
       'webform_ui_elements[details_01][parent_key]' => 'details_02',
       'webform_ui_elements[details_02][parent_key]' => 'details_01',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test', $edit, t('Save elements'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test', $edit, 'Save elements');
     $this->assertRaw('Parent <em class="placeholder">details_01</em> key is not valid.');
     $this->assertRaw('Parent <em class="placeholder">details_02</em> key is not valid.');
 
@@ -138,7 +138,7 @@ public function testElements() {
     $edit = [
       'webform_ui_elements[name][required]' => FALSE,
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact', $edit, t('Save elements'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact', $edit, 'Save elements');
     $this->assertNoFieldChecked('edit-webform-ui-elements-name-required');
 
     /**************************************************************************/
@@ -152,19 +152,19 @@ public function testElements() {
     $this->assertRaw('Save + Add element');
 
     // Create element.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', ['key' => 'test', 'properties[title]' => 'Test'], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', ['key' => 'test', 'properties[title]' => 'Test'], 'Save');
 
     // Check elements URL contains ?update query string parameter.
     $this->assertUrl('admin/structure/webform/manage/contact', ['query' => ['update' => 'test']]);
 
     // Check that save elements removes ?update query string parameter.
-    $this->drupalPostForm(NULL, [], t('Save elements'));
+    $this->drupalPostForm(NULL, [], 'Save elements');
 
     // Check that save elements removes ?update query string parameter.
     $this->assertUrl('admin/structure/webform/manage/contact', ['query' => ['update' => 'test']]);
 
     // Create validate unique element.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', ['key' => 'test', 'properties[title]' => 'Test'], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', ['key' => 'test', 'properties[title]' => 'Test'], 'Save');
     $this->assertRaw('The machine-readable name is already in use. It must be unique.');
 
     // Check read element.
@@ -173,7 +173,7 @@ public function testElements() {
     $this->assertRaw('<input data-drupal-selector="edit-test" type="text" id="edit-test" name="test" value="" size="60" maxlength="255" class="form-text" />');
 
     // Update element.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/test/edit', ['properties[title]' => 'Test 123', 'properties[default_value]' => 'This is a default value'], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/test/edit', ['properties[title]' => 'Test 123', 'properties[default_value]' => 'This is a default value'], 'Save');
 
     // Check elements URL contains ?update query string parameter.
     $this->assertUrl('admin/structure/webform/manage/contact', ['query' => ['update' => 'test']]);
@@ -184,11 +184,11 @@ public function testElements() {
     $this->assertRaw('<input data-drupal-selector="edit-test" type="text" id="edit-test" name="test" value="This is a default value" size="60" maxlength="255" class="form-text" />');
 
     // Check that 'test' element is being added to the webform_submission_data table.
-    $this->drupalPostForm('/webform/contact/test', [], t('Send message'));
+    $this->drupalPostForm('/webform/contact/test', [], 'Send message');
     $this->assertEqual(1, \Drupal::database()->query("SELECT COUNT(sid) FROM {webform_submission_data} WHERE webform_id='contact' AND name='test'")->fetchField());
 
     // Check delete element.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/test/delete', [], t('Delete'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/test/delete', [], 'Delete');
     $this->drupalGet('/webform/contact');
     $this->assertNoRaw('<label for="edit-test">Test 123</label>');
     $this->assertNoRaw('<input data-drupal-selector="edit-test" type="text" id="edit-test" name="test" value="This is a default value" size="60" maxlength="255" class="form-text" />');
@@ -209,7 +209,7 @@ public function testElements() {
     /**************************************************************************/
 
     // Check create element.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', ['key' => 'test', 'properties[title]' => 'Test'], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/textfield', ['key' => 'test', 'properties[title]' => 'Test'], 'Save');
 
     // Check element type.
     $this->drupalGet('/admin/structure/webform/manage/contact/element/test/edit');
@@ -239,7 +239,7 @@ public function testElements() {
     $this->assertRaw('(Changing from <em class="placeholder">Text field</em>)');
 
     // Change the element type.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/test/edit', [], t('Save'), ['query' => ['type' => 'value']]);
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/test/edit', [], 'Save', ['query' => ['type' => 'value']]);
 
     // Change the element type from 'textfield' to 'value'.
     $this->drupalGet('/admin/structure/webform/manage/contact/element/test/edit');
@@ -248,7 +248,7 @@ public function testElements() {
     $this->assertRaw('Value <a href="' . $base_path . 'admin/structure/webform/manage/contact/element/test/change" class="button button--small webform-ajax-link" data-dialog-type="modal" data-dialog-options="{&quot;width&quot;:800,&quot;dialogClass&quot;:&quot;webform-ui-dialog&quot;}" data-drupal-selector="edit-change-type" id="edit-change-type">Change</a>');
 
     // Check color element that does not have related type and return 404.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/color', ['key' => 'test_color', 'properties[title]' => 'Test color'], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/color', ['key' => 'test_color', 'properties[title]' => 'Test color'], 'Save');
     $this->drupalGet('/admin/structure/webform/manage/contact/element/test_color/change');
     $this->assertResponse(404);
 
@@ -260,7 +260,7 @@ public function testElements() {
     $edit = [
       'properties[default_value]' => 'not a valid date',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_element_date/element/date_min_max_dynamic/edit', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_date/element/date_min_max_dynamic/edit', $edit, 'Save');
     $this->assertRaw('The Default value could not be interpreted in <a href="https://www.gnu.org/software/tar/manual/html_chapter/tar_7.html#Date-input-formats">GNU Date Input Format</a>.');
   }
 
diff --git a/web/modules/webform/modules/webform_ui/tests/src/FunctionalJavascript/WebformUiElementJavaScriptTest.php b/web/modules/webform/modules/webform_ui/tests/src/FunctionalJavascript/WebformUiElementJavaScriptTest.php
index ab5e26c46c..5f86ccb02a 100644
--- a/web/modules/webform/modules/webform_ui/tests/src/FunctionalJavascript/WebformUiElementJavaScriptTest.php
+++ b/web/modules/webform/modules/webform_ui/tests/src/FunctionalJavascript/WebformUiElementJavaScriptTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests webform UI element JavasScript.
  *
- * @group webform_javascript
+ * @group webform_ui
  */
 class WebformUiElementJavaScriptTest extends WebformWebDriverTestBase {
 
diff --git a/web/modules/webform/modules/webform_ui/webform_ui.info.yml b/web/modules/webform/modules/webform_ui/webform_ui.info.yml
index a6811b45fe..30a6d1462c 100644
--- a/web/modules/webform/modules/webform_ui/webform_ui.info.yml
+++ b/web/modules/webform/modules/webform_ui/webform_ui.info.yml
@@ -2,11 +2,11 @@ name: 'Webform UI'
 type: module
 description: 'Provides a user interface for building and maintaining webforms.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/modules/webform_ui/webform_ui.links.action.yml b/web/modules/webform/modules/webform_ui/webform_ui.links.action.yml
index 99b05d9de2..6894c94a10 100644
--- a/web/modules/webform/modules/webform_ui/webform_ui.links.action.yml
+++ b/web/modules/webform/modules/webform_ui/webform_ui.links.action.yml
@@ -2,6 +2,7 @@ entity.webform_ui.element:
   route_name: entity.webform_ui.element
   title: 'Add element'
   class: '\Drupal\webform\Plugin\Menu\LocalAction\WebformDialogLocalAction'
+  weight: 0
   dialog: normal
   attributes:
     id: 'webform-ui-add-element'
@@ -12,16 +13,20 @@ entity.webform_ui.element.page:
   route_name: entity.webform_ui.element.add_page
   title: 'Add page'
   class: '\Drupal\webform\Plugin\Menu\LocalAction\WebformDialogLocalAction'
+  weight: 10
   off_canvas: normal
   attributes:
     id: 'webform-ui-add-page'
   appears_on:
     - entity.webform.edit_form
 
+# Webform cards use 'weight: 20'.
+
 entity.webform_ui.element.layout:
   route_name: entity.webform_ui.element.add_layout
   title: 'Add layout'
   class: '\Drupal\webform\Plugin\Menu\LocalAction\WebformDialogLocalAction'
+  weight: 30
   off_canvas: normal
   attributes:
     id: 'webform-ui-add-layout'
diff --git a/web/modules/webform/modules/webform_ui/webform_ui.module b/web/modules/webform/modules/webform_ui/webform_ui.module
index e87cac681e..d8d79c3016 100644
--- a/web/modules/webform/modules/webform_ui/webform_ui.module
+++ b/web/modules/webform/modules/webform_ui/webform_ui.module
@@ -52,13 +52,11 @@ function webform_ui_entity_type_alter(array &$entity_types) {
  * @see Drupal.behaviors.webformUiElementsActionsSecondary
  */
 function webform_ui_preprocess_menu_local_action(&$variables) {
-  if (\Drupal::routeMatch()->getRouteName() != 'entity.webform.edit_form') {
+  if (\Drupal::routeMatch()->getRouteName() !== 'entity.webform.edit_form') {
     return;
   }
 
-  if (!in_array($variables['link']['#url']->getRouteName(), ['entity.webform_ui.element.add_page', 'entity.webform_ui.element.add_layout'])) {
-    return;
+  if (in_array($variables['link']['#url']->getRouteName(), ['entity.webform_ui.element.add_page', 'entity.webform_ui.element.add_layout'])) {
+    $variables['link']['#options']['attributes']['class'][] = 'button--secondary';
   }
-
-  $variables['link']['#options']['attributes']['class'][] = 'button--secondary';
 }
diff --git a/web/modules/webform/reports/accessiblity/text/example_accessibility_wizard.txt b/web/modules/webform/reports/accessiblity/text/example_accessibility_wizard.txt
index 87a2e95ae6..8bcaefe8e4 100644
--- a/web/modules/webform/reports/accessiblity/text/example_accessibility_wizard.txt
+++ b/web/modules/webform/reports/accessiblity/text/example_accessibility_wizard.txt
@@ -8,7 +8,47 @@ Results for URL: http://localhost/wf/webform/example_accessibility_wizard
  • Error: This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of 3.12:1. Recommendation: change background to #0378d5.
    ├── WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail
    ├── #webform-submission-example-accessibility-wizard-add-form > div:nth-child(7) > ul > li:nth-child(1) > span:nth-child(1)
-   └── <span class="progress-marker">1</span>
+   └── <span class="progress-marker" data-webform-progress-step="" data-webform-progress-link="">1</span>
 
-1 Errors
+ • Error: This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of 4.48:1. Recommendation: change background to #767676.
+   ├── WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail
+   ├── #webform-submission-example-accessibility-wizard-add-form > div:nth-child(7) > ul > li:nth-child(2) > span:nth-child(1)
+   └── <span class="progress-marker" data-webform-progress-step="" data-webform-progress-link="">2</span>
+
+ • Error: This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of 4.48:1. Recommendation: change text colour to #767676.
+   ├── WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail
+   ├── #webform-submission-example-accessibility-wizard-add-form > div:nth-child(7) > ul > li:nth-child(2) > span:nth-child(2) > span
+   └── <span class="progress-title" data-webform-progress-link=""> <span class="visua...</span>
+
+ • Error: This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of 4.48:1. Recommendation: change background to #767676.
+   ├── WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail
+   ├── #webform-submission-example-accessibility-wizard-add-form > div:nth-child(7) > ul > li:nth-child(3) > span:nth-child(1)
+   └── <span class="progress-marker" data-webform-progress-step="" data-webform-progress-link="">3</span>
+
+ • Error: This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of 4.48:1. Recommendation: change text colour to #767676.
+   ├── WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail
+   ├── #webform-submission-example-accessibility-wizard-add-form > div:nth-child(7) > ul > li:nth-child(3) > span:nth-child(2) > span
+   └── <span class="progress-title" data-webform-progress-link=""> <span class="visua...</span>
+
+ • Error: This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of 4.48:1. Recommendation: change background to #767676.
+   ├── WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail
+   ├── #webform-submission-example-accessibility-wizard-add-form > div:nth-child(7) > ul > li:nth-child(4) > span:nth-child(1)
+   └── <span class="progress-marker" data-webform-progress-step="" data-webform-progress-link="">4</span>
+
+ • Error: This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of 4.48:1. Recommendation: change text colour to #767676.
+   ├── WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail
+   ├── #webform-submission-example-accessibility-wizard-add-form > div:nth-child(7) > ul > li:nth-child(4) > span:nth-child(2) > span
+   └── <span class="progress-title" data-webform-progress-link=""> <span class="visua...</span>
+
+ • Error: This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of 4.48:1. Recommendation: change background to #767676.
+   ├── WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail
+   ├── #webform-submission-example-accessibility-wizard-add-form > div:nth-child(7) > ul > li:nth-child(5) > span:nth-child(1)
+   └── <span class="progress-marker" data-webform-progress-step="" data-webform-progress-link="">5</span>
+
+ • Error: This element has insufficient contrast at this conformance level. Expected a contrast ratio of at least 4.5:1, but text in this element has a contrast ratio of 4.48:1. Recommendation: change text colour to #767676.
+   ├── WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail
+   ├── #webform-submission-example-accessibility-wizard-add-form > div:nth-child(7) > ul > li:nth-child(5) > span:nth-child(2) > span
+   └── <span class="progress-title" data-webform-progress-link=""> <span class="visua...</span>
+
+9 Errors
 
diff --git a/web/modules/webform/src/Access/WebformSubmissionAccess.php b/web/modules/webform/src/Access/WebformSubmissionAccess.php
index e58ad9796b..82d3ef19ad 100644
--- a/web/modules/webform/src/Access/WebformSubmissionAccess.php
+++ b/web/modules/webform/src/Access/WebformSubmissionAccess.php
@@ -12,7 +12,7 @@
 class WebformSubmissionAccess {
 
   /**
-   * Check whether a webform submissions' webform has wizard pages.
+   * Check whether a webform submissions' webform has wizard pages/cards.
    *
    * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
    *   A webform submission.
@@ -21,8 +21,10 @@ class WebformSubmissionAccess {
    *   The access result.
    */
   public static function checkWizardPagesAccess(WebformSubmissionInterface $webform_submission) {
-    $condition = $webform_submission->getWebform()->hasWizardPages();
-    return AccessResult::allowedIf($condition);
+    $elements_raw = $webform_submission->getWebform()->getElementsRaw();
+    $has_pages = (strpos($elements_raw, "'#type': webform_wizard_page") !== FALSE
+      || strpos($elements_raw, "'#type': webform_card") !== FALSE);
+    return AccessResult::allowedIf($has_pages);
   }
 
   /**
diff --git a/web/modules/webform/src/Breadcrumb/WebformBreadcrumbBuilder.php b/web/modules/webform/src/Breadcrumb/WebformBreadcrumbBuilder.php
index 2a22502679..963c908c14 100644
--- a/web/modules/webform/src/Breadcrumb/WebformBreadcrumbBuilder.php
+++ b/web/modules/webform/src/Breadcrumb/WebformBreadcrumbBuilder.php
@@ -29,7 +29,7 @@ class WebformBreadcrumbBuilder implements BreadcrumbBuilderInterface {
   protected $type;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
@@ -88,7 +88,7 @@ public function applies(RouteMatchInterface $route_match) {
     /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
     $webform_submission = ($route_match->getParameter('webform_submission') instanceof WebformSubmissionInterface) ? $route_match->getParameter('webform_submission') : NULL;
 
-    if ((count($args) > 2) && $args[0] == 'entity' && ($args[2] == 'webform' || $args[2] == 'webform_submission')) {
+    if ((count($args) > 2) && $args[0] === 'entity' && ($args[2] === 'webform' || $args[2] === 'webform_submission')) {
       $this->type = 'webform_source_entity';
     }
     elseif ($route_name === 'webform.reports_plugins.elements.test') {
@@ -142,7 +142,7 @@ public function applies(RouteMatchInterface $route_match) {
   public function build(RouteMatchInterface $route_match) {
     $route_name = $route_match->getRouteName();
 
-    if ($this->type == 'webform_source_entity') {
+    if ($this->type === 'webform_source_entity') {
       $source_entity = $this->requestHandler->getCurrentSourceEntity(['webform', 'webform_submission']);
       $entity_type = $source_entity->getEntityTypeId();
       $entity_id = $source_entity->id();
@@ -162,14 +162,14 @@ public function build(RouteMatchInterface $route_match) {
         }
       }
     }
-    elseif ($this->type == 'webform_help') {
+    elseif ($this->type === 'webform_help') {
       $breadcrumb = new Breadcrumb();
       $breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));
       $breadcrumb->addLink(Link::createFromRoute($this->t('Administration'), 'system.admin'));
       $breadcrumb->addLink(Link::createFromRoute($this->t('Help'), 'help.main'));
       $breadcrumb->addLink(Link::createFromRoute($this->t('Webform'), 'help.page', ['name' => 'webform']));
     }
-    elseif ($this->type == 'webform_plugins_elements') {
+    elseif ($this->type === 'webform_plugins_elements') {
       $breadcrumb = new Breadcrumb();
       $breadcrumb->addLink(Link::createFromRoute($this->t('Home'), '<front>'));
       $breadcrumb->addLink(Link::createFromRoute($this->t('Administration'), 'system.admin'));
@@ -185,7 +185,7 @@ public function build(RouteMatchInterface $route_match) {
       switch ($this->type) {
         case 'webform_config':
           $breadcrumb->addLink(Link::createFromRoute($this->t('Configuration'), 'webform.config'));
-          if (strpos($route_name, 'config_translation.item.') === 0 && $route_name != 'config_translation.item.overview.webform.config') {
+          if (strpos($route_name, 'config_translation.item.') === 0 && $route_name !== 'config_translation.item.overview.webform.config') {
             $breadcrumb->addLink(Link::createFromRoute($this->t('Translate'), 'config_translation.item.overview.webform.config'));
           }
           break;
@@ -273,4 +273,14 @@ public function build(RouteMatchInterface $route_match) {
     return $breadcrumb;
   }
 
+  /**
+   * Get the type of webform breadcrumb.
+   *
+   * @return string
+   *   The type of webform breadcrumb.
+   */
+  public function getType() {
+    return $this->type;
+  }
+
 }
diff --git a/web/modules/webform/src/Commands/WebformCliService.php b/web/modules/webform/src/Commands/WebformCliService.php
index e012f06b7f..bb2d06adc7 100644
--- a/web/modules/webform/src/Commands/WebformCliService.php
+++ b/web/modules/webform/src/Commands/WebformCliService.php
@@ -457,7 +457,7 @@ public function drush_webform_import($webform_id = NULL, $import_uri = NULL) {
    */
   public function drush_webform_purge_validate($webform_id = NULL) {
     // If webform id is set to 'all' or not included skip validation.
-    if ($this->drush_get_option('all') || $webform_id == NULL) {
+    if ($this->drush_get_option('all') || $webform_id === NULL) {
       return;
     }
 
@@ -483,7 +483,7 @@ public function drush_webform_purge($webform_id = NULL) {
     }
 
     // Set the webform.
-    $webform = ($webform_id == 'all') ? NULL : Webform::load($webform_id);
+    $webform = ($webform_id === 'all') ? NULL : Webform::load($webform_id);
 
     /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
     $entity_type_manager = \Drupal::service('entity_type.manager');
@@ -577,7 +577,7 @@ public function drush_webform_tidy($target = NULL) {
       $dependencies = FALSE;
     }
 
-    $files = file_scan_directory($file_directory_path, ($prefix) ? '/^' . preg_quote($prefix, '/.') . '.*\.yml$/' : '/.*\.yml$/');
+    $files = \Drupal::service('file_system')->scanDirectory($file_directory_path, ($prefix) ? '/^' . preg_quote($prefix, '/.') . '.*\.yml$/' : '/.*\.yml$/');
     $this->drush_print($this->dt("Reviewing @count YAML configuration '@prefix.*' files in '@module'.", ['@count' => count($files), '@module' => $target, '@prefix' => $prefix]));
 
     $total = 0;
@@ -619,7 +619,7 @@ public function drush_webform_tidy($target = NULL) {
 
       // Tidy and add new line to the end of the tidied file.
       $tidied_yaml = WebformYaml::encode($data) . PHP_EOL;
-      if ($tidied_yaml != $original_yaml) {
+      if ($tidied_yaml !== $original_yaml) {
         $this->drush_print($this->dt('Tidying @file…', ['@file' => $file->filename]));
         file_put_contents($file->uri, $tidied_yaml);
         $total++;
@@ -780,7 +780,7 @@ public function drush_webform_libraries_download() {
       $files = scandir($temp_location);
       // Remove directories (. ..)
       unset($files[0], $files[1]);
-      if ((count($files) == 1) && is_dir($temp_location . '/' . current($files))) {
+      if ((count($files) === 1) && is_dir($temp_location . '/' . current($files))) {
         $temp_location .= '/' . current($files);
       }
       $this->drush_move_dir($temp_location, $download_location);
@@ -993,7 +993,7 @@ public function drush_webform_docs() {
       $help_html = \Drupal::service('renderer')->renderPlain($help_section);
       $help_html = $this->_drush_webform_docs_tidy($help_html);
 
-      if ($help_name == 'videos') {
+      if ($help_name === 'videos') {
         // Download YouTube thumbnails so that they can be updated to
         // https://www.drupal.org/files/
         preg_match_all('#https://img.youtube.com/vi/([^/]+)/0.jpg#', $help_html, $matches);
@@ -1314,7 +1314,7 @@ function $command_hook() {
 // @codingStandardsIgnoreFile
 
 /**
- * This is file was generated using Drush. DO NOT EDIT. 
+ * This is file was generated using Drush. DO NOT EDIT.
  *
  * @see drush webform-generate-commands
  * @see \Drupal\webform\Commands\DrushCliServiceBase::generate_commands_drush8
@@ -1452,7 +1452,7 @@ public function $command_method($command_params) {
 // @codingStandardsIgnoreFile
 
 /**
- * This is file was generated using Drush. DO NOT EDIT. 
+ * This is file was generated using Drush. DO NOT EDIT.
  *
  * @see drush webform-generate-commands
  * @see \Drupal\webform\Commands\DrushCliServiceBase::generate_commands_drush9
@@ -1512,7 +1512,7 @@ protected function _drush_webform_validate($webform_id = NULL) {
         return $this->drush_set_error($this->dt("'@title' (@entity_type:@entity_id) does not reference a webform.", $dt_args));
       }
 
-      if ($source_entity->webform->target_id != $webform_id) {
+      if ($source_entity->webform->target_id !== $webform_id) {
         return $this->drush_set_error($this->dt("'@title' (@entity_type:@entity_id) does not have a '@webform_id' webform associated with it.", $dt_args));
       }
     }
diff --git a/web/modules/webform/src/Controller/WebformElementController.php b/web/modules/webform/src/Controller/WebformElementController.php
index 9d1378b26f..5fd82e9023 100644
--- a/web/modules/webform/src/Controller/WebformElementController.php
+++ b/web/modules/webform/src/Controller/WebformElementController.php
@@ -56,7 +56,7 @@ public function close($storage, $id) {
   public function autocomplete(Request $request, WebformInterface $webform, $key) {
     // Get autocomplete query.
     $q = $request->query->get('q') ?: '';
-    if ($q == '') {
+    if ($q === '') {
       return new JsonResponse([]);
     }
 
@@ -129,7 +129,7 @@ protected function getMatchesFromExistingValues($q, $webform_id, $key, $operator
       ->fields('webform_submission_data', ['value'])
       ->condition('webform_id', $webform_id)
       ->condition('name', $key)
-      ->condition('value', ($operator == 'START_WITH') ? "$q%" : "%$q%", 'LIKE')
+      ->condition('value', ($operator === 'START_WITH') ? "$q%" : "%$q%", 'LIKE')
       ->orderBy('value');
     if ($limit) {
       $query->range(0, $limit);
@@ -203,7 +203,7 @@ protected function getMatchesFromOptionsRecursive($q, array $options, array &$ma
       // Cast TranslatableMarkup to string.
       $label = (string) $label;
 
-      if ($operator == 'STARTS_WITH' && stripos($label, $q) === 0) {
+      if ($operator === 'STARTS_WITH' && stripos($label, $q) === 0) {
         $matches[$label] = [
           'value' => $label,
           'label' => $label,
diff --git a/web/modules/webform/src/Controller/WebformEntityController.php b/web/modules/webform/src/Controller/WebformEntityController.php
index 8329afd70f..2d310a3ebf 100644
--- a/web/modules/webform/src/Controller/WebformEntityController.php
+++ b/web/modules/webform/src/Controller/WebformEntityController.php
@@ -32,7 +32,7 @@ class WebformEntityController extends ControllerBase implements ContainerInjecti
   protected $renderer;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/src/Controller/WebformPluginElementController.php b/web/modules/webform/src/Controller/WebformPluginElementController.php
index 8877152db4..58730b4455 100644
--- a/web/modules/webform/src/Controller/WebformPluginElementController.php
+++ b/web/modules/webform/src/Controller/WebformPluginElementController.php
@@ -32,7 +32,7 @@ class WebformPluginElementController extends ControllerBase implements Container
   protected $elementInfo;
 
   /**
-   * A webform element plugin manager.
+   * The webform element plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
diff --git a/web/modules/webform/src/Controller/WebformPluginHandlerController.php b/web/modules/webform/src/Controller/WebformPluginHandlerController.php
index 7079d9bae4..8de9a824e4 100644
--- a/web/modules/webform/src/Controller/WebformPluginHandlerController.php
+++ b/web/modules/webform/src/Controller/WebformPluginHandlerController.php
@@ -18,7 +18,7 @@
 class WebformPluginHandlerController extends ControllerBase implements ContainerInjectionInterface {
 
   /**
-   * A webform handler plugin manager.
+   * The webform handler plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformHandlerManagerInterface
    */
@@ -61,7 +61,7 @@ public function index() {
           $definition['description'],
           $definition['category'],
           (isset($excluded_handlers[$plugin_id])) ? $this->t('Yes') : $this->t('No'),
-          ($definition['cardinality'] == -1) ? $this->t('Unlimited') : $definition['cardinality'],
+          ($definition['cardinality'] === -1) ? $this->t('Unlimited') : $definition['cardinality'],
           $definition['conditions'] ? $this->t('Yes') : $this->t('No'),
           $definition['submission'] ? $this->t('Required') : $this->t('Optional'),
           $definition['results'] ? $this->t('Processed') : $this->t('Ignored'),
diff --git a/web/modules/webform/src/Controller/WebformPluginVariantController.php b/web/modules/webform/src/Controller/WebformPluginVariantController.php
index 086c2ae6ef..0f5da17e0f 100644
--- a/web/modules/webform/src/Controller/WebformPluginVariantController.php
+++ b/web/modules/webform/src/Controller/WebformPluginVariantController.php
@@ -17,7 +17,7 @@
 class WebformPluginVariantController extends ControllerBase implements ContainerInjectionInterface {
 
   /**
-   * A webform variant plugin manager.
+   * The webform variant plugin manager.
    *
    * @var \Drupal\Component\Plugin\PluginManagerInterface
    */
diff --git a/web/modules/webform/src/Controller/WebformResultsExportController.php b/web/modules/webform/src/Controller/WebformResultsExportController.php
index c2f4192ce3..dd28b95f50 100644
--- a/web/modules/webform/src/Controller/WebformResultsExportController.php
+++ b/web/modules/webform/src/Controller/WebformResultsExportController.php
@@ -37,7 +37,7 @@ class WebformResultsExportController extends ControllerBase implements Container
   protected $submissionExporter;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
@@ -294,7 +294,7 @@ public static function batchProcess(WebformInterface $webform, EntityInterface $
     $context['message'] = t('Exported @count of @total submissions…', ['@count' => $context['sandbox']['progress'], '@total' => $context['sandbox']['max']]);
 
     // Track finished.
-    if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
+    if ($context['sandbox']['progress'] !== $context['sandbox']['max']) {
       $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
     }
   }
diff --git a/web/modules/webform/src/Controller/WebformSubmissionController.php b/web/modules/webform/src/Controller/WebformSubmissionController.php
index 0c28a70aa1..bd2bf3885a 100644
--- a/web/modules/webform/src/Controller/WebformSubmissionController.php
+++ b/web/modules/webform/src/Controller/WebformSubmissionController.php
@@ -28,7 +28,7 @@ class WebformSubmissionController extends ControllerBase {
   protected $renderer;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/src/Controller/WebformSubmissionViewController.php b/web/modules/webform/src/Controller/WebformSubmissionViewController.php
index baeaf69e94..931ecb902c 100644
--- a/web/modules/webform/src/Controller/WebformSubmissionViewController.php
+++ b/web/modules/webform/src/Controller/WebformSubmissionViewController.php
@@ -26,7 +26,7 @@ class WebformSubmissionViewController extends EntityViewController {
   protected $currentUser;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/src/Controller/WebformTestController.php b/web/modules/webform/src/Controller/WebformTestController.php
index 78b6624d09..399d685385 100644
--- a/web/modules/webform/src/Controller/WebformTestController.php
+++ b/web/modules/webform/src/Controller/WebformTestController.php
@@ -26,7 +26,7 @@ class WebformTestController extends ControllerBase implements ContainerInjection
   protected $messenger;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/src/Element/WebformActions.php b/web/modules/webform/src/Element/WebformActions.php
index 03e9bb7d50..9b30317c2d 100644
--- a/web/modules/webform/src/Element/WebformActions.php
+++ b/web/modules/webform/src/Element/WebformActions.php
@@ -110,7 +110,7 @@ public static function processWebformActions(&$element, FormStateInterface $form
       // Apply attributes (class, style, properties).
       if (!empty($element['#' . $settings_name . '__attributes'])) {
         foreach ($element['#' . $settings_name . '__attributes'] as $attribute_name => $attribute_value) {
-          if ($attribute_name == 'class') {
+          if ($attribute_name === 'class') {
             // Merge class names.
             $element[$button_name]['#attributes']['class'] = array_merge($element[$button_name]['#attributes']['class'], $attribute_value);
           }
diff --git a/web/modules/webform/src/Element/WebformCodeMirror.php b/web/modules/webform/src/Element/WebformCodeMirror.php
index e03fedd078..072c081a9e 100644
--- a/web/modules/webform/src/Element/WebformCodeMirror.php
+++ b/web/modules/webform/src/Element/WebformCodeMirror.php
@@ -69,13 +69,13 @@ public function getInfo() {
    * {@inheritdoc}
    */
   public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
-    if ($input === FALSE && $element['#mode'] == 'yaml' && isset($element['#default_value'])) {
+    if ($input === FALSE && $element['#mode'] === 'yaml' && isset($element['#default_value'])) {
       // Convert associative array in default value to YAML.
       if (is_array($element['#default_value'])) {
         $element['#default_value'] = WebformYaml::encode($element['#default_value']);
       }
       // Convert empty YAML into an empty string.
-      if ($element['#default_value'] == '{  }') {
+      if ($element['#default_value'] === '{  }') {
         $element['#default_value'] = '';
       }
       return $element['#default_value'];
@@ -93,7 +93,7 @@ public static function processWebformCodeMirror(&$element, FormStateInterface $f
     }
 
     // Check edit Twig template permission and complete disable editing.
-    if ($element['#mode'] == 'twig') {
+    if ($element['#mode'] === 'twig') {
       if (!WebformTwigExtension::hasEditTwigAccess()) {
         $element['#disable'] = TRUE;
         $element['#attributes']['disabled'] = 'disabled';
@@ -159,7 +159,7 @@ public static function validateWebformCodeMirror(&$element, FormStateInterface $
     }
     else {
       // If editing YAML and #default_value is an array, decode #value.
-      if ($element['#mode'] == 'yaml'
+      if ($element['#mode'] === 'yaml'
         && (isset($element['#default_value']) && is_array($element['#default_value']) || $element['#decode_value'])
       ) {
         // Handle rare case where single array value is not parsed correctly.
diff --git a/web/modules/webform/src/Element/WebformCompositeFormElementTrait.php b/web/modules/webform/src/Element/WebformCompositeFormElementTrait.php
index 4da05e781c..479e0ed9b4 100644
--- a/web/modules/webform/src/Element/WebformCompositeFormElementTrait.php
+++ b/web/modules/webform/src/Element/WebformCompositeFormElementTrait.php
@@ -75,7 +75,7 @@ public static function preRenderWebformCompositeFormElement($element) {
     switch ($wrapper_type) {
       case 'fieldset':
         // Set the element's title attribute to show #title as a tooltip, if needed.
-        if (isset($element['#title']) && $element['#title_display'] == 'attribute') {
+        if (isset($element['#title']) && $element['#title_display'] === 'attribute') {
           $element['#attributes']['title'] = $element['#title'];
           if (!empty($element['#required'])) {
             // Append an indication that this fieldset is required.
diff --git a/web/modules/webform/src/Element/WebformComputedBase.php b/web/modules/webform/src/Element/WebformComputedBase.php
index 4141af3987..310345eb5c 100644
--- a/web/modules/webform/src/Element/WebformComputedBase.php
+++ b/web/modules/webform/src/Element/WebformComputedBase.php
@@ -18,27 +18,6 @@
  */
 abstract class WebformComputedBase extends FormElement implements WebformComputedInterface {
 
-  /**
-   * Denotes HTML.
-   *
-   * @var string
-   */
-  const MODE_HTML = 'html';
-
-  /**
-   * Denotes plain text.
-   *
-   * @var string
-   */
-  const MODE_TEXT = 'text';
-
-  /**
-   * Denotes markup whose content type should be detected.
-   *
-   * @var string
-   */
-  const MODE_AUTO = 'auto';
-
   /**
    * Cache of submissions being processed.
    *
@@ -88,7 +67,7 @@ public static function processWebformComputed(&$element, FormStateInterface $for
       $element['#tree'] = TRUE;
 
       // Set #type to item to trigger #states behavior.
-      // @see drupal_process_states;
+      // @see \Drupal\Core\Form\FormHelper::processStates;
       $element['#type'] = 'item';
 
       $value = static::computeValue($element, $webform_submission);
@@ -327,8 +306,8 @@ public static function ajaxWebformComputedCallback(array $form, FormStateInterfa
    *   The markup type (html or text).
    */
   public static function getMode(array $element) {
-    if (empty($element['#mode']) || $element['#mode'] === static::MODE_AUTO) {
-      return (WebformHtmlHelper::containsHtml($element['#template'])) ? static::MODE_HTML : static::MODE_TEXT;
+    if (empty($element['#mode']) || $element['#mode'] === WebformComputedInterface::MODE_AUTO) {
+      return (WebformHtmlHelper::containsHtml($element['#template'])) ? WebformComputedInterface::MODE_HTML : WebformComputedInterface::MODE_TEXT;
     }
     else {
       return $element['#mode'];
diff --git a/web/modules/webform/src/Element/WebformComputedInterface.php b/web/modules/webform/src/Element/WebformComputedInterface.php
index b107b8931d..01332bb031 100644
--- a/web/modules/webform/src/Element/WebformComputedInterface.php
+++ b/web/modules/webform/src/Element/WebformComputedInterface.php
@@ -9,6 +9,27 @@
  */
 interface WebformComputedInterface {
 
+  /**
+   * Denotes HTML.
+   *
+   * @var string
+   */
+  const MODE_HTML = 'html';
+
+  /**
+   * Denotes plain text.
+   *
+   * @var string
+   */
+  const MODE_TEXT = 'text';
+
+  /**
+   * Denotes markup whose content type should be detected.
+   *
+   * @var string
+   */
+  const MODE_AUTO = 'auto';
+
   /**
    * Compute value.
    *
diff --git a/web/modules/webform/src/Element/WebformComputedToken.php b/web/modules/webform/src/Element/WebformComputedToken.php
index c11332a805..36b7b88ddb 100644
--- a/web/modules/webform/src/Element/WebformComputedToken.php
+++ b/web/modules/webform/src/Element/WebformComputedToken.php
@@ -21,7 +21,7 @@ public static function computeValue(array $element, WebformSubmissionInterface $
     $token_manager = \Drupal::service('webform.token_manager');
 
     // Replace tokens in value.
-    return $token_manager->replace($element['#template'], $webform_submission, [], ['html' => ($mode == static::MODE_HTML)]);
+    return $token_manager->replace($element['#template'], $webform_submission, [], ['html' => ($mode === WebformComputedInterface::MODE_HTML)]);
   }
 
 }
diff --git a/web/modules/webform/src/Element/WebformComputedTwig.php b/web/modules/webform/src/Element/WebformComputedTwig.php
index 3e92c89cf0..11c9598ee2 100644
--- a/web/modules/webform/src/Element/WebformComputedTwig.php
+++ b/web/modules/webform/src/Element/WebformComputedTwig.php
@@ -43,7 +43,7 @@ public static function computeValue(array $element, WebformSubmissionInterface $
 
     $template = ($whitespace === static::WHITESPACE_SPACELESS) ? '{% spaceless %}' . $element['#template'] . '{% endspaceless %}' : $element['#template'];
 
-    $options = ['html' => (static::getMode($element) === static::MODE_HTML)];
+    $options = ['html' => (static::getMode($element) === WebformComputedInterface::MODE_HTML)];
 
     $value = WebformTwigExtension::renderTwigTemplate($webform_submission, $template, $options);
 
diff --git a/web/modules/webform/src/Element/WebformElementMultiple.php b/web/modules/webform/src/Element/WebformElementMultiple.php
index b713981edb..3a56efcc0b 100644
--- a/web/modules/webform/src/Element/WebformElementMultiple.php
+++ b/web/modules/webform/src/Element/WebformElementMultiple.php
@@ -55,7 +55,7 @@ public static function valueCallback(&$element, $input, FormStateInterface $form
    * Processes element multiple.
    */
   public static function processWebformElementMultiple(&$element, FormStateInterface $form_state, &$complete_form) {
-    $cardinality = $element['#value'];
+    $cardinality = (int) $element['#value'];
 
     $element['#tree'] = TRUE;
 
@@ -74,11 +74,11 @@ public static function processWebformElementMultiple(&$element, FormStateInterfa
         'number' => t('Limited'),
         WebformMultiple::CARDINALITY_UNLIMITED => t('Unlimited'),
       ],
-      '#default_value' => ($cardinality == WebformMultiple::CARDINALITY_UNLIMITED) ? WebformMultiple::CARDINALITY_UNLIMITED : 'number',
+      '#default_value' => ($cardinality === WebformMultiple::CARDINALITY_UNLIMITED) ? WebformMultiple::CARDINALITY_UNLIMITED : 'number',
     ];
     $element['container']['cardinality_number'] = [
       '#type' => 'number',
-      '#default_value' => $cardinality != WebformMultiple::CARDINALITY_UNLIMITED ? $cardinality : $element['#min'],
+      '#default_value' => $cardinality !== WebformMultiple::CARDINALITY_UNLIMITED ? $cardinality : $element['#min'],
       '#min' => $element['#min'],
       '#title' => t('Limit'),
       '#title_display' => 'invisible',
@@ -101,7 +101,7 @@ public static function processWebformElementMultiple(&$element, FormStateInterfa
     array_unshift($element['#element_validate'], [get_called_class(), 'validateWebformElementMultiple']);
 
     // Set #type to item to apply #states.
-    // @see drupal_process_states
+    // @see \Drupal\Core\Form\FormHelper::processStates
     $element['#type'] = 'item';
 
     return $element;
@@ -121,9 +121,9 @@ public static function validateWebformElementMultiple(&$element, FormStateInterf
       $multiple = $element['#default_value'];
     }
     else {
-      $cardinality = $element['#value']['container']['cardinality'];
+      $cardinality = (int) $element['#value']['container']['cardinality'];
       $cardinality_number = (int) $element['#value']['container']['cardinality_number'];
-      if ($cardinality == WebformMultiple::CARDINALITY_UNLIMITED) {
+      if ($cardinality === WebformMultiple::CARDINALITY_UNLIMITED) {
         $multiple = WebformMultiple::CARDINALITY_UNLIMITED;
       }
       else {
@@ -131,7 +131,7 @@ public static function validateWebformElementMultiple(&$element, FormStateInterf
       }
     }
 
-    if ($multiple == WebformMultiple::CARDINALITY_UNLIMITED) {
+    if ($multiple === WebformMultiple::CARDINALITY_UNLIMITED) {
       $multiple = TRUE;
     }
     elseif ($multiple === 1) {
diff --git a/web/modules/webform/src/Element/WebformElementOptions.php b/web/modules/webform/src/Element/WebformElementOptions.php
index 0726c91c9b..c895e0f278 100644
--- a/web/modules/webform/src/Element/WebformElementOptions.php
+++ b/web/modules/webform/src/Element/WebformElementOptions.php
@@ -92,7 +92,7 @@ public static function processWebformElementOptions(&$element, FormStateInterfac
       '#type' => 'select',
       '#description' => t('Please select <a href=":href">predefined @type</a> or enter custom @type.', $t_args),
       '#options' => [
-        self::CUSTOM_OPTION => t('Custom @type…', $t_args),
+        static::CUSTOM_OPTION => t('Custom @type…', $t_args),
       ] + $options,
 
       '#attributes' => [
@@ -130,7 +130,7 @@ public static function processWebformElementOptions(&$element, FormStateInterfac
     if ($has_options) {
       $element['custom']['#states'] = [
         'visible' => [
-          'select.js-' . $element['#id'] . '-options' => ['value' => self::CUSTOM_OPTION],
+          'select.js-' . $element['#id'] . '-options' => ['value' => static::CUSTOM_OPTION],
         ],
       ];
     }
@@ -154,7 +154,7 @@ public static function validateWebformElementOptions(&$element, FormStateInterfa
     $custom_value = NestedArray::getValue($form_state->getValues(), $element['custom']['#parents']);
 
     $value = $options_value;
-    if ($options_value == self::CUSTOM_OPTION) {
+    if ($options_value === static::CUSTOM_OPTION) {
       try {
         $value = (is_string($custom_value)) ? Yaml::decode($custom_value) : $custom_value;
       }
diff --git a/web/modules/webform/src/Element/WebformElementStates.php b/web/modules/webform/src/Element/WebformElementStates.php
index c85a2c17aa..18ec64de70 100644
--- a/web/modules/webform/src/Element/WebformElementStates.php
+++ b/web/modules/webform/src/Element/WebformElementStates.php
@@ -240,7 +240,7 @@ public static function processWebformStates(&$element, FormStateInterface $form_
       if ($triggers) {
         $element['disabled_message'] = [
           '#type' => 'webform_message',
-          '#message_message' => t('<a href="https://www.w3schools.com/tags/att_input_disabled.asp">Disabled</a> elements do not submit data back to the server and the element\'s server-side default or current value will be preserved and saved to the database.'),
+          '#message_message' => t('<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-disabled">Disabled</a> elements do not submit data back to the server and the element\'s server-side default or current value will be preserved and saved to the database.'),
           '#message_type' => 'warning',
           '#states' => ['visible' => $triggers],
         ];
@@ -260,7 +260,7 @@ public static function processWebformStates(&$element, FormStateInterface $form_
         if (!isset($sources[$sources_key])) {
           foreach ($values as $key => $value) {
             $sources[$sources_key][] = [
-              'label' => (string) $value . ($value != $key ? ' (' . $key . ')' : ''),
+              'label' => (string) $value . ($value !== $key ? ' (' . $key . ')' : ''),
               'value' => (string) $key,
             ];
           }
@@ -494,7 +494,7 @@ protected static function buildConditionRow(array $element, array $condition, $t
     ];
     $row['condition']['pattern'] = [
       '#type' => 'container',
-      'description' => ['#markup' => t('Enter a <a href=":href">regular expression</a>', [':href' => 'http://www.w3schools.com/js/js_regexp.asp'])],
+      'description' => ['#markup' => t('Enter a <a href=":href">regular expression</a>', [':href' => 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions'])],
       '#states' => [
         'visible' => [
           [$trigger_selector => ['value' => 'pattern']],
@@ -613,11 +613,11 @@ public static function addConditionSubmit(array &$form, FormStateInterface $form
 
     // The $row_index is not sequential so we need to rebuild the value instead
     // of just using an array_slice().
-    $row_index = $button['#row_index'];
+    $row_index = (int) $button['#row_index'];
     $values = [];
     foreach ($element['states']['#value'] as $index => $value) {
       $values[] = $value;
-      if ($index == $row_index) {
+      if ($index === $row_index) {
         $values[] = ['selector' => '', 'trigger' => '', 'value' => ''];
       }
     }
@@ -858,7 +858,7 @@ protected static function convertElementValueToFormApiStates(array $element, arr
         foreach ($state_array['conditions'] as $index => $condition) {
           extract(static::getFormApiStatesCondition($condition));
           if ($selector && $trigger) {
-            if ($operator == 'or' || $operator == 'xor') {
+            if ($operator === 'or' || $operator === 'xor') {
               if ($index !== 0) {
                 $states[$state][] = $operator;
               }
@@ -1026,7 +1026,7 @@ protected static function isDefaultValueCustomizedFormApiStates(array $element)
           }
 
           // Make sure the same operator is being used between the conditions.
-          if ($operator && $operator != $condition) {
+          if ($operator && $operator !== $condition) {
             return t('Conditional logic (Form API #states) has multiple operators.', ['%operator' => mb_strtoupper($condition)]);
           }
 
diff --git a/web/modules/webform/src/Element/WebformEmailConfirm.php b/web/modules/webform/src/Element/WebformEmailConfirm.php
index 46ac874c50..24accdf6d0 100644
--- a/web/modules/webform/src/Element/WebformEmailConfirm.php
+++ b/web/modules/webform/src/Element/WebformEmailConfirm.php
@@ -92,6 +92,9 @@ public static function processWebformEmailConfirm(&$element, FormStateInterface
     $mail_1_properties = [
       '#title',
       '#description',
+      '#help_title',
+      '#help',
+      '#help_display',
     ];
     $element['mail_1'] = $element_shared_properties + array_intersect_key($element, array_combine($mail_1_properties, $mail_1_properties));
     $element['mail_1']['#attributes']['class'][] = 'webform-email';
@@ -124,9 +127,14 @@ public static function processWebformEmailConfirm(&$element, FormStateInterface
     $element['#description_display'] = 'invisible';
 
     // Remove properties that are being applied to the sub elements.
-    unset($element['#maxlength']);
-    unset($element['#attributes']);
-    unset($element['#description']);
+    unset(
+      $element['#maxlength'],
+      $element['#attributes'],
+      $element['#description'],
+      $element['#help'],
+      $element['#help_title'],
+      $element['#help_display']
+    );
 
     // Add validate callback.
     $element += ['#element_validate' => []];
diff --git a/web/modules/webform/src/Element/WebformEntityTrait.php b/web/modules/webform/src/Element/WebformEntityTrait.php
index 8d1953ff1d..497cb8b377 100644
--- a/web/modules/webform/src/Element/WebformEntityTrait.php
+++ b/web/modules/webform/src/Element/WebformEntityTrait.php
@@ -71,8 +71,8 @@ public static function setOptions(array &$element, array $settings = []) {
 
     // If the selection handler is not using views, then translate
     // the entity reference's options.
-    if ($element['#selection_handler'] != 'views') {
-      $options = self::translateOptions($options, $element);
+    if ($element['#selection_handler'] !== 'views') {
+      $options = static::translateOptions($options, $element);
     }
 
     if ($element['#type'] === 'webform_entity_select') {
@@ -108,7 +108,7 @@ protected static function translateOptions(array $options, array $element) {
 
     foreach ($options as $key => $value) {
       if (is_array($value)) {
-        $options[$key] = self::translateOptions($value, $element);
+        $options[$key] = static::translateOptions($value, $element);
       }
       else {
         // Set the entity in the correct language for display.
diff --git a/web/modules/webform/src/Element/WebformImageResolution.php b/web/modules/webform/src/Element/WebformImageResolution.php
index f9c32df581..b430c99237 100644
--- a/web/modules/webform/src/Element/WebformImageResolution.php
+++ b/web/modules/webform/src/Element/WebformImageResolution.php
@@ -67,24 +67,28 @@ public static function processWebformImageResolution(&$element, FormStateInterfa
       '#description' => t('The maximum allowed image size expressed as WIDTH×HEIGHT (e.g. 640×480). Leave blank for no restriction. If a larger image is uploaded, it will be resized to reflect the given width and height. Resizing images on upload will cause the loss of <a href="http://wikipedia.org/wiki/Exchangeable_image_file_format">EXIF data</a> in the image.'),
       '#height_title' => t('Maximum height'),
       '#width_title' => t('Maximum width'),
-      '#field_prefix' => '<div class="container-inline">',
-      '#field_suffix' => '</div>',
     ];
-    $element['x'] = [
+    $element['container'] = [
+      '#prefix' => '<div class="container-inline">',
+      '#suffix' => '</div>',
+    ];
+    $element['container']['x'] = [
       '#type' => 'number',
       '#title' => $element['#width_title'],
       '#title_display' => 'invisible',
       '#value' => empty($element['#value']) ? NULL : $element['#value']['x'],
       '#min' => 1,
       '#field_suffix' => ' × ',
+      '#parents' => array_merge($element['#parents'], ['x']),
     ];
-    $element['y'] = [
+    $element['container']['y'] = [
       '#type' => 'number',
       '#title' => $element['#height_title'],
       '#title_display' => 'invisible',
       '#value' => empty($element['#value']) ? NULL : $element['#value']['y'],
       '#min' => 1,
       '#field_suffix' => ' ' . t('pixels'),
+      '#parents' => array_merge($element['#parents'], ['y']),
     ];
 
     // Add validate callback.
@@ -100,16 +104,16 @@ public static function processWebformImageResolution(&$element, FormStateInterfa
    * @see \Drupal\image\Plugin\Field\FieldType\ImageItem::validateResolution
    */
   public static function validateWebformImageResolution(&$element, FormStateInterface $form_state, &$complete_form) {
-    if (!empty($element['x']['#value']) || !empty($element['y']['#value'])) {
+    if (!empty($element['container']['x']['#value']) || !empty($element['container']['y']['#value'])) {
       foreach (['x', 'y'] as $dimension) {
-        if (!$element[$dimension]['#value']) {
+        if (!$element['container'][$dimension]['#value']) {
           // We expect the field name placeholder value to be wrapped in t()
           // here, so it won't be escaped again as it's already marked safe.
-          $form_state->setError($element[$dimension], t('Both a height and width value must be specified in the @name field.', ['@name' => $element['#title']]));
+          $form_state->setError($element['container'][$dimension], t('Both a height and width value must be specified in the @name field.', ['@name' => $element['#title']]));
           return;
         }
       }
-      $form_state->setValueForElement($element, $element['x']['#value'] . 'x' . $element['y']['#value']);
+      $form_state->setValueForElement($element, $element['container']['x']['#value'] . 'x' . $element['container']['y']['#value']);
     }
     else {
       $form_state->setValueForElement($element, '');
diff --git a/web/modules/webform/src/Element/WebformLikert.php b/web/modules/webform/src/Element/WebformLikert.php
index 9d9a872ffc..8b44dd9a26 100644
--- a/web/modules/webform/src/Element/WebformLikert.php
+++ b/web/modules/webform/src/Element/WebformLikert.php
@@ -63,7 +63,7 @@ public static function processWebformLikert(&$element, FormStateInterface $form_
         $answer_description = '';
       }
       else {
-        $answer_description_property_name = ($element['#answers_description_display'] == 'help') ? 'help' : 'description';
+        $answer_description_property_name = ($element['#answers_description_display'] === 'help') ? 'help' : 'description';
         list($answer_title, $answer_description) = explode(WebformOptionsHelper::DESCRIPTION_DELIMITER, $answer);
       }
       $answers[$answer_key] = [
@@ -121,7 +121,7 @@ public static function processWebformLikert(&$element, FormStateInterface $form_
         $question_description = '';
       }
       else {
-        $question_description_property_name = ($element['#questions_description_display'] == 'help') ? '#help' : '#description';
+        $question_description_property_name = ($element['#questions_description_display'] === 'help') ? '#help' : '#description';
         list($question_title, $question_description) = explode(WebformOptionsHelper::DESCRIPTION_DELIMITER, $question);
       }
 
diff --git a/web/modules/webform/src/Element/WebformLocationBase.php b/web/modules/webform/src/Element/WebformLocationBase.php
index 1492caab7a..c594423091 100644
--- a/web/modules/webform/src/Element/WebformLocationBase.php
+++ b/web/modules/webform/src/Element/WebformLocationBase.php
@@ -91,7 +91,7 @@ public static function processWebformComposite(&$element, FormStateInterface $fo
     // readonly elements to hidden elements.
     $composite_elements = static::getCompositeElements($element);
     foreach ($composite_elements as $composite_key => $composite_element) {
-      if ($composite_key != 'value') {
+      if ($composite_key !== 'value') {
         if (isset($element[$composite_key]['#access']) && $element[$composite_key]['#access'] === FALSE) {
           unset($element[$composite_key]['#access']);
           unset($element[$composite_key]['#pre_render']);
diff --git a/web/modules/webform/src/Element/WebformManagedFileBase.php b/web/modules/webform/src/Element/WebformManagedFileBase.php
index 2f8864083e..663a465dd1 100644
--- a/web/modules/webform/src/Element/WebformManagedFileBase.php
+++ b/web/modules/webform/src/Element/WebformManagedFileBase.php
@@ -21,7 +21,7 @@ abstract class WebformManagedFileBase extends ManagedFile {
      *
      * @var string
      *
-     * @see http://www.w3schools.com/tags/att_input_accept.asp
+     * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept
      */
     protected static $accept;
 
diff --git a/web/modules/webform/src/Element/WebformMapping.php b/web/modules/webform/src/Element/WebformMapping.php
index c4e0f32fde..3c9359493c 100644
--- a/web/modules/webform/src/Element/WebformMapping.php
+++ b/web/modules/webform/src/Element/WebformMapping.php
@@ -63,7 +63,7 @@ public static function processWebformMapping(&$element, FormStateInterface $form
         $source_description = '';
       }
       else {
-        $source_description_property_name = ($element['#source__description_display'] == 'help') ? 'help' : 'description';
+        $source_description_property_name = ($element['#source__description_display'] === 'help') ? 'help' : 'description';
         list($source_title, $source_description) = explode(WebformOptionsHelper::DESCRIPTION_DELIMITER, $source);
       }
       $sources[$source_key] = [
@@ -81,8 +81,8 @@ public static function processWebformMapping(&$element, FormStateInterface $form
     // Set base destination element.
     $destination_element_base = [
       '#title_display' => 'invisible',
-      '#required' => ($element['#required'] === self::REQUIRED_ALL) ? TRUE : FALSE,
-      '#error_no_message'  => ($element['#required'] !== self::REQUIRED_ALL) ? TRUE : FALSE,
+      '#required' => ($element['#required'] === static::REQUIRED_ALL) ? TRUE : FALSE,
+      '#error_no_message'  => ($element['#required'] !== static::REQUIRED_ALL) ? TRUE : FALSE,
     ];
 
     // Get base #destination__* properties.
@@ -190,7 +190,7 @@ public static function validateWebformMapping(&$element, FormStateInterface $for
     // Note: Not validating REQUIRED_ALL because each destination element is
     // already required.
     $has_access = (!isset($element['#access']) || $element['#access'] === TRUE);
-    if ($element['#required'] && $element['#required'] !== self::REQUIRED_ALL && empty($value) && $has_access) {
+    if ($element['#required'] && $element['#required'] !== static::REQUIRED_ALL && empty($value) && $has_access) {
       WebformElementHelper::setRequiredError($element, $form_state);
     }
 
diff --git a/web/modules/webform/src/Element/WebformMessage.php b/web/modules/webform/src/Element/WebformMessage.php
index 9c94ad1c6d..e0b574d8de 100644
--- a/web/modules/webform/src/Element/WebformMessage.php
+++ b/web/modules/webform/src/Element/WebformMessage.php
@@ -87,7 +87,7 @@ public static function preRenderWebformMessage(array $element) {
     $element['#attributes']['class'][] = 'js-webform-message';
 
     // Ignore 'user' and 'state' storage is current user is anonymous.
-    if (\Drupal::currentUser()->isAnonymous() && in_array($message_storage, [self::STORAGE_USER, self::STORAGE_STATE, self::STORAGE_CUSTOM])) {
+    if (\Drupal::currentUser()->isAnonymous() && in_array($message_storage, [static::STORAGE_USER, static::STORAGE_STATE, static::STORAGE_CUSTOM])) {
       $message_storage = '';
     }
 
@@ -104,7 +104,7 @@ public static function preRenderWebformMessage(array $element) {
         'aria-label' => t('close'),
         'class' => ['js-webform-message__link', 'webform-message__link'],
       ];
-      if (in_array($message_storage, [self::STORAGE_USER, self::STORAGE_STATE, self::STORAGE_CUSTOM])) {
+      if (in_array($message_storage, [static::STORAGE_USER, static::STORAGE_STATE, static::STORAGE_CUSTOM])) {
         $close_url = Url::fromRoute('webform.element.message.close', [
           'storage' => $message_storage,
           'id' => $message_id,
@@ -173,19 +173,19 @@ public static function isClosed($storage, $id) {
     $account = \Drupal::currentUser();
     $namespace = 'webform.element.message';
     switch ($storage) {
-      case self::STORAGE_STATE:
+      case static::STORAGE_STATE:
         /** @var \Drupal\Core\State\StateInterface $state */
         $state = \Drupal::service('state');
         $values = $state->get($namespace, []);
         return (isset($values[$id])) ? TRUE : FALSE;
 
-      case self::STORAGE_USER:
+      case static::STORAGE_USER:
         /** @var \Drupal\user\UserDataInterface $user_data */
         $user_data = \Drupal::service('user.data');
         $values = $user_data->get('webform', $account->id(), $namespace) ?: [];
         return (isset($values[$id])) ? TRUE : FALSE;
 
-      case self::STORAGE_CUSTOM:
+      case static::STORAGE_CUSTOM:
         $result = \Drupal::moduleHandler()->invokeAll('webform_message_custom', ['closed', $id]);
         return array_filter($result) ? TRUE : FALSE;
     }
@@ -206,7 +206,7 @@ public static function setClosed($storage, $id) {
     $account = \Drupal::currentUser();
     $namespace = 'webform.element.message';
     switch ($storage) {
-      case self::STORAGE_STATE:
+      case static::STORAGE_STATE:
         /** @var \Drupal\Core\State\StateInterface $state */
         $state = \Drupal::service('state');
         $values = $state->get($namespace, []);
@@ -214,7 +214,7 @@ public static function setClosed($storage, $id) {
         $state->set($namespace, $values);
         break;
 
-      case self::STORAGE_USER:
+      case static::STORAGE_USER:
         /** @var \Drupal\user\UserDataInterface $user_data */
         $user_data = \Drupal::service('user.data');
         $values = $user_data->get('webform', $account->id(), $namespace) ?: [];
@@ -222,7 +222,7 @@ public static function setClosed($storage, $id) {
         $user_data->set('webform', $account->id(), $namespace, $values);
         break;
 
-      case self::STORAGE_CUSTOM:
+      case static::STORAGE_CUSTOM:
         \Drupal::moduleHandler()->invokeAll('webform_message_custom', ['close', $id]);
         break;
     }
@@ -242,7 +242,7 @@ public static function resetClosed($storage, $id) {
     $account = \Drupal::currentUser();
     $namespace = 'webform.element.message';
     switch ($storage) {
-      case self::STORAGE_STATE:
+      case static::STORAGE_STATE:
         /** @var \Drupal\Core\State\StateInterface $state */
         $state = \Drupal::service('state');
         $values = $state->get($namespace, []);
@@ -250,7 +250,7 @@ public static function resetClosed($storage, $id) {
         $state->set($namespace, $values);
         break;
 
-      case self::STORAGE_USER:
+      case static::STORAGE_USER:
         /** @var \Drupal\user\UserDataInterface $user_data */
         $user_data = \Drupal::service('user.data');
         $values = $user_data->get('webform', $account->id(), $namespace) ?: [];
@@ -258,7 +258,7 @@ public static function resetClosed($storage, $id) {
         $user_data->set('webform', $account->id(), $namespace, $values);
         break;
 
-      case self::STORAGE_CUSTOM:
+      case static::STORAGE_CUSTOM:
         \Drupal::moduleHandler()->invokeAll('webform_message_custom', ['reset', $id]);
         break;
     }
diff --git a/web/modules/webform/src/Element/WebformMultiple.php b/web/modules/webform/src/Element/WebformMultiple.php
index db0dc5ad60..2f510a1dbf 100644
--- a/web/modules/webform/src/Element/WebformMultiple.php
+++ b/web/modules/webform/src/Element/WebformMultiple.php
@@ -40,6 +40,7 @@ public function getInfo() {
       ],
       '#cardinality' => FALSE,
       '#min_items' => NULL,
+      '#item_label' => $this->t('item'),
       '#no_items_message' => $this->t('No items entered. Please add items below.'),
       '#empty_items' => 1,
       '#add_more' => TRUE,
@@ -171,8 +172,10 @@ public static function processWebformMultiple(&$element, FormStateInterface $for
     $ajax_attributes = $element['#ajax_attributes'];
     $ajax_attributes['id'] = $table_id;
     $element += ['#prefix' => '', '#suffix' => ''];
-    $element['#prefix'] = $element['#prefix'] . '<div' . new Attribute($ajax_attributes) . '>';
-    $element['#suffix'] = '</div>' . $element['#suffix'];
+    $element['#ajax_prefix'] = '<div' . new Attribute($ajax_attributes) . '>';
+    $element['#ajax_suffix'] = '</div>';
+    $element['#prefix'] = $element['#prefix'] . $element['#ajax_prefix'];
+    $element['#suffix'] = $element['#ajax_suffix'] . $element['#suffix'];
 
     // DEBUG:
     // Disable Ajax callback by commenting out the below callback and wrapper.
@@ -662,7 +665,7 @@ protected static function buildElementRow($table_id, $row_index, array $element,
       if ($element['#add']) {
         $row['_operations_']['add'] = [
           '#type' => 'image_button',
-          '#title' => t('Add'),
+          '#title' => t('Add new @item after @item @number', ['@number' => $row_index + 1, '@item' => $element['#item_label']]),
           '#src' => drupal_get_path('module', 'webform') . '/images/icons/plus.svg',
           '#limit_validation_errors' => [],
           '#submit' => [[get_called_class(), 'addItemSubmit']],
@@ -677,7 +680,7 @@ protected static function buildElementRow($table_id, $row_index, array $element,
       if ($element['#remove']) {
         $row['_operations_']['remove'] = [
           '#type' => 'image_button',
-          '#title' => t('Remove'),
+          '#title' => t('Remove @item @number', ['@number' => $row_index + 1, '@item' => $element['#item_label']]),
           '#src' => drupal_get_path('module', 'webform') . '/images/icons/minus.svg',
           '#limit_validation_errors' => [],
           '#submit' => [[get_called_class(), 'removeItemSubmit']],
@@ -753,7 +756,7 @@ protected static function setElementRowDefaultValueRecursive(array &$element, ar
    *   The default value.
    */
   protected static function setElementDefaultValue(array &$element, $default_value) {
-    if ($element['#type'] == 'value') {
+    if ($element['#type'] === 'value') {
       $element['#value'] = $default_value;
     }
     else {
@@ -839,7 +842,7 @@ public static function addItemSubmit(array &$form, FormStateInterface $form_stat
     $values = [];
     foreach ($element['items']['#value'] as $row_index => $value) {
       $values[] = $value;
-      if ($row_index == $button['#row_index']) {
+      if ($row_index === $button['#row_index']) {
         $values[] = [];
       }
     }
@@ -903,6 +906,9 @@ public static function ajaxCallback(array &$form, FormStateInterface $form_state
     $button = $form_state->getTriggeringElement();
     $parent_length = (isset($button['#row_index'])) ? -4 : -2;
     $element = NestedArray::getValue($form, array_slice($button['#array_parents'], 0, $parent_length));
+    // Make sure only the ajax prefix and suffix is used.
+    $element['#prefix'] = $element['#ajax_prefix'];
+    $element['#suffix'] = $element['#ajax_suffix'];
     return $element;
   }
 
diff --git a/web/modules/webform/src/Element/WebformOtherBase.php b/web/modules/webform/src/Element/WebformOtherBase.php
index ecdbb845db..19d1d55976 100644
--- a/web/modules/webform/src/Element/WebformOtherBase.php
+++ b/web/modules/webform/src/Element/WebformOtherBase.php
@@ -32,6 +32,8 @@ abstract class WebformOtherBase extends FormElement {
    * The properties of the element.
    *
    * @var array
+   *
+   * @see \Drupal\webform\Element\WebformSelectOther::$properties
    */
   protected static $properties = [
     '#title',
@@ -46,6 +48,15 @@ abstract class WebformOtherBase extends FormElement {
     '#attributes',
   ];
 
+  /**
+   * The properties of the other element.
+   *
+   * @var array
+   */
+  protected static $otherProperties = [
+    '#required_error',
+  ];
+
   /**
    * {@inheritdoc}
    */
@@ -105,6 +116,7 @@ public static function processWebformOther(&$element, FormStateInterface $form_s
 
     $element[$type]['#type'] = static::$type;
     $element[$type]['#webform_element'] = TRUE;
+    $element[$type]['#webform_other'] = TRUE;
     $element[$type] += array_intersect_key($element, array_combine($properties, $properties));
     $element[$type]['#title_display'] = 'invisible';
     if (!isset($element[$type]['#options'][static::OTHER_OPTION])) {
@@ -133,11 +145,12 @@ public static function processWebformOther(&$element, FormStateInterface $form_s
         '#title_display' => 'invisible',
       ];
     }
+    $element['other'] += array_intersect_key($element, array_combine(static::$otherProperties, static::$otherProperties));
 
     $element['other']['#wrapper_attributes']['class'][] = "js-webform-$type-other-input";
     $element['other']['#wrapper_attributes']['class'][] = "webform-$type-other-input";
 
-    if ($element['other']['#type'] == 'datetime') {
+    if ($element['other']['#type'] === 'datetime') {
       $element['other']['#prefix'] = '<div class="' . implode(' ', $element['other']['#wrapper_attributes']['class']) . '">';
       $element['other']['#suffix'] = '</div>';
       unset($element['other']['#wrapper_attributes']['class']);
@@ -302,7 +315,7 @@ public static function getElementType() {
    *   TRUE if the webform element contains multiple values.
    */
   protected static function isMultiple(array $element) {
-    return (!empty($element['#multiple']) || static::$type == 'checkboxes') ? TRUE : FALSE;
+    return (!empty($element['#multiple']) || static::$type === 'checkboxes') ? TRUE : FALSE;
   }
 
   /**
diff --git a/web/modules/webform/src/Element/WebformSelectOther.php b/web/modules/webform/src/Element/WebformSelectOther.php
index ea49ec35a7..3ae9c4872a 100644
--- a/web/modules/webform/src/Element/WebformSelectOther.php
+++ b/web/modules/webform/src/Element/WebformSelectOther.php
@@ -23,6 +23,7 @@ class WebformSelectOther extends WebformOtherBase {
   protected static $properties = [
     '#title',
     '#required',
+    '#required_error',
     '#options',
     '#default_value',
     '#attributes',
@@ -30,6 +31,7 @@ class WebformSelectOther extends WebformOtherBase {
     '#multiple',
     '#empty_value',
     '#empty_option',
+    '#sort_options',
 
     '#ajax',
   ];
diff --git a/web/modules/webform/src/Element/WebformSignature.php b/web/modules/webform/src/Element/WebformSignature.php
index 173948f027..13f417e1a6 100644
--- a/web/modules/webform/src/Element/WebformSignature.php
+++ b/web/modules/webform/src/Element/WebformSignature.php
@@ -85,8 +85,8 @@ public static function preRenderWebformSignature(array $element) {
   }
 
   /**
-  +   * Webform element validation handler for #type 'signature'.
-  +   */
+   * Webform element validation handler for #type 'signature'.
+   */
   public static function validateWebformSignature(&$element, FormStateInterface $form_state, &$complete_form) {
     $value = $element['#value'];
     if (!static::isSignatureValid($value)) {
diff --git a/web/modules/webform/src/Element/WebformTermCheckboxes.php b/web/modules/webform/src/Element/WebformTermCheckboxes.php
index 611e34e9c8..c4f040c71f 100644
--- a/web/modules/webform/src/Element/WebformTermCheckboxes.php
+++ b/web/modules/webform/src/Element/WebformTermCheckboxes.php
@@ -79,7 +79,7 @@ protected static function getOptionsTree(array $element, $language) {
       if (!$item->access('view')) {
         continue;
       }
-      
+
       $options[$item->id()] = $item->getName();
     }
     return $options;
diff --git a/web/modules/webform/src/Element/WebformTermReferenceTrait.php b/web/modules/webform/src/Element/WebformTermReferenceTrait.php
index 517c0d1b70..ea80a2a3fb 100644
--- a/web/modules/webform/src/Element/WebformTermReferenceTrait.php
+++ b/web/modules/webform/src/Element/WebformTermReferenceTrait.php
@@ -33,7 +33,7 @@ public static function setOptions(array &$element) {
 
     // Add the vocabulary to the cache tags.
     // Issue #2920913: The taxonomy_term_list cache should be invalidated
-    // on a vocabulary-by-vocabulary basis
+    // on a vocabulary-by-vocabulary basis.
     // @see https://www.drupal.org/project/drupal/issues/2920913
     $element['#cache']['tags'][] = 'taxonomy_term_list';
   }
diff --git a/web/modules/webform/src/Element/WebformTime.php b/web/modules/webform/src/Element/WebformTime.php
index 2785c5ba9f..7c34e64f47 100644
--- a/web/modules/webform/src/Element/WebformTime.php
+++ b/web/modules/webform/src/Element/WebformTime.php
@@ -117,9 +117,9 @@ public static function validateWebformTime(&$element, FormStateInterface $form_s
     // @see https://github.com/jonthornton/jquery-timepicker
     // @see js/webform.element.time.js
     $is_valid_time = $time && (
-      $value == static::formatTime('H:i', $time) ||
-      $value == static::formatTime('H:i:s', $time) ||
-      $value == static::formatTime($element['#time_format'], $time)
+      $value === static::formatTime('H:i', $time) ||
+      $value === static::formatTime('H:i:s', $time) ||
+      $value === static::formatTime($element['#time_format'], $time)
     );
     if (!$is_valid_time) {
       if ($has_access) {
diff --git a/web/modules/webform/src/Entity/Webform.php b/web/modules/webform/src/Entity/Webform.php
index f2d6711f88..a01b4fc1a4 100644
--- a/web/modules/webform/src/Entity/Webform.php
+++ b/web/modules/webform/src/Entity/Webform.php
@@ -820,7 +820,7 @@ public function getNumberOfActions() {
    * {@inheritdoc}
    */
   public function hasPreview() {
-    return ($this->getSetting('preview') != DRUPAL_DISABLED);
+    return ($this->getSetting('preview') !== DRUPAL_DISABLED);
   }
 
   /**
@@ -926,7 +926,7 @@ public function getSettings() {
     // Settings should not be empty even.
     // https://www.drupal.org/node/2880392.
     return (isset($this->settings)) ? $this->settings +
-      self::getDefaultSettings() : self::getDefaultSettings();
+      static::getDefaultSettings() : static::getDefaultSettings();
   }
 
   /**
@@ -1033,7 +1033,7 @@ public static function getDefaultSettings() {
       'page' => TRUE,
       'page_submit_path' => '',
       'page_confirm_path' => '',
-      'page_admin_theme' => FALSE,
+      'page_theme_name' => '',
       'form_title' => 'both',
       'form_submit_once' => FALSE,
       'form_exception_message' => '',
@@ -1063,6 +1063,11 @@ public static function getDefaultSettings() {
       'form_access_denied_message' => '',
       'form_access_denied_attributes' => [],
       'form_file_limit' => '',
+      'share' => FALSE,
+      'share_node' => FALSE,
+      'share_theme_name' => '',
+      'share_title' => TRUE,
+      'share_page_body_attributes' => [],
       'submission_label' => '',
       'submission_log' => FALSE,
       'submission_views' => [],
@@ -1088,11 +1093,17 @@ public static function getDefaultSettings() {
       'wizard_progress_percentage' => FALSE,
       'wizard_progress_link' => FALSE,
       'wizard_progress_states' => FALSE,
+      'wizard_auto_forward' => TRUE,
       'wizard_start_label' => '',
       'wizard_preview_link' => FALSE,
       'wizard_confirmation' => TRUE,
       'wizard_confirmation_label' => '',
       'wizard_track' => '',
+      'wizard_prev_button_label' => '',
+      'wizard_next_button_label' => '',
+      'wizard_toggle' => FALSE,
+      'wizard_toggle_show_label' => '',
+      'wizard_toggle_hide_label' => '',
       'preview' => DRUPAL_DISABLED,
       'preview_label' => '',
       'preview_title' => '',
@@ -1101,7 +1112,7 @@ public static function getDefaultSettings() {
       'preview_excluded_elements' => [],
       'preview_exclude_empty' => TRUE,
       'preview_exclude_empty_checkbox' => FALSE,
-      'draft' => self::DRAFT_NONE,
+      'draft' => WebformInterface::DRAFT_NONE,
       'draft_multiple' => FALSE,
       'draft_auto_save' => FALSE,
       'draft_saved_message' => '',
@@ -1148,10 +1159,14 @@ public function getSubmissionForm(array $values = [], $operation = 'add') {
     // Test a single webform variant which is set via
     // ?_webform_handler[ELEMENT_KEY]={variant_id}.
     $webform_variant = \Drupal::request()->query->get('_webform_variant') ?: [];
-    if ($webform_variant &&
-      ($operation === 'add' && $this->access('update') || $operation === 'test' && $this->access('test'))) {
-      $values += ['data' => []];
-      $values['data'] = $webform_variant + $values['data'];
+    if ($webform_variant) {
+      $is_add_operation = ($operation === 'add' && $this->access('update'));
+      $is_test_operation = ($operation === 'test' && $this->access('test'));
+      $is_share_operation = (strpos(\Drupal::routeMatch()->getRouteName(), 'entity.webform.share_page') === 0);
+      if ($is_add_operation || $is_test_operation || $is_share_operation) {
+        $values += ['data' => []];
+        $values['data'] = $webform_variant + $values['data'];
+      }
     }
 
     // Set this webform's id which can be used by preCreate hooks.
@@ -1188,7 +1203,7 @@ public function getElementsOriginalRaw() {
   public function getElementsOriginalDecoded() {
     $this->elementsOriginal;
     try {
-      $elements = Yaml::decode($this->elementsOriginal);
+      $elements = WebformYaml::decode($this->elementsOriginal);
       return (is_array($elements)) ? $elements : [];
     }
     catch (\Exception $exception) {
@@ -1425,7 +1440,7 @@ protected function initElements() {
       // If current webform is translated, load the base (default) webform and
       // apply the translation to the elements.
       if ($config_translation
-        && ($this->langcode != $language_manager->getCurrentLanguage()->getId())) {
+        && ($this->langcode !== $language_manager->getCurrentLanguage()->getId())) {
         // Always get the elements in the original language.
         $elements = $translation_manager->getElements($this);
         // For none admin routes get the element (label) translations.
@@ -1434,7 +1449,7 @@ protected function initElements() {
         }
       }
       else {
-        $elements = Yaml::decode($this->elements);
+        $elements = WebformYaml::decode($this->elements);
       }
 
       // Since YAML supports simple values.
@@ -1541,7 +1556,7 @@ protected function initElementsRecursive(array &$elements, $parent = '', $depth
         $parent_element['#webform_children'][$key] = $key;
         // Set #parent_flexbox to TRUE is the parent element is a
         // 'webform_flexbox'.
-        $element['#webform_parent_flexbox'] = (isset($parent_element['#type']) && $parent_element['#type'] == 'webform_flexbox') ? TRUE : FALSE;
+        $element['#webform_parent_flexbox'] = (isset($parent_element['#type']) && $parent_element['#type'] === 'webform_flexbox') ? TRUE : FALSE;
 
         $element['#webform_parents'] = $parent_element['#webform_parents'];
       }
@@ -1584,7 +1599,7 @@ protected function initElementsRecursive(array &$elements, $parent = '', $depth
         $element_plugin->initialize($element);
 
         // Track flexbox.
-        if ($element['#type'] == 'flexbox' || $element['#type'] == 'webform_flexbox') {
+        if ($element['#type'] === 'flexbox' || $element['#type'] === 'webform_flexbox') {
           $this->hasFlexboxLayout = TRUE;
         }
 
@@ -1723,7 +1738,7 @@ public function setElementProperties($key, array $properties, $parent_key = '')
         $last_action_key = end($this->elementsActions);
         $updated_elements = [];
         foreach ($elements as $element_key => $element) {
-          if ($element_key == $last_action_key) {
+          if ($element_key === $last_action_key) {
             $updated_elements[$key] = $properties;
           }
           $updated_elements[$element_key] = $element;
@@ -1760,12 +1775,12 @@ protected function setElementPropertiesRecursive(array &$elements, $key, array $
         continue;
       }
 
-      if ($element_key == $key) {
+      if ($element_key === $key) {
         $element = $properties + WebformElementHelper::removeProperties($element);
         return TRUE;
       }
 
-      if ($element_key == $parent_key) {
+      if ($element_key === $parent_key) {
         $element[$key] = $properties;
         return TRUE;
       }
@@ -1823,7 +1838,7 @@ protected function deleteElementRecursive(array &$elements, $key) {
         continue;
       }
 
-      if ($element_key == $key) {
+      if ($element_key === $key) {
         $sub_element_keys = [$element_key => $element_key];
         $this->collectSubElementKeysRecursive($sub_element_keys, $element);
         unset($elements[$element_key]);
@@ -1878,6 +1893,8 @@ public function getPages($operation = 'default', WebformSubmissionInterface $web
    *
    * @return array
    *   An associative array of webform wizard pages.
+   *
+   * @see \Drupal\webform_cards\WebformCardsManager::buildPages
    */
   protected function buildPages($operation = 'default') {
     if (isset($this->pages[$operation])) {
@@ -1914,32 +1931,37 @@ protected function buildPages($operation = 'default') {
         // to the current user.
         $access_operation = (in_array($operation, ['default', 'add'])) ? 'create' : 'update';
         if ($element_plugin->checkAccessRules($access_operation, $element)) {
-          $pages[$key] = array_intersect_key($element, $wizard_properties);
-          $pages[$key]['#access'] = TRUE;
+          $pages[$key] = array_intersect_key($element, $wizard_properties) + [
+              '#type' => 'page',
+              '#access' => TRUE,
+            ];
         }
       }
     }
 
     // Add preview page.
     $settings = $this->getSettings();
-    if ($settings['preview'] != DRUPAL_DISABLED) {
+    if ((int) $settings['preview'] !== DRUPAL_DISABLED) {
       // If there is no start page, we must define one.
       if (empty($pages)) {
-        $pages['webform_start'] = [
+        $pages[WebformInterface::PAGE_START] = [
           '#title' => $this->getSetting('wizard_start_label', TRUE),
+          '#type' => 'page',
           '#access' => TRUE,
         ];
       }
-      $pages['webform_preview'] = [
+      $pages[WebformInterface::PAGE_PREVIEW] = [
         '#title' => $this->getSetting('preview_label', TRUE),
+        '#type' => 'page',
         '#access' => TRUE,
       ];
     }
 
     // Only add complete page, if there are some pages.
     if ($pages && $this->getSetting('wizard_confirmation')) {
-      $pages['webform_confirmation'] = [
+      $pages[WebformInterface::PAGE_CONFIRMATION] = [
         '#title' => $this->getSetting('wizard_confirmation_label', TRUE),
+        '#type' => 'page',
         '#access' => TRUE,
       ];
     }
@@ -2160,7 +2182,33 @@ public function preSave(EntityStorageInterface $storage) {
    * {@inheritdoc}
    */
   public function postSave(EntityStorageInterface $storage, $update = TRUE) {
-    parent::postSave($storage, $update);
+    // Because webform are not fieldable, when a webform is saved not all
+    // config/content entity related caches need to be cleared.
+    // parent::postSave($storage, $update);
+    /**************************************************************************/
+
+    $this->invalidateTagsOnSave($update);
+
+    $entity_type_manager = $this->entityTypeManager();
+    $bundle_of = $this->getEntityType()->getBundleOf();
+    if (!$update) {
+      \Drupal::service('entity_bundle.listener')->onBundleCreate($this->id(), $bundle_of);
+    }
+    else {
+      // Invalidate the render cache of entities for which this entity
+      // is a bundle.
+      if ($entity_type_manager->hasHandler($bundle_of, 'view_builder')) {
+        $entity_type_manager->getViewBuilder($bundle_of)->resetCache();
+      }
+
+      // Webform does not not clear field definitions on every change.
+      // @see \Drupal\Core\Entity\EntityFieldManager::clearCachedFieldDefinitions
+      // Entity bundle field definitions may depend on bundle settings.
+      // \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
+      $this->entityTypeBundleInfo()->clearCachedBundles();
+    }
+
+    /**************************************************************************/
 
     // Update paths.
     $this->updatePaths();
@@ -2170,7 +2218,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
     // different.
     $elements_original = $this->getElementsOriginalDecoded() ?: [];
     $elements = $this->getElementsDecoded() ?: [];
-    if ($elements_original != $elements) {
+    if ($elements_original !== $elements) {
       $elements_original = WebformElementHelper::getFlattened($elements_original);
       $elements = WebformElementHelper::getFlattened($elements);
 
@@ -2188,7 +2236,7 @@ public function postSave(EntityStorageInterface $storage, $update = TRUE) {
 
       // Handle update element.
       foreach ($elements as $element_key => $element) {
-        if (isset($elements_original[$element_key]) && $elements_original[$element_key] != $element) {
+        if (isset($elements_original[$element_key]) && $elements_original[$element_key] !== $element) {
           $this->invokeHandlers('updateElement', $element_key, $element, $elements_original[$element_key]);
         }
       }
@@ -2264,13 +2312,17 @@ public function deletePaths() {
       return;
     }
 
-    /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
-    $path_alias_storage = \Drupal::service('path.alias_storage');
+    $path_alias_storage = \Drupal::entityTypeManager()->getStorage('path_alias');
+    $query = $path_alias_storage->getQuery('OR');
 
     // Delete webform base, confirmation, submissions and drafts paths.
     $path_suffixes = ['', '/confirmation', '/submissions', '/drafts'];
     foreach ($path_suffixes as $path_suffix) {
-      $path_alias_storage->delete(['source' => '/webform/' . $this->id() . $path_suffix]);
+      $query->condition('path', '/webform/' . $this->id() . $path_suffix);
+    }
+
+    if ($ids = $query->execute()) {
+      $path_alias_storage->delete($path_alias_storage->loadMultiple($ids));
     }
   }
 
@@ -2285,18 +2337,26 @@ public function deletePaths() {
    *   (optional) The language code of the alias.
    */
   protected function updatePath($source, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED) {
-    /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
-    $path_alias_storage = \Drupal::service('path.alias_storage');
-
-    $path = $path_alias_storage->load(['source' => $source, 'langcode' => $langcode]);
+    $path_alias_storage = \Drupal::entityTypeManager()->getStorage('path_alias');
 
     // Check if the path alias is already setup.
-    if ($path && ($path['alias'] == $alias)) {
-      return;
+    $path_aliases = $path_alias_storage->loadByProperties(['path' => $source, 'langcode' => $langcode]);
+    if ($path_aliases) {
+      /** @var \Drupal\path_alias\PathAliasInterface $path_alias */
+      $path_alias = reset($path_aliases);
+      if ($path_alias->getAlias() === $alias) {
+        return;
+      }
+    }
+    else {
+      $path_alias = $path_alias_storage->create([
+        'path' => $source,
+        'langcode' => $langcode,
+      ]);
     }
 
-    $pid = $path['pid'] ?? NULL;
-    $path_alias_storage->save($source, $alias, $langcode, $pid);
+    $path_alias->setAlias($alias);
+    $path_alias->save();
   }
 
   /**
@@ -2405,7 +2465,7 @@ public function getHandlers($plugin_id = NULL, $status = NULL, $results = NULL,
     // This is used to limit track and enforce a handlers cardinality.
     if (isset($plugin_id)) {
       foreach ($handlers as $instance_id => $handler) {
-        if ($handler->getPluginId() != $plugin_id) {
+        if ($handler->getPluginId() !== $plugin_id) {
           $handlers->removeInstanceId($instance_id);
         }
       }
@@ -2415,7 +2475,7 @@ public function getHandlers($plugin_id = NULL, $status = NULL, $results = NULL,
     // This is used to limit track and enforce a handlers cardinality.
     if (isset($status)) {
       foreach ($handlers as $instance_id => $handler) {
-        if ($handler->getStatus() != $status) {
+        if ($handler->getStatus() !== $status) {
           $handlers->removeInstanceId($instance_id);
         }
       }
@@ -2426,7 +2486,7 @@ public function getHandlers($plugin_id = NULL, $status = NULL, $results = NULL,
     if (isset($results)) {
       foreach ($handlers as $instance_id => $handler) {
         $plugin_definition = $handler->getPluginDefinition();
-        if ($plugin_definition['results'] != $results) {
+        if ($plugin_definition['results'] !== $results) {
           $handlers->removeInstanceId($instance_id);
         }
       }
@@ -2437,7 +2497,7 @@ public function getHandlers($plugin_id = NULL, $status = NULL, $results = NULL,
     if (isset($submission)) {
       foreach ($handlers as $instance_id => $handler) {
         $plugin_definition = $handler->getPluginDefinition();
-        if ($plugin_definition['submission'] != $submission) {
+        if ($plugin_definition['submission'] !== $submission) {
           $handlers->removeInstanceId($instance_id);
         }
       }
@@ -2519,7 +2579,7 @@ public function invokeHandlers($method, &$data, &$context1 = NULL, &$context2 =
         // If a handler has change some settings set override.
         // Only look for altered original settings, which prevents issues where
         // a webform saved settings and default settings are out-of-sync.
-        if (array_intersect_key($settings, $this->settingsOriginal) != $this->settingsOriginal) {
+        if (array_intersect_key($settings, $this->settingsOriginal) !== $this->settingsOriginal) {
           $this->setSettingsOverride($settings);
         }
         return NULL;
@@ -2732,7 +2792,7 @@ public function deleteWebformVariant(WebformVariantInterface $variant) {
   /**
    * {@inheritdoc}
    */
-  public function applyVariants(WebformSubmissionInterface $webform_submission = NULL, $variants = [], $force = FALSE) {
+  public function applyVariants(WebformSubmissionInterface $webform_submission = NULL, array $variants = [], $force = FALSE) {
     // Get variants from webform submission.
     if ($webform_submission) {
       // Make sure webform submission is associated with this webform.
diff --git a/web/modules/webform/src/Entity/Webform.php.orig b/web/modules/webform/src/Entity/Webform.php.orig
deleted file mode 100644
index f5135e7a4a..0000000000
--- a/web/modules/webform/src/Entity/Webform.php.orig
+++ /dev/null
@@ -1,3056 +0,0 @@
-<?php
-
-namespace Drupal\webform\Entity;
-
-use Drupal\Component\Utility\NestedArray;
-use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Cache\Cache;
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
-use Drupal\Core\Serialization\Yaml;
-use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
-use Drupal\Core\Entity\EntityStorageInterface;
-use Drupal\Core\Language\LanguageInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\user\Entity\User;
-use Drupal\user\UserInterface;
-use Drupal\webform\Plugin\WebformElement\WebformActions;
-use Drupal\webform\Plugin\WebformElement\WebformWizardPage;
-use Drupal\webform\Plugin\WebformElementAssetInterface;
-use Drupal\webform\Plugin\WebformElementAttachmentInterface;
-use Drupal\webform\Plugin\WebformElementComputedInterface;
-use Drupal\webform\Plugin\WebformElementVariantInterface;
-use Drupal\webform\Plugin\WebformElementWizardPageInterface;
-use Drupal\webform\Plugin\WebformHandlerMessageInterface;
-use Drupal\webform\Plugin\WebformVariantInterface;
-use Drupal\webform\Plugin\WebformVariantPluginCollection;
-use Drupal\webform\Utility\WebformElementHelper;
-use Drupal\webform\Utility\WebformReflectionHelper;
-use Drupal\webform\Plugin\WebformHandlerInterface;
-use Drupal\webform\Plugin\WebformHandlerPluginCollection;
-use Drupal\webform\Utility\WebformTextHelper;
-use Drupal\webform\Utility\WebformYaml;
-use Drupal\webform\WebformException;
-use Drupal\webform\WebformInterface;
-use Drupal\webform\WebformSubmissionInterface;
-use Drupal\webform\WebformSubmissionStorageInterface;
-
-/**
- * Defines the webform entity.
- *
- * @ConfigEntityType(
- *   id = "webform",
- *   label = @Translation("Webform"),
- *   label_collection = @Translation("Webforms"),
- *   label_singular = @Translation("webform"),
- *   label_plural = @Translation("webforms"),
- *   label_count = @PluralTranslation(
- *     singular = "@count webform",
- *     plural = "@count webforms",
- *   ),
- *   handlers = {
- *     "storage" = "\Drupal\webform\WebformEntityStorage",
- *     "view_builder" = "Drupal\webform\WebformEntityViewBuilder",
- *     "list_builder" = "Drupal\webform\WebformEntityListBuilder",
- *     "access" = "Drupal\webform\WebformEntityAccessControlHandler",
- *     "form" = {
- *       "add" = "Drupal\webform\WebformEntityAddForm",
- *       "duplicate" = "Drupal\webform\WebformEntityAddForm",
- *       "delete" = "Drupal\webform\WebformEntityDeleteForm",
- *       "edit" = "Drupal\webform\WebformEntityElementsForm",
- *       "export" = "Drupal\webform\WebformEntityExportForm",
- *       "settings" = "Drupal\webform\EntitySettings\WebformEntitySettingsGeneralForm",
- *       "settings_form" = "Drupal\webform\EntitySettings\WebformEntitySettingsFormForm",
- *       "settings_submissions" = "Drupal\webform\EntitySettings\WebformEntitySettingsSubmissionsForm",
- *       "settings_confirmation" = "Drupal\webform\EntitySettings\WebformEntitySettingsConfirmationForm",
- *       "settings_assets" = "Drupal\webform\EntitySettings\WebformEntitySettingsAssetsForm",
- *       "settings_access" = "Drupal\webform\EntitySettings\WebformEntitySettingsAccessForm",
- *       "handlers" = "Drupal\webform\WebformEntityHandlersForm",
- *       "variants" = "Drupal\webform\WebformEntityVariantsForm",
- *     }
- *   },
- *   admin_permission = "administer webform",
- *   bundle_of = "webform_submission",
- *   static_cache = TRUE,
- *   entity_keys = {
- *     "id" = "id",
- *     "label" = "title",
- *   },
- *   links = {
- *     "canonical" = "/webform/{webform}",
- *     "access-denied" = "/webform/{webform}/access-denied",
- *     "submissions" = "/webform/{webform}/submissions",
- *     "add-form" = "/webform/{webform}",
- *     "edit-form" = "/admin/structure/webform/manage/{webform}/elements",
- *     "test-form" = "/webform/{webform}/test",
- *     "duplicate-form" = "/admin/structure/webform/manage/{webform}/duplicate",
- *     "delete-form" = "/admin/structure/webform/manage/{webform}/delete",
- *     "export-form" = "/admin/structure/webform/manage/{webform}/export",
- *     "settings" = "/admin/structure/webform/manage/{webform}/settings",
- *     "settings-form" = "/admin/structure/webform/manage/{webform}/settings/form",
- *     "settings-submissions" = "/admin/structure/webform/manage/{webform}/settings/submissions",
- *     "settings-confirmation" = "/admin/structure/webform/manage/{webform}/settings/confirmation",
- *     "settings-assets" = "/admin/structure/webform/manage/{webform}/settings/assets",
- *     "settings-access" = "/admin/structure/webform/manage/{webform}/settings/access",
- *     "handlers" = "/admin/structure/webform/manage/{webform}/handlers",
- *     "variants" = "/admin/structure/webform/manage/{webform}/variants",
- *     "results-submissions" = "/admin/structure/webform/manage/{webform}/results/submissions",
- *     "results-export" = "/admin/structure/webform/manage/{webform}/results/download",
- *     "results-log" = "/admin/structure/webform/manage/{webform}/results/log",
- *     "results-clear" = "/admin/structure/webform/manage/{webform}/results/clear",
- *     "collection" = "/admin/structure/webform",
- *   },
- *   config_export = {
- *     "status",
- *     "open",
- *     "close",
- *     "weight",
- *     "uid",
- *     "template",
- *     "archive",
- *     "id",
- *     "uuid",
- *     "title",
- *     "description",
- *     "category",
- *     "elements",
- *     "css",
- *     "javascript",
- *     "settings",
- *     "access",
- *     "handlers",
- *     "variants",
- *     "third_party_settings",
- *   },
- *   lookup_keys = {
- *     "status",
- *     "template",
- *   },
- * )
- */
-class Webform extends ConfigEntityBundleBase implements WebformInterface {
-
-  use StringTranslationTrait;
-
-  /**
-   * The webform ID.
-   *
-   * @var string
-   */
-  protected $id;
-
-  /**
-   * The webform UUID.
-   *
-   * @var string
-   */
-  protected $uuid;
-
-  /**
-   * The webform's current operation.
-   *
-   * @var string
-   */
-  protected $operation;
-
-  /**
-   * The webform override state.
-   *
-   * When set to TRUE the webform can't not be saved.
-   *
-   * @var bool
-   */
-  protected $override = FALSE;
-
-  /**
-   * The webform status.
-   *
-   * @var string
-   */
-  protected $status = WebformInterface::STATUS_OPEN;
-
-  /**
-   * The webform open date/time.
-   *
-   * @var bool
-   */
-  protected $open;
-
-  /**
-   * The webform close date/time.
-   *
-   * @var bool
-   */
-  protected $close;
-
-  /**
-   * The webform weight.
-   *
-   * @var int
-   */
-  protected $weight = 0;
-
-  /**
-   * The webform template indicator.
-   *
-   * @var bool
-   */
-  protected $template = FALSE;
-
-  /**
-   * The webform archive indicator.
-   *
-   * @var bool
-   */
-  protected $archive = FALSE;
-
-  /**
-   * The webform title.
-   *
-   * @var string
-   */
-  protected $title;
-
-  /**
-   * The webform description.
-   *
-   * @var string
-   */
-  protected $description;
-
-  /**
-   * The webform options category.
-   *
-   * @var string
-   */
-  protected $category;
-
-  /**
-   * The owner's uid.
-   *
-   * @var int
-   */
-  protected $uid;
-
-  /**
-   * The webform settings.
-   *
-   * @var array
-   */
-  protected $settings = [];
-
-  /**
-   * The webform settings original.
-   *
-   * @var string
-   */
-  protected $settingsOriginal;
-
-  /**
-   * The webform access controls.
-   *
-   * @var array
-   */
-  protected $access = [];
-
-  /**
-   * The webform elements.
-   *
-   * @var string
-   */
-  protected $elements;
-
-  /**
-   * The CSS style sheet.
-   *
-   * @var string
-   */
-  protected $css = '';
-
-  /**
-   * The JavaScript.
-   *
-   * @var string
-   */
-  protected $javascript = '';
-
-  /**
-   * The array of webform handlers for this webform.
-   *
-   * @var array
-   */
-  protected $handlers = [];
-
-  /**
-   * Holds the collection of webform handlers that are used by this webform.
-   *
-   * @var \Drupal\webform\Plugin\WebformHandlerPluginCollection
-   */
-  protected $handlersCollection;
-
-  /**
-   * The array of webform variants for this webform.
-   *
-   * @var array
-   */
-  protected $variants = [];
-
-  /**
-   * Holds the collection of webform variants that are used by this webform.
-   *
-   * @var \Drupal\webform\Plugin\WebformVariantsPluginCollection
-   */
-  protected $variantsCollection;
-
-  /**
-   * The webform elements original.
-   *
-   * @var string
-   */
-  protected $elementsOriginal;
-
-  /**
-   * The webform elements decoded.
-   *
-   * @var array
-   */
-  protected $elementsDecoded;
-
-  /**
-   * The webform elements initializes (and decoded).
-   *
-   * @var array
-   */
-  protected $elementsInitialized;
-
-  /**
-   * The webform elements decoded and flattened.
-   *
-   * @var array
-   */
-  protected $elementsDecodedAndFlattened;
-
-  /**
-   * The webform elements initialized and flattened.
-   *
-   * @var array
-   */
-  protected $elementsInitializedAndFlattened;
-
-  /**
-   * The webform elements initialized, flattened, and has value.
-   *
-   * @var array
-   */
-  protected $elementsInitializedFlattenedAndHasValue;
-
-  /**
-   * The webform elements translations.
-   *
-   * @var array
-   */
-  protected $elementsTranslations;
-
-  /**
-   * Track the elements that are prepopulated.
-   *
-   * @var array
-   */
-  protected $elementsPrepopulate = [];
-
-  /**
-   * Track the elements that are 'webform_actions' (aka submit buttons).
-   *
-   * @var array
-   */
-  protected $elementsActions = [];
-
-  /**
-   * Track the elements that are 'webform_pages' (aka Wizard pages).
-   *
-   * @var array
-   */
-  protected $elementsWizardPages = [];
-
-  /**
-   * Track managed file elements.
-   *
-   * @var array
-   */
-  protected $elementsManagedFiles = [];
-
-  /**
-   * Track attachment elements.
-   *
-   * @var array
-   */
-  protected $elementsAttachments = [];
-
-  /**
-   * Track computed elements.
-   *
-   * @var array
-   */
-  protected $elementsComputed = [];
-
-  /**
-   * Track variant elements.
-   *
-   * @var array
-   */
-  protected $elementsVariant = [];
-
-  /**
-   * Track elements CSS.
-   *
-   * @var array
-   */
-  protected $elementsCss = [];
-
-  /**
-   * Track elements JavaScript.
-   *
-   * @var array
-   */
-  protected $elementsJavaScript = [];
-
-  /**
-   * A webform's default data extracted from each element's default value or value.
-   *
-   * @var array
-   */
-  protected $elementsDefaultData = [];
-
-  /**
-   * The webform pages.
-   *
-   * @var array
-   */
-  protected $pages;
-
-  /**
-   * Track if the webform is using a flexbox layout.
-   *
-   * @var bool
-   */
-  protected $hasFlexboxLayout = FALSE;
-
-  /**
-   * Track if the webform has container.
-   *
-   * @var bool
-   */
-  protected $hasContainer = FALSE;
-
-  /**
-   * Track if the webform has conditions (i.e. #states).
-   *
-   * @var bool
-   */
-  protected $hasConditions = FALSE;
-
-  /**
-   * Track if the webform has required elements.
-   *
-   * @var bool
-   */
-  protected $hasRequired = FALSE;
-
-  /**
-   * Track if the webform has translations.
-   *
-   * @var bool
-   */
-  protected $hasTranslations;
-
-  /**
-   * Track if the webform has message handler.
-   *
-   * @var bool
-   */
-  protected $hasMessageHandler;
-
-  /**
-   * Track if a webform handler requires anonymous submission tracking .
-   *
-   * @var bool
-   */
-  protected $hasAnonymousSubmissionTrackingHandler;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getLangcode() {
-    return $this->langcode;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getWeight() {
-    return $this->weight;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getOwner() {
-    return $this->uid ? User::load($this->uid) : NULL;
-  }
-
-  /**
-   * Sets the entity owner's user entity.
-   *
-   * @param \Drupal\user\UserInterface $account
-   *   The owner user entity.
-   *
-   * @return $this
-   */
-  public function setOwner(UserInterface $account) {
-    $this->uid = $account->id();
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getOwnerId() {
-    return $this->uid;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setOwnerId($uid) {
-    $this->uid = ($uid) ? $uid : NULL;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getOperation() {
-    return $this->operation;
-
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setOperation($operation) {
-    $this->operation = $operation;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isTest() {
-    return ($this->operation === 'test') ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setOverride($override = TRUE) {
-    $this->override = $override;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isOverridden() {
-    return $this->override;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setStatus($status) {
-    if ($status === NULL || $status === WebformInterface::STATUS_SCHEDULED) {
-      $this->status = WebformInterface::STATUS_SCHEDULED;
-    }
-    elseif ($status === WebformInterface::STATUS_OPEN) {
-      $this->status = WebformInterface::STATUS_OPEN;
-    }
-    elseif ($status === WebformInterface::STATUS_CLOSED) {
-      $this->status = WebformInterface::STATUS_CLOSED;
-    }
-    else {
-      $this->status = ((bool) $status) ? WebformInterface::STATUS_OPEN : WebformInterface::STATUS_CLOSED;
-    }
-
-    // Clear open and close if status is not scheduled.
-    if ($this->status !== WebformInterface::STATUS_SCHEDULED) {
-      $this->open = NULL;
-      $this->close = NULL;
-    }
-
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function status() {
-    return $this->isOpen();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isOpen() {
-    // Archived webforms are always closed.
-    if ($this->isArchived()) {
-      return FALSE;
-    }
-
-    switch ($this->status) {
-      case WebformInterface::STATUS_OPEN:
-        return TRUE;
-
-      case WebformInterface::STATUS_CLOSED:
-        return FALSE;
-
-      case WebformInterface::STATUS_SCHEDULED:
-        $is_opened = TRUE;
-        if ($this->open && strtotime($this->open) > time()) {
-          $is_opened = FALSE;
-        }
-
-        $is_closed = FALSE;
-        if ($this->close && strtotime($this->close) < time()) {
-          $is_closed = TRUE;
-        }
-
-        return ($is_opened && !$is_closed) ? TRUE : FALSE;
-    }
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isClosed() {
-    return !$this->isOpen();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isScheduled() {
-    return ($this->status === WebformInterface::STATUS_SCHEDULED);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isOpening() {
-    return ($this->isScheduled() && ($this->open && strtotime($this->open) > time())) ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isTemplate() {
-    return $this->template ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isArchived() {
-    return $this->archive ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isConfidential() {
-    return $this->getSetting('form_confidential');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasRemoteAddr() {
-    return (!$this->isConfidential() && $this->getSetting('form_remote_addr')) ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isResultsDisabled() {
-    $elements = $this->getElementsDecoded();
-    $settings = $this->getSettings();
-    return (!empty($settings['results_disabled']) || !empty($elements['#method'])) ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasSubmissions() {
-    /** @var \Drupal\webform\WebformSubmissionStorageInterface $submission_storage */
-    $submission_storage = \Drupal::entityTypeManager()->getStorage('webform_submission');
-    return ($submission_storage->getTotal($this)) ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasSubmissionLog() {
-    return $this->getSetting('submission_log', TRUE) ?: FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasTranslations() {
-    if (isset($this->hasTranslations)) {
-      return $this->hasTranslations;
-    }
-
-    // Make sure the config translation module is enabled.
-    if (!\Drupal::moduleHandler()->moduleExists('config_translation')) {
-      $this->hasTranslations = FALSE;
-      return $this->hasTranslations;
-    }
-
-    /** @var \Drupal\locale\LocaleConfigManager $local_config_manager */
-    $local_config_manager = \Drupal::service('locale.config_manager');
-    $languages = \Drupal::languageManager()->getLanguages();
-    foreach ($languages as $langcode => $language) {
-      if ($local_config_manager->hasTranslation('webform.webform.' . $this->id(), $langcode)) {
-        $this->hasTranslations = TRUE;
-        return $this->hasTranslations;
-      }
-    }
-
-    $this->hasTranslations = FALSE;
-    return $this->hasTranslations;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasPage() {
-    $settings = $this->getSettings();
-    return $settings['page'] ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasManagedFile() {
-    $this->initElements();
-    return (!empty($this->elementsManagedFiles)) ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasAttachments() {
-    $this->initElements();
-    return (!empty($this->elementsAttachments)) ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasComputed() {
-    $this->initElements();
-    return (!empty($this->elementsComputed)) ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasVariants() {
-    $this->initElements();
-    return (!empty($this->elementsVariant)) ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasFlexboxLayout() {
-    $this->initElements();
-    return $this->hasFlexboxLayout;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasContainer() {
-    $this->initElements();
-    return $this->hasContainer;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasConditions() {
-    $this->initElements();
-    return $this->hasConditions;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasRequired() {
-    $this->initElements();
-    return $this->hasRequired;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasActions() {
-    return $this->getNumberOfActions() ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getNumberOfActions() {
-    $this->initElements();
-    return count($this->elementsActions);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasPreview() {
-    return ($this->getSetting('preview') != DRUPAL_DISABLED);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasWizardPages() {
-    return $this->getNumberOfWizardPages() ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getNumberOfWizardPages() {
-    $this->initElements();
-    return count($this->elementsWizardPages);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDescription() {
-    return $this->description;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setDescription($description) {
-    $this->description = $description;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAssets() {
-    $this->initElements();
-
-    // Css.
-    $css = [];
-    $shared_css = \Drupal::config('webform.settings')->get('assets.css') ?: '';
-    if ($shared_css) {
-      $css[] = $shared_css;
-    }
-    $webform_css = $this->css ?: '';
-    if ($webform_css) {
-      $css[] = $webform_css;
-    }
-    $css += $this->elementsCss;
-
-    // JavaScript.
-    $javascript = [];
-    $shared_javascript = \Drupal::config('webform.settings')->get('assets.javascript') ?: '';
-    if ($shared_javascript) {
-      $javascript[] = $shared_javascript;
-    }
-    $webform_javascript = $this->javascript ?: '';
-    if ($webform_javascript) {
-      $javascript[] = $webform_javascript;
-    }
-    $javascript += $this->elementsJavaScript;
-
-    return [
-      'css' => implode(PHP_EOL, $css),
-      'javascript' => implode(PHP_EOL, $javascript),
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCss() {
-    return $this->css;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setCss($css) {
-    $this->css = $css;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getJavaScript() {
-    return $this->javascript;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setJavaScript($javascript) {
-    $this->javascript = $javascript;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getSettings() {
-    // Settings should not be empty even.
-    // https://www.drupal.org/node/2880392.
-    return (isset($this->settings)) ? $this->settings +
-      self::getDefaultSettings() : self::getDefaultSettings();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setSettings(array $settings) {
-    // Always apply the default settings.
-    $this->settings += static::getDefaultSettings();
-
-    // Now apply new settings.
-    foreach ($settings as $name => $value) {
-      if (array_key_exists($name, $this->settings)) {
-        $this->settings[$name] = $value;
-      }
-    }
-
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getSetting($key, $default = FALSE) {
-    $settings = $this->getSettings();
-    $value = (isset($settings[$key])) ? $settings[$key] : NULL;
-    if ($default) {
-      return $value ?: \Drupal::config('webform.settings')->get('settings.default_' . $key);
-    }
-    else {
-      return $value;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setSetting($key, $value) {
-    $settings = $this->getSettings();
-    $settings[$key] = $value;
-    $this->setSettings($settings);
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function resetSettings() {
-    $this->settings = $this->settingsOriginal;
-    $this->setOverride(FALSE);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setSettingsOverride(array $settings) {
-    $this->setSettings($settings);
-    $this->setOverride();
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setSettingOverride($key, $value) {
-    $this->setSetting($key, $value);
-    $this->setOverride();
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setPropertyOverride($property_name, $value) {
-    $this->set($property_name, $value);
-    $this->setOverride();
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAccessRules() {
-    return $this->access;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setAccessRules(array $access) {
-    $this->access = $access;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getDefaultSettings() {
-    return [
-      'ajax' => FALSE,
-      'ajax_scroll_top' => 'form',
-      'ajax_progress_type' => '',
-      'ajax_effect' => '',
-      'ajax_speed' => NULL,
-      'page' => TRUE,
-      'page_submit_path' => '',
-      'page_confirm_path' => '',
-      'page_admin_theme' => FALSE,
-      'form_title' => 'both',
-      'form_submit_once' => FALSE,
-      'form_exception_message' => '',
-      'form_open_message' => '',
-      'form_close_message' => '',
-      'form_previous_submissions' => TRUE,
-      'form_confidential' => FALSE,
-      'form_confidential_message' => '',
-      'form_remote_addr' => TRUE,
-      'form_convert_anonymous' => FALSE,
-      'form_prepopulate' => FALSE,
-      'form_prepopulate_source_entity' => FALSE,
-      'form_prepopulate_source_entity_required' => FALSE,
-      'form_prepopulate_source_entity_type' => FALSE,
-      'form_reset' => FALSE,
-      'form_disable_autocomplete' => FALSE,
-      'form_novalidate' => FALSE,
-      'form_disable_inline_errors' => FALSE,
-      'form_required' => FALSE,
-      'form_unsaved' => FALSE,
-      'form_disable_back' => FALSE,
-      'form_submit_back' => FALSE,
-      'form_autofocus' => FALSE,
-      'form_details_toggle' => FALSE,
-      'form_access_denied' => WebformInterface::ACCESS_DENIED_DEFAULT,
-      'form_access_denied_title' => '',
-      'form_access_denied_message' => '',
-      'form_access_denied_attributes' => [],
-      'form_file_limit' => '',
-      'submission_label' => '',
-      'submission_log' => FALSE,
-      'submission_views' => [],
-      'submission_views_replace' => [],
-      'submission_user_columns' => [],
-      'submission_user_duplicate' => FALSE,
-      'submission_access_denied' => WebformInterface::ACCESS_DENIED_DEFAULT,
-      'submission_access_denied_title' => '',
-      'submission_access_denied_message' => '',
-      'submission_access_denied_attributes' => [],
-      'submission_exception_message' => '',
-      'submission_locked_message' => '',
-      'submission_excluded_elements' => [],
-      'submission_exclude_empty' => FALSE,
-      'submission_exclude_empty_checkbox' => FALSE,
-      'previous_submission_message' => '',
-      'previous_submissions_message' => '',
-      'autofill' => FALSE,
-      'autofill_message' => '',
-      'autofill_excluded_elements' => [],
-      'wizard_progress_bar' => TRUE,
-      'wizard_progress_pages' => FALSE,
-      'wizard_progress_percentage' => FALSE,
-      'wizard_progress_link' => FALSE,
-      'wizard_progress_states' => FALSE,
-      'wizard_start_label' => '',
-      'wizard_preview_link' => FALSE,
-      'wizard_confirmation' => TRUE,
-      'wizard_confirmation_label' => '',
-      'wizard_track' => '',
-      'preview' => DRUPAL_DISABLED,
-      'preview_label' => '',
-      'preview_title' => '',
-      'preview_message' => '',
-      'preview_attributes' => [],
-      'preview_excluded_elements' => [],
-      'preview_exclude_empty' => TRUE,
-      'preview_exclude_empty_checkbox' => FALSE,
-      'draft' => self::DRAFT_NONE,
-      'draft_multiple' => FALSE,
-      'draft_auto_save' => FALSE,
-      'draft_saved_message' => '',
-      'draft_loaded_message' => '',
-      'draft_pending_single_message' => '',
-      'draft_pending_multiple_message' => '',
-      'confirmation_type' => WebformInterface::CONFIRMATION_PAGE,
-      'confirmation_title' => '',
-      'confirmation_message' => '',
-      'confirmation_url' => '',
-      'confirmation_attributes' => [],
-      'confirmation_back' => TRUE,
-      'confirmation_back_label' => '',
-      'confirmation_back_attributes' => [],
-      'confirmation_exclude_query' => FALSE,
-      'confirmation_exclude_token' => FALSE,
-      'confirmation_update' => FALSE,
-      'limit_total' => NULL,
-      'limit_total_interval' => NULL,
-      'limit_total_message' => '',
-      'limit_total_unique' => FALSE,
-      'limit_user' => NULL,
-      'limit_user_interval' => NULL,
-      'limit_user_message' => '',
-      'limit_user_unique' => FALSE,
-      'entity_limit_total' => NULL,
-      'entity_limit_total_interval' => NULL,
-      'entity_limit_user' => NULL,
-      'entity_limit_user_interval' => NULL,
-      'purge' => WebformSubmissionStorageInterface::PURGE_NONE,
-      'purge_days' => NULL,
-      'results_disabled' => FALSE,
-      'results_disabled_ignore' => FALSE,
-      'results_customize' => FALSE,
-      'token_view' => FALSE,
-      'token_update' => FALSE,
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getSubmissionForm(array $values = [], $operation = 'add') {
-    // Test a single webform variant which is set via
-    // ?_webform_handler[ELEMENT_KEY]={variant_id}.
-    $webform_variant = \Drupal::request()->query->get('_webform_variant') ?: [];
-    if ($webform_variant &&
-      ($operation === 'add' && $this->access('update') || $operation === 'test' && $this->access('test'))) {
-      $values += ['data' => []];
-      $values['data'] = $webform_variant + $values['data'];
-    }
-
-    // Set this webform's id which can be used by preCreate hooks.
-    $values['webform_id'] = $this->id();
-
-    /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
-    $webform_submission = $this->entityTypeManager()
-      ->getStorage('webform_submission')
-      ->create($values);
-
-    // Pass this webform to the webform submission as a direct entity reference.
-    // This guarantees overridden properties and settings are maintained.
-    // Not sure why the overridden webform is not being correctly passed to the
-    // webform submission.
-    // @see \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem::setValue
-    if ($this->isOverridden()) {
-      $webform_submission->webform_id->entity = $this;
-    }
-
-    return \Drupal::service('entity.form_builder')
-      ->getForm($webform_submission, $operation);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsOriginalRaw() {
-    return $this->elementsOriginal;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsOriginalDecoded() {
-    $this->elementsOriginal;
-    try {
-      $elements = Yaml::decode($this->elementsOriginal);
-      return (is_array($elements)) ? $elements : [];
-    }
-    catch (\Exception $exception) {
-      return FALSE;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsRaw() {
-    return $this->elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsDecoded() {
-    $this->initElements();
-    return $this->elementsDecoded;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsInitialized() {
-    $this->initElements();
-    return $this->elementsInitialized;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsInitializedAndFlattened($operation = NULL) {
-    $this->initElements();
-    return $this->checkElementsFlattenedAccess($operation, $this->elementsInitializedAndFlattened);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsDecodedAndFlattened($operation = NULL) {
-    $this->initElements();
-    return $this->checkElementsFlattenedAccess($operation, $this->elementsDecodedAndFlattened);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsInitializedFlattenedAndHasValue($operation = NULL) {
-    $this->initElements();
-    return $this->checkElementsFlattenedAccess($operation, $this->elementsInitializedFlattenedAndHasValue);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsManagedFiles() {
-    $this->initElements();
-    return $this->elementsManagedFiles;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsAttachments() {
-    $this->initElements();
-    return $this->elementsAttachments;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsComputed() {
-    $this->initElements();
-    return $this->elementsComputed;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsVariant() {
-    $this->initElements();
-    return $this->elementsVariant;
-  }
-
-  /**
-   * Check operation access for each element.
-   *
-   * @param string $operation
-   *   (optional) The operation that is to be performed on the element.
-   * @param array $elements
-   *   An associative array of flattened form elements.
-   *
-   * @return array
-   *   An associative array of flattened form elements with each element's
-   *   operation access checked.
-   */
-  protected function checkElementsFlattenedAccess($operation = NULL, array $elements) {
-    if ($operation === NULL) {
-      return $elements;
-    }
-
-    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
-    $element_manager = \Drupal::service('plugin.manager.webform.element');
-    foreach ($elements as $key => $element) {
-      $element_plugin = $element_manager->getElementInstance($element, $this);
-      if (!$element_plugin->checkAccessRules($operation, $element)) {
-        unset($elements[$key]);
-      }
-    }
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsSelectorOptions(array $options = []) {
-    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
-    $element_manager = \Drupal::service('plugin.manager.webform.element');
-
-    // The value element is excluded because it is not available
-    // to the #states API. The value element is available to WebformHandles.
-    // @see \Drupal\webform\Form\WebformHandlerFormBase
-    $options += ['excluded_elements' => ['value']];
-
-    $selectors = [];
-    $elements = $this->getElementsInitializedAndFlattened();
-    foreach ($elements as $element) {
-      $element_plugin = $element_manager->getElementInstance($element, $this);
-
-      // Check excluded elements.
-      if ($options['excluded_elements'] && in_array($element_plugin->getPluginId(), $options['excluded_elements'])) {
-        continue;
-      }
-
-      $element_selectors = $element_plugin->getElementSelectorOptions($element);
-      foreach ($element_selectors as $element_selector_key => $element_selector_value) {
-        // Suffix duplicate selector optgroups with empty characters.
-        //
-        // This prevents elements with the same titles and multiple selectors
-        // from clobbering each other.
-        if (isset($selectors[$element_selector_key]) && is_array($element_selector_value)) {
-          while (isset($selectors[$element_selector_key])) {
-            $element_selector_key .= ' ';
-          }
-          $selectors[$element_selector_key] = $element_selector_value;
-        }
-        else {
-          $selectors[$element_selector_key] = $element_selector_value;
-        }
-      }
-      $selectors += $element_plugin->getElementSelectorOptions($element);
-    }
-    return $selectors;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsSelectorSourceValues() {
-    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
-    $element_manager = \Drupal::service('plugin.manager.webform.element');
-
-    $source_values = [];
-    $elements = $this->getElementsInitializedAndFlattened();
-    foreach ($elements as $element) {
-      $element_plugin = $element_manager->getElementInstance($element, $this);
-      $source_values += $element_plugin->getElementSelectorSourceValues($element);
-    }
-    return $source_values;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsPrepopulate() {
-    $this->initElements();
-    return $this->elementsPrepopulate;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementsDefaultData() {
-    $this->initElements();
-    return $this->elementsDefaultData;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setElements(array $elements) {
-    $this->elements = WebformYaml::encode($elements);
-    $this->resetElements();
-    return $this;
-  }
-
-  /**
-   * Initialize parse webform elements.
-   */
-  protected function initElements() {
-    if (isset($this->elementsInitialized)) {
-      return;
-    }
-
-    // @see \Drupal\webform\Entity\Webform::resetElements
-    $this->hasFlexboxLayout = FALSE;
-    $this->hasContainer = FALSE;
-    $this->hasConditions = FALSE;
-    $this->hasRequired = FALSE;
-    $this->elementsPrepopulate = [];
-    $this->elementsActions = [];
-    $this->elementsWizardPages = [];
-    $this->elementsDecodedAndFlattened = [];
-    $this->elementsInitializedAndFlattened = [];
-    $this->elementsInitializedFlattenedAndHasValue = [];
-    $this->elementsTranslations = [];
-    $this->elementsManagedFiles = [];
-    $this->elementsAttachments = [];
-    $this->elementsComputed = [];
-    $this->elementsVariant = [];
-    $this->elementsCss = [];
-    $this->elementsJavaScript = [];
-    $this->elementsDefaultData = [];
-
-    try {
-      $config_translation = \Drupal::moduleHandler()->moduleExists('config_translation');
-      /** @var \Drupal\webform\WebformTranslationManagerInterface $translation_manager */
-      $translation_manager = \Drupal::service('webform.translation_manager');
-      /** @var \Drupal\Core\Language\LanguageManagerInterface $language_manager */
-      $language_manager = \Drupal::service('language_manager');
-
-      // If current webform is translated, load the base (default) webform and
-      // apply the translation to the elements.
-      if ($config_translation
-        && ($this->langcode != $language_manager->getCurrentLanguage()->getId())) {
-        // Always get the elements in the original language.
-        $elements = $translation_manager->getElements($this);
-        // For none admin routes get the element (label) translations.
-        if (!$translation_manager->isAdminRoute()) {
-          $this->elementsTranslations = $translation_manager->getElements($this, $language_manager->getCurrentLanguage()->getId());
-        }
-      }
-      else {
-        $elements = Yaml::decode($this->elements);
-      }
-
-      // Since YAML supports simple values.
-      $elements = (is_array($elements)) ? $elements : [];
-      $this->elementsDecoded = $elements;
-    }
-    catch (\Exception $exception) {
-      $link = $this->toLink($this->t('Edit'), 'edit-form')->toString();
-      \Drupal::logger('webform')
-        ->notice('%title elements are not valid. @message', [
-          '%title' => $this->label(),
-          '@message' => $exception->getMessage(),
-          'link' => $link,
-        ]);
-      $elements = FALSE;
-    }
-
-    if ($elements !== FALSE) {
-      $this->initElementsRecursive($elements);
-      $this->invokeHandlers('alterElements', $elements, $this);
-    }
-
-    $this->elementsInitialized = $elements;
-  }
-
-  /**
-   * Reset parsed and cached webform elements.
-   */
-  protected function resetElements() {
-    $this->pages = NULL;
-    $this->hasFlexboxLayout = NULL;
-    $this->hasContainer = NULL;
-    $this->hasConditions = NULL;
-    $this->hasRequired = NULL;
-    $this->elementsPrepopulate = [];
-    $this->elementsActions = [];
-    $this->elementsWizardPages = [];
-    $this->elementsDecoded = NULL;
-    $this->elementsInitialized = NULL;
-    $this->elementsDecodedAndFlattened = NULL;
-    $this->elementsInitializedAndFlattened = NULL;
-    $this->elementsInitializedFlattenedAndHasValue = NULL;
-    $this->elementsTranslations = NULL;
-    $this->elementsManagedFiles = [];
-    $this->elementsAttachments = [];
-    $this->elementsComputed = [];
-    $this->elementsVariant = [];
-    $this->elementsCss = [];
-    $this->elementsJavaScript = [];
-    $this->elementsDefaultData = [];
-  }
-
-  /**
-   * Initialize webform elements into a flatten array.
-   *
-   * @param array $elements
-   *   The webform elements.
-   * @param string $parent
-   *   The parent key.
-   * @param int $depth
-   *   The element's depth.
-   */
-  protected function initElementsRecursive(array &$elements, $parent = '', $depth = 0) {
-    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
-    $element_manager = \Drupal::service('plugin.manager.webform.element');
-
-    // Remove ignored properties.
-    $elements = WebformElementHelper::removeIgnoredProperties($elements);
-
-    foreach ($elements as $key => &$element) {
-      if (!WebformElementHelper::isElement($element, $key)) {
-        continue;
-      }
-
-      // Apply translation to element.
-      if (isset($this->elementsTranslations[$key])) {
-        WebformElementHelper::applyTranslation($element, $this->elementsTranslations[$key]);
-      }
-
-      // Prevent regressions where webform_computed_* element is still using
-      // #value instead of #template.
-      if (isset($element['#type']) && strpos($element['#type'], 'webform_computed_') === 0) {
-        if (isset($element['#value']) && !isset($element['#template'])) {
-          $element['#template'] = $element['#value'];
-          unset($element['#value']);
-        }
-      }
-
-      // Copy only the element properties to decoded and flattened elements.
-      $this->elementsDecodedAndFlattened[$key] = WebformElementHelper::getProperties($element);
-
-      // Set webform, id, key, parent_key, depth, and parent children.
-      $element['#webform'] = $this->id();
-      $element['#webform_id'] = $this->id() . '--' . $key;
-      $element['#webform_key'] = $key;
-      $element['#webform_parent_key'] = $parent;
-      $element['#webform_parent_flexbox'] = FALSE;
-      $element['#webform_depth'] = $depth;
-      $element['#webform_children'] = [];
-      $element['#webform_multiple'] = FALSE;
-      $element['#webform_composite'] = FALSE;
-
-      if (!empty($parent)) {
-        $parent_element =& $this->elementsInitializedAndFlattened[$parent];
-        // Add element to the parent element's children.
-        $parent_element['#webform_children'][$key] = $key;
-        // Set #parent_flexbox to TRUE is the parent element is a
-        // 'webform_flexbox'.
-        $element['#webform_parent_flexbox'] = (isset($parent_element['#type']) && $parent_element['#type'] == 'webform_flexbox') ? TRUE : FALSE;
-
-        $element['#webform_parents'] = $parent_element['#webform_parents'];
-      }
-
-      // Add element key to parents.
-      // #webform_parents allows make it possible to use NestedArray::getValue
-      // to get the entire unflattened element.
-      $element['#webform_parents'][] = $key;
-
-      // Set #title and #admin_title to NULL if it is not defined.
-      $element += [
-        '#title' => NULL,
-        '#admin_title' => NULL,
-      ];
-
-      // Set #markup type to 'webform_markup' to trigger #display_on behavior.
-      // @see https://www.drupal.org/node/2036237
-      if (empty($element['#type']) && empty($element['#theme']) && isset($element['#markup'])) {
-        $element['#type'] = 'webform_markup';
-      }
-
-      $element_plugin = NULL;
-      if (isset($element['#type'])) {
-        // Load the element's handler.
-        $element_plugin = $element_manager->getElementInstance($element, $this);
-
-        // Store a reference to the plugin id which is used by derivatives.
-        // Webform elements support derivatives but Form API elements
-        // do not support derivatives. Therefore we need to store a
-        // reference to the plugin id for when a webform element derivative
-        // changes the $elements['#type'] property.
-        // @see \Drupal\webform\Plugin\WebformElementManager::getElementPluginId
-        // @see \Drupal\webform_options_custom\Plugin\WebformElement\WebformOptionsCustom::setOptions
-        $element['#webform_plugin_id'] = $element_plugin->getPluginId();
-
-        // Initialize the element.
-        // Note: Composite sub elements are initialized via
-        // \Drupal\webform\Plugin\WebformElement\WebformCompositeBase::initialize
-        // and stored in the '#webform_composite_elements' property.
-        $element_plugin->initialize($element);
-
-        // Track flexbox.
-        if ($element['#type'] == 'flexbox' || $element['#type'] == 'webform_flexbox') {
-          $this->hasFlexboxLayout = TRUE;
-        }
-
-        // Track container.
-        if ($element_plugin->isContainer($element)) {
-          $this->hasContainer = TRUE;
-        }
-
-        // Track conditional.
-        if (!empty($element['#states'])) {
-          $this->hasConditions = TRUE;
-        }
-
-        // Track required.
-        if (!empty($element['#required']) || (!empty($element['#states']) && (!empty($element['#states']['required']) || !empty($element['#states']['optional'])))) {
-          $this->hasRequired = TRUE;
-        }
-
-        // Track prepopulated.
-        if (!empty($element['#prepopulate']) && $element_plugin->hasProperty('prepopulate')) {
-          $this->elementsPrepopulate[$key] = $key;
-        }
-
-        // Track actions.
-        if ($element_plugin instanceof WebformActions) {
-          $this->elementsActions[$key] = $key;
-        }
-
-        // Track wizard.
-        if ($element_plugin instanceof WebformWizardPage) {
-          $this->elementsWizardPages[$key] = $key;
-        }
-
-        // Track managed files.
-        if ($element_plugin->hasManagedFiles($element)) {
-          $this->elementsManagedFiles[$key] = $key;
-        }
-
-        // Track attachments.
-        if ($element_plugin instanceof WebformElementAttachmentInterface) {
-          $this->elementsAttachments[$key] = $key;
-        }
-
-        // Track computed.
-        if ($element_plugin instanceof WebformElementComputedInterface) {
-          $this->elementsComputed[$key] = $key;
-        }
-
-        // Track variant.
-        if ($element_plugin instanceof WebformElementVariantInterface) {
-          $this->elementsVariant[$key] = $key;
-        }
-
-        // Track assets (CSS and JavaScript).
-        // @see \Drupal\webform_options_custom\Plugin\WebformElement\WebformOptionsCustom
-        if ($element_plugin instanceof WebformElementAssetInterface) {
-          $asset_id = $element_plugin->getAssetId();
-          if (!isset($this->elementsCss[$asset_id])) {
-            if ($css = $element_plugin->getCss()) {
-              $this->elementsCss[$asset_id] = $css;
-            }
-          }
-          if (!isset($this->elementsJavaScript[$asset_id])) {
-            if ($javascript = $element_plugin->getJavaScript()) {
-              $this->elementsJavaScript[$asset_id] = $javascript;
-            }
-          }
-        }
-
-        // Track default data.
-        if (isset($element['#value'])) {
-          $this->elementsDefaultData[$key] = $element['#value'];
-        }
-        elseif (isset($element['#default_value'])) {
-          $this->elementsDefaultData[$key] = $element['#default_value'];
-        }
-
-        $element['#webform_multiple'] = $element_plugin->hasMultipleValues($element);
-        $element['#webform_composite'] = $element_plugin->isComposite();
-      }
-
-      // Copy only the element properties to initialized and flattened elements.
-      $this->elementsInitializedAndFlattened[$key] = WebformElementHelper::getProperties($element);
-
-      // Check if element has value (aka can be exported) and add it to
-      // flattened has value array.
-      if ($element_plugin && $element_plugin->isInput($element)) {
-        $this->elementsInitializedFlattenedAndHasValue[$key] = &$this->elementsInitializedAndFlattened[$key];
-      }
-
-      $this->initElementsRecursive($element, $key, $depth + 1);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElement($key, $include_children = FALSE) {
-    $elements_flattened = $this->getElementsInitializedAndFlattened();
-    $element = (isset($elements_flattened[$key])) ? $elements_flattened[$key] : NULL;
-    if ($element && $include_children) {
-      $elements = $this->getElementsInitialized();
-      return NestedArray::getValue($elements, $element['#webform_parents']);
-    }
-    else {
-      return $element;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementDecoded($key) {
-    $elements = $this->getElementsDecodedAndFlattened();
-    return (isset($elements[$key])) ? $elements[$key] : NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementInitialized($key) {
-    $elements = $this->getElementsInitializedAndFlattened();
-    return (isset($elements[$key])) ? $elements[$key] : NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setElementProperties($key, array $properties, $parent_key = '') {
-    $elements = $this->getElementsDecoded();
-    // If element is was not added to elements, add it as the last element.
-    if (!$this->setElementPropertiesRecursive($elements, $key, $properties, $parent_key)) {
-      if ($this->hasActions() && array_key_exists(end($this->elementsActions), $elements)) {
-        // Add element before the last 'webform_actions' element if action is
-        // not placed into container.
-        $last_action_key = end($this->elementsActions);
-        $updated_elements = [];
-        foreach ($elements as $element_key => $element) {
-          if ($element_key == $last_action_key) {
-            $updated_elements[$key] = $properties;
-          }
-          $updated_elements[$element_key] = $element;
-        }
-        $elements = $updated_elements;
-      }
-      else {
-        $elements[$key] = $properties;
-      }
-    }
-    $this->setElements($elements);
-    return $this;
-  }
-
-  /**
-   * Set element properties.
-   *
-   * @param array $elements
-   *   An associative nested array of elements.
-   * @param string $key
-   *   The element's key.
-   * @param array $properties
-   *   An associative array of properties.
-   * @param string $parent_key
-   *   (optional) The element's parent key. Only used for new elements.
-   *
-   * @return bool
-   *   TRUE when the element's properties has been set. FALSE when the element
-   *   has not been found.
-   */
-  protected function setElementPropertiesRecursive(array &$elements, $key, array $properties, $parent_key = '') {
-    foreach ($elements as $element_key => &$element) {
-      if (!WebformElementHelper::isElement($element, $element_key)) {
-        continue;
-      }
-
-      if ($element_key == $key) {
-        $element = $properties + WebformElementHelper::removeProperties($element);
-        return TRUE;
-      }
-
-      if ($element_key == $parent_key) {
-        $element[$key] = $properties;
-        return TRUE;
-      }
-
-      if ($this->setElementPropertiesRecursive($element, $key, $properties, $parent_key)) {
-        return TRUE;
-      }
-    }
-
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function deleteElement($key) {
-    $element = $this->getElementDecoded($key);
-
-    // Delete element from the elements render array.
-    $elements = $this->getElementsDecoded();
-    $sub_element_keys = $this->deleteElementRecursive($elements, $key);
-    $this->setElements($elements);
-
-    // Delete the variants.
-    $is_variant = (isset($element['#type']) && $element['#type'] === 'webform_variant');
-    if ($is_variant) {
-      $variants = $this->getVariants(NULL, NULL, $key);
-      foreach ($variants as $variant) {
-        $this->deleteWebformVariant($variant);
-      }
-    }
-
-    // Delete submission element key data.
-    \Drupal::database()->delete('webform_submission_data')
-      ->condition('webform_id', $this->id())
-      ->condition('name', $sub_element_keys, 'IN')
-      ->execute();
-  }
-
-  /**
-   * Remove an element by key from a render array.
-   *
-   * @param array $elements
-   *   An associative nested array of elements.
-   * @param string $key
-   *   The element's key.
-   *
-   * @return bool|array
-   *   An array containing the deleted element and sub element keys.
-   *   FALSE is no sub elements are found.
-   */
-  protected function deleteElementRecursive(array &$elements, $key) {
-    foreach ($elements as $element_key => &$element) {
-      if (!WebformElementHelper::isElement($element, $element_key)) {
-        continue;
-      }
-
-      if ($element_key == $key) {
-        $sub_element_keys = [$element_key => $element_key];
-        $this->collectSubElementKeysRecursive($sub_element_keys, $element);
-        unset($elements[$element_key]);
-        return $sub_element_keys;
-      }
-
-      if ($sub_element_keys = $this->deleteElementRecursive($element, $key)) {
-        return $sub_element_keys;
-      }
-    }
-
-    return FALSE;
-  }
-
-  /**
-   * Collect sub element keys from a render array.
-   *
-   * @param array $sub_element_keys
-   *   An array to be populated with sub element keys.
-   * @param array $elements
-   *   A render array.
-   */
-  protected function collectSubElementKeysRecursive(array &$sub_element_keys, array $elements) {
-    foreach ($elements as $key => &$element) {
-      if (!WebformElementHelper::isElement($element, $key)) {
-        continue;
-      }
-      $sub_element_keys[$key] = $key;
-      $this->collectSubElementKeysRecursive($sub_element_keys, $element);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPages($operation = 'default', WebformSubmissionInterface $webform_submission = NULL) {
-    $pages = $this->buildPages($operation);
-    if ($this->getSetting('wizard_progress_states') && $webform_submission) {
-      /** @var \Drupal\webform\WebformSubmissionConditionsValidatorInterface $constraint_validator */
-      $constraint_validator = \Drupal::service('webform_submission.conditions_validator');
-      $pages = $constraint_validator->buildPages($pages, $webform_submission);
-    }
-    return $pages;
-  }
-
-  /**
-   * Build and cache a webform's wizard pages based on the current operation.
-   *
-   * @param string $operation
-   *   The webform submission operation.
-   *   Usually 'default', 'add', 'edit', 'edit_all', 'api', or 'test'.
-   *
-   * @return array
-   *   An associative array of webform wizard pages.
-   */
-  protected function buildPages($operation = 'default') {
-    if (isset($this->pages[$operation])) {
-      return $this->pages[$operation];
-    }
-
-    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
-    $element_manager = \Drupal::service('plugin.manager.webform.element');
-
-    $wizard_properties = [
-      '#title' => '#title',
-      '#prev_button_label' => '#prev_button_label',
-      '#next_button_label' => '#next_button_label',
-      '#states' => '#states',
-    ];
-
-    $pages = [];
-
-    // Add webform wizard pages.
-    $elements = $this->getElementsInitialized();
-    if (is_array($elements) && !in_array($operation, ['edit_all', 'api'])) {
-      foreach ($elements as $key => $element) {
-        if (!isset($element['#type'])) {
-          continue;
-        }
-
-        /** @var \Drupal\webform\Plugin\WebformElementInterface $element_plugin */
-        $element_plugin = $element_manager->getElementInstance($element, $this);
-        if (!($element_plugin instanceof WebformElementWizardPageInterface)) {
-          continue;
-        }
-
-        // Check element access rules and only include pages that are visible
-        // to the current user.
-        $access_operation = (in_array($operation, ['default', 'add'])) ? 'create' : 'update';
-        if ($element_plugin->checkAccessRules($access_operation, $element)) {
-          $pages[$key] = array_intersect_key($element, $wizard_properties);
-          $pages[$key]['#access'] = TRUE;
-        }
-      }
-    }
-
-    // Add preview page.
-    $settings = $this->getSettings();
-    if ($settings['preview'] != DRUPAL_DISABLED) {
-      // If there is no start page, we must define one.
-      if (empty($pages)) {
-        $pages['webform_start'] = [
-          '#title' => $this->getSetting('wizard_start_label', TRUE),
-          '#access' => TRUE,
-        ];
-      }
-      $pages['webform_preview'] = [
-        '#title' => $this->getSetting('preview_label', TRUE),
-        '#access' => TRUE,
-      ];
-    }
-
-    // Only add complete page, if there are some pages.
-    if ($pages && $this->getSetting('wizard_confirmation')) {
-      $pages['webform_confirmation'] = [
-        '#title' => $this->getSetting('wizard_confirmation_label', TRUE),
-        '#access' => TRUE,
-      ];
-    }
-
-    $this->pages[$operation] = $pages;
-
-    return $this->pages[$operation];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPage($operation, $key) {
-    $pages = $this->getPages($operation);
-    return (isset($pages[$key])) ? $pages[$key] : NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function createDuplicate() {
-    /** @var \Drupal\webform\WebformInterface $duplicate */
-    $duplicate = parent::createDuplicate();
-
-    // Clear path aliases, which must be unique.
-    $duplicate->setSetting('page_submit_path', '');
-    $duplicate->setSetting('page_confirm_path', '');
-
-    // Update owner to current user.
-    $duplicate->setOwnerId(\Drupal::currentUser()->id());
-
-    // If template being used to create a new webform, clear description
-    // and remove the template flag.
-    // @see \Drupal\webform_templates\Controller\WebformTemplatesController::index
-    $is_template_duplicate = \Drupal::request()->get('template');
-    if ($duplicate->isTemplate() && !$is_template_duplicate) {
-      $duplicate->set('description', '');
-      $duplicate->set('template', FALSE);
-    }
-
-    // If archived, remove archive flag.
-    if ($duplicate->isArchived()) {
-      $duplicate->set('archive', FALSE);
-    }
-
-    // Set default status.
-    $duplicate->setStatus(\Drupal::config('webform.settings')->get('settings.default_status'));
-
-    // Remove enforce module dependency when a sub-module's webform is
-    // duplicated.
-    if (isset($duplicate->dependencies['enforced']['module'])) {
-      $modules = WebformReflectionHelper::getSubModules();
-      $duplicate->dependencies['enforced']['module'] = array_diff($duplicate->dependencies['enforced']['module'], $modules);
-      if (empty($duplicate->dependencies['enforced']['module'])) {
-        unset($duplicate->dependencies['enforced']['module']);
-        if (empty($duplicate->dependencies['enforced'])) {
-          unset($duplicate->dependencies['enforced']);
-        }
-      }
-    }
-
-    return $duplicate;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function preCreate(EntityStorageInterface $storage, array &$values) {
-    /** @var \Drupal\webform\WebformAccessRulesManagerInterface $access_rules_manager */
-    $access_rules_manager = \Drupal::service('webform.access_rules_manager');
-
-    $values += [
-      'status' => \Drupal::config('webform.settings')->get('settings.default_status'),
-      'uid' => \Drupal::currentUser()->id(),
-      'settings' => static::getDefaultSettings(),
-      'access' => $access_rules_manager->getDefaultAccessRules(),
-    ];
-
-    // Convert boolean status to STATUS constant.
-    if ($values['status'] === TRUE) {
-      $values['status'] = WebformInterface::STATUS_OPEN;
-    }
-    elseif ($values['status'] === FALSE) {
-      $values['status'] = WebformInterface::STATUS_CLOSED;
-    }
-    elseif ($values['status'] === NULL) {
-      $values['status'] = WebformInterface::STATUS_SCHEDULED;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function postLoad(EntityStorageInterface $storage, array &$entities) {
-    foreach ($entities as $entity) {
-      $entity->elementsOriginal = $entity->elements;
-      $entity->settingsOriginal = $entity->settings;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function preDelete(EntityStorageInterface $storage, array $entities) {
-    /** @var \Drupal\webform\WebformInterface[] $entities */
-    parent::preDelete($storage, $entities);
-
-    /** @var \Drupal\user\UserDataInterface $user_data */
-    $user_data = \Drupal::service('user.data');
-
-    // Delete all paths, states, and user data associated with this webform.
-    foreach ($entities as $entity) {
-      // Delete all paths.
-      $entity->deletePaths();
-
-      // Delete the state.
-      // @see \Drupal\webform\Entity\Webform::getState
-      \Drupal::state()->delete('webform.webform.' . $entity->id());
-
-      // Delete user data.
-      // @see \Drupal\webform\Entity\Webform::getUserData
-      $user_data->delete('webform', NULL, $entity->id());
-    }
-
-    // Delete all submission associated with this webform.
-    $submission_ids = \Drupal::entityQuery('webform_submission')
-      ->accessCheck(FALSE)
-      ->condition('webform_id', array_keys($entities), 'IN')
-      ->sort('sid')
-      ->execute();
-    $submission_storage = \Drupal::entityTypeManager()->getStorage('webform_submission');
-    $submissions = $submission_storage->loadMultiple($submission_ids);
-    $submission_storage->delete($submissions);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCacheTags() {
-    $cache_tags = parent::getCacheTags();
-    // Add webform to cache tags which are used by the WebformSubmissionForm.
-    $cache_tags[] = 'webform:' . $this->id();
-    // Add webform settings to cache tags which are used to define
-    // default settings.
-    $cache_tags[] = 'config:webform.settings';
-    return $cache_tags;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCacheContexts() {
-    $cache_contexts = parent::getCacheContexts();
-
-    // Add paths to cache contexts since webform can be placed on multiple
-    // pages.
-    $cache_contexts[] = 'url.path';
-
-    // Add all prepopulate query string parameters.
-    if ($this->getSetting('form_prepopulate')) {
-      $cache_contexts[] = 'url.query_args';
-    }
-    else {
-      // Add source entity type and id query string parameters.
-      if ($this->getSetting('form_prepopulate_source_entity')) {
-        $cache_contexts[] = 'url.query_args:entity_type';
-        $cache_contexts[] = 'url.query_args:entity_id';
-      }
-      // Add webform (secure) token query string parameter.
-      if ($this->getSetting('token_view') || $this->getSetting('token_update')) {
-        $cache_contexts[] = 'url.query_args:token';
-      }
-    }
-
-    return $cache_contexts;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCacheMaxAge() {
-    if ($this->isScheduled()) {
-      $time = time();
-      if ($this->open && strtotime($this->open) > $time) {
-        return (strtotime($this->open) - $time);
-      }
-      elseif ($this->close && strtotime($this->close) > $time) {
-        return (strtotime($this->close) - $time);
-      }
-    }
-
-    return parent::getCacheMaxAge();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preSave(EntityStorageInterface $storage) {
-    // Throw exception when saving overridden webform.
-    if ($this->isOverridden()) {
-      throw new WebformException(sprintf('The %s webform [%s] has overridden settings and/or properties and can not be saved.', $this->label(), $this->id()));
-    }
-
-    // Always unpublish templates.
-    if ($this->isTemplate()) {
-      $this->setStatus(WebformInterface::STATUS_CLOSED);
-    }
-
-    // Serialize elements array to YAML.
-    if (is_array($this->elements)) {
-      $this->elements = Yaml::encode($this->elements);
-    }
-
-    parent::preSave($storage);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function postSave(EntityStorageInterface $storage, $update = TRUE) {
-    parent::postSave($storage, $update);
-
-    // Update paths.
-    $this->updatePaths();
-
-    // Invoke handler element CRUD methods.
-    // Note: Comparing parsed YAML since the actual YAML formatting could be
-    // different.
-    $elements_original = $this->getElementsOriginalDecoded() ?: [];
-    $elements = $this->getElementsDecoded() ?: [];
-    if ($elements_original != $elements) {
-      $elements_original = WebformElementHelper::getFlattened($elements_original);
-      $elements = WebformElementHelper::getFlattened($elements);
-
-      // Handle create element.
-      $created_elements = array_diff_key($elements, $elements_original) ?: [];
-      foreach ($created_elements as $element_key => $element) {
-        $this->invokeHandlers('createElement', $element_key, $element);
-      }
-
-      // Handle delete element.
-      $deleted_elements = array_diff_key($elements_original, $elements) ?: [];
-      foreach ($deleted_elements as $element_key => $element) {
-        $this->invokeHandlers('deleteElement', $element_key, $element);
-      }
-
-      // Handle update element.
-      foreach ($elements as $element_key => $element) {
-        if (isset($elements_original[$element_key]) && $elements_original[$element_key] != $element) {
-          $this->invokeHandlers('updateElement', $element_key, $element, $elements_original[$element_key]);
-        }
-      }
-
-      // Invalidate library_info cache tag if any updated or deleted elements
-      // has assets (CSS or JavaScript).
-      // @see webform_library_info_build()
-      /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
-      $element_manager = \Drupal::service('plugin.manager.webform.element');
-      $checked_elements = $created_elements + $deleted_elements;
-      foreach ($checked_elements as $element_key => $element) {
-        $element_plugin = $element_manager->getElementInstance($element, $this);
-        if ($element_plugin instanceof WebformElementAssetInterface
-          && $element_plugin->hasAssets()) {
-          Cache::invalidateTags(['library_info']);
-          break;
-        }
-      }
-    }
-
-    // Reset elements.
-    $this->resetElements();
-    $this->elementsOriginal = $this->elements;
-
-    // Reset settings.
-    $this->settingsOriginal = $this->settings;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function updatePaths() {
-    // Path module must be enabled for URL aliases to be updated.
-    if (!\Drupal::moduleHandler()->moduleExists('path')) {
-      return;
-    }
-
-    // If 'Allow users to post submission from a dedicated URL' is disabled,
-    // delete all existing paths.
-    if (empty($this->settings['page'])) {
-      $this->deletePaths();
-      return;
-    }
-
-    $page_submit_path = trim($this->settings['page_submit_path'], '/');
-    $default_page_base_path = trim(\Drupal::config('webform.settings')->get('settings.default_page_base_path'), '/');
-
-    // Skip generating paths if submit path and base path are empty.
-    if (empty($page_submit_path) && empty($default_page_base_path)) {
-      return;
-    }
-
-    // Update webform base, confirmation, submissions and drafts paths.
-    $path_base_alias = '/' . ($page_submit_path ?: $default_page_base_path . '/' . str_replace('_', '-', $this->id()));
-    $path_suffixes = ['', '/confirmation', '/submissions', '/drafts'];
-    foreach ($path_suffixes as $path_suffix) {
-      $path_source = '/webform/' . $this->id() . $path_suffix;
-      $path_alias = $path_base_alias . $path_suffix;
-      if ($path_suffix === '/confirmation' && $this->settings['page_confirm_path']) {
-        $path_alias = '/' . trim($this->settings['page_confirm_path'], '/');
-      }
-      $this->updatePath($path_source, $path_alias, $this->langcode);
-      $this->updatePath($path_source, $path_alias, LanguageInterface::LANGCODE_NOT_SPECIFIED);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function deletePaths() {
-    // Path module must be enabled for URL aliases to be updated.
-    if (!\Drupal::moduleHandler()->moduleExists('path')) {
-      return;
-    }
-
-    /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
-    $path_alias_storage = \Drupal::service('path.alias_storage');
-
-    // Delete webform base, confirmation, submissions and drafts paths.
-    $path_suffixes = ['', '/confirmation', '/submissions', '/drafts'];
-    foreach ($path_suffixes as $path_suffix) {
-      $path_alias_storage->delete(['source' => '/webform/' . $this->id() . $path_suffix]);
-    }
-  }
-
-  /**
-   * Saves a path alias to the database.
-   *
-   * @param string $source
-   *   The internal system path.
-   * @param string $alias
-   *   The URL alias.
-   * @param string $langcode
-   *   (optional) The language code of the alias.
-   */
-  protected function updatePath($source, $alias, $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED) {
-    /** @var \Drupal\Core\Path\AliasStorageInterface $path_alias_storage */
-    $path_alias_storage = \Drupal::service('path.alias_storage');
-
-    $path = $path_alias_storage->load(['source' => $source, 'langcode' => $langcode]);
-
-    // Check if the path alias is already setup.
-    if ($path && ($path['alias'] == $alias)) {
-      return;
-    }
-
-    $pid = $path['pid'] ?? NULL;
-    $path_alias_storage->save($source, $alias, $langcode, $pid);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPluginCollections() {
-    return [
-      'handlers' => $this->getHandlers(),
-      'variants' => $this->getVariants(),
-    ];
-  }
-
-  /****************************************************************************/
-  // Handler plugins.
-  /****************************************************************************/
-
-  /**
-   * Returns the webform handler plugin manager.
-   *
-   * @return \Drupal\Component\Plugin\PluginManagerInterface
-   *   The webform handler plugin manager.
-   */
-  protected function getWebformHandlerPluginManager() {
-    return \Drupal::service('plugin.manager.webform.handler');
-  }
-
-  /**
-   * Reset cached handler settings.
-   */
-  protected function resetHandlers() {
-    $this->hasMessageHandler = NULL;
-    $this->hasAnonymousSubmissionTrackingHandler = NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasMessageHandler() {
-    if (isset($this->hasMessagehandler)) {
-      $this->hasMessagehandler;
-    }
-
-    $this->hasMessagehandler = FALSE;
-    $handlers = $this->getHandlers();
-    foreach ($handlers as $handler) {
-      if ($handler instanceof WebformHandlerMessageInterface) {
-        $this->hasMessagehandler = TRUE;
-        break;
-      }
-    }
-
-    return $this->hasMessagehandler;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasAnonymousSubmissionTrackingHandler() {
-    if (isset($this->hasAnonymousSubmissionTrackingHandler)) {
-      $this->hasAnonymousSubmissionTrackingHandler;
-    }
-
-    $this->hasAnonymousSubmissionTrackingHandler = FALSE;
-    $handlers = $this->getHandlers();
-    foreach ($handlers as $handler) {
-      if ($handler->hasAnonymousSubmissionTracking()) {
-        $this->hasAnonymousSubmissionTrackingHandler = TRUE;
-        break;
-      }
-    }
-
-    return $this->hasAnonymousSubmissionTrackingHandler;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getHandler($handler_id) {
-    return $this->getHandlers()->get($handler_id);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getHandlers($plugin_id = NULL, $status = NULL, $results = NULL, $submission = NULL) {
-    if (!$this->handlersCollection) {
-      $this->handlersCollection = new WebformHandlerPluginCollection($this->getWebformHandlerPluginManager(), $this->handlers);
-      /** @var \Drupal\webform\Plugin\WebformHandlerBase $handler */
-      foreach ($this->handlersCollection as $handler) {
-        // Initialize the handler and pass in the webform.
-        $handler->setWebform($this);
-      }
-      $this->handlersCollection->sort();
-    }
-
-    /** @var \Drupal\webform\Plugin\WebformHandlerPluginCollection $handlers */
-    $handlers = $this->handlersCollection;
-
-    // Clone the handlers if they are being filtered.
-    if (isset($plugin_id) || isset($status) || isset($results)) {
-      /** @var \Drupal\webform\Plugin\WebformHandlerPluginCollection $handlers */
-      $handlers = clone $this->handlersCollection;
-    }
-
-    // Filter the handlers by plugin id.
-    // This is used to limit track and enforce a handlers cardinality.
-    if (isset($plugin_id)) {
-      foreach ($handlers as $instance_id => $handler) {
-        if ($handler->getPluginId() != $plugin_id) {
-          $handlers->removeInstanceId($instance_id);
-        }
-      }
-    }
-
-    // Filter the handlers by status.
-    // This is used to limit track and enforce a handlers cardinality.
-    if (isset($status)) {
-      foreach ($handlers as $instance_id => $handler) {
-        if ($handler->getStatus() != $status) {
-          $handlers->removeInstanceId($instance_id);
-        }
-      }
-    }
-
-    // Filter the handlers by results.
-    // This is used to track is results are processed or ignored.
-    if (isset($results)) {
-      foreach ($handlers as $instance_id => $handler) {
-        $plugin_definition = $handler->getPluginDefinition();
-        if ($plugin_definition['results'] != $results) {
-          $handlers->removeInstanceId($instance_id);
-        }
-      }
-    }
-
-    // Filter the handlers by submission.
-    // This is used to track is submissions must be saved to the database.
-    if (isset($submission)) {
-      foreach ($handlers as $instance_id => $handler) {
-        $plugin_definition = $handler->getPluginDefinition();
-        if ($plugin_definition['submission'] != $submission) {
-          $handlers->removeInstanceId($instance_id);
-        }
-      }
-    }
-
-    return $handlers;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function addWebformHandler(WebformHandlerInterface $handler) {
-    $handler->setWebform($this);
-    $handler_id = $handler->getHandlerId();
-    $configuration = $handler->getConfiguration();
-    $this->getHandlers()->addInstanceId($handler_id, $configuration);
-    $this->save();
-    $this->resetHandlers();
-    $handler->createHandler();
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function updateWebformHandler(WebformHandlerInterface $handler) {
-    $handler->setWebform($this);
-    $handler_id = $handler->getHandlerId();
-    $configuration = $handler->getConfiguration();
-    $this->getHandlers()->setInstanceConfiguration($handler_id, $configuration);
-    $this->save();
-    $this->resetHandlers();
-    $handler->updateHandler();
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function deleteWebformHandler(WebformHandlerInterface $handler) {
-    $handler->setWebform($this);
-    $this->getHandlers()->removeInstanceId($handler->getHandlerId());
-    $handler->deleteHandler();
-    $this->save();
-    $this->resetHandlers();
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function invokeHandlers($method, &$data, &$context1 = NULL, &$context2 = NULL, &$context3 = NULL) {
-    // Get webform submission from arguments for conditions validations.
-    $webform_submission = NULL;
-    $args = func_get_args();
-    foreach ($args as $arg) {
-      if ($arg instanceof WebformSubmissionInterface) {
-        $webform_submission = $arg;
-        break;
-      }
-    }
-
-    // Get handlers.
-    $handlers = $this->getHandlers();
-
-    switch ($method) {
-      case 'overrideSettings';
-        // If webform submission and alter settings, make sure to completely
-        // reset all settings to their original values.
-        $this->resetSettings();
-        $settings = $this->getSettings();
-        foreach ($handlers as $handler) {
-          $handler->setWebformSubmission($webform_submission);
-          $this->invokeHandlerAlter($handler, $method, $args);
-          if ($this->isHandlerEnabled($handler, $webform_submission)) {
-            $handler->overrideSettings($settings, $webform_submission);
-          }
-        }
-        // If a handler has change some settings set override.
-        // Only look for altered original settings, which prevents issues where
-        // a webform saved settings and default settings are out-of-sync.
-        if (array_intersect_key($settings, $this->settingsOriginal) != $this->settingsOriginal) {
-          $this->setSettingsOverride($settings);
-        }
-        return NULL;
-
-      case 'access':
-      case 'accessElement':
-        // WebformHandler::access() and WebformHandler::accessElement()
-        // returns a AccessResult.
-        /** @var \Drupal\Core\Access\AccessResultInterface $result */
-        $result = AccessResult::neutral();
-        foreach ($handlers as $handler) {
-          $handler->setWebformSubmission($webform_submission);
-          $this->invokeHandlerAlter($handler, $method, $args);
-          if ($this->isHandlerEnabled($handler, $webform_submission)) {
-            $result = $result->orIf($handler->$method($data, $context1, $context2));
-          }
-        }
-        return $result;
-
-      default:
-        foreach ($handlers as $handler) {
-          $handler->setWebformSubmission($webform_submission);
-          $this->invokeHandlerAlter($handler, $method, $args);
-          if ($this->isHandlerEnabled($handler, $webform_submission)) {
-            $handler->$method($data, $context1, $context2);
-          }
-        }
-        return NULL;
-    }
-  }
-
-  /**
-   * Determine if a webform handler is enabled.
-   *
-   * @param \Drupal\webform\Plugin\WebformHandlerInterface $handler
-   *   A webform handler.
-   * @param \Drupal\webform\WebformSubmissionInterface|null $webform_submission
-   *   A webform submission.
-   *
-   * @return bool
-   *   TRUE if a webform handler is enabled.
-   */
-  protected function isHandlerEnabled(WebformHandlerInterface $handler, WebformSubmissionInterface $webform_submission = NULL) {
-    // Check if the handler is disabled.
-    if ($handler->isDisabled()) {
-      return FALSE;
-    }
-    // If webform submission defined, check the handlers conditions.
-    elseif ($webform_submission && !$handler->checkConditions($webform_submission)) {
-      return FALSE;
-    }
-    else {
-      return TRUE;
-    }
-  }
-
-  /**
-   * Alter a webform handler when it is invoked.
-   *
-   * @param \Drupal\webform\Plugin\WebformHandlerInterface $handler
-   *   A webform handler.
-   * @param string $method_name
-   *   The handler method to be invoked.
-   * @param array $args
-   *   Array of arguments being passed to the handler's method.
-   *
-   * @see hook_webform_handler_invoke_alter()
-   * @see hook_webform_handler_invoke_METHOD_NAME_alter()
-   */
-  protected function invokeHandlerAlter(WebformHandlerInterface $handler, $method_name, array $args) {
-    $method_name = WebformTextHelper::camelToSnake($method_name);
-    \Drupal::moduleHandler()->alter('webform_handler_invoke', $handler, $method_name, $args);
-    \Drupal::moduleHandler()->alter('webform_handler_invoke_' . $method_name, $handler, $args);
-  }
-
-  /****************************************************************************/
-  // Element plugins.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function invokeElements($method, &$data, &$context1 = NULL, &$context2 = NULL) {
-    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
-    $element_manager = \Drupal::service('plugin.manager.webform.element');
-
-    $elements = $this->getElementsInitializedAndFlattened();
-    foreach ($elements as $element) {
-      $element_manager->invokeMethod($method, $element, $data, $context1, $context2);
-    }
-  }
-
-  /****************************************************************************/
-  // Variant plugins.
-  /****************************************************************************/
-
-  /**
-   * Returns the webform variant plugin manager.
-   *
-   * @return \Drupal\Component\Plugin\PluginManagerInterface
-   *   The webform variant plugin manager.
-   */
-  protected function getWebformVariantPluginManager() {
-    return \Drupal::service('plugin.manager.webform.variant');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasVariant($variant_id) {
-    return $this->getVariants()->has($variant_id);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getVariant($variant_id) {
-    return $this->getVariants()->get($variant_id);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getVariants($plugin_id = NULL, $status = NULL, $element_key = NULL) {
-    if (!$this->variantsCollection) {
-      $this->variantsCollection = new WebformVariantPluginCollection($this->getWebformVariantPluginManager(), $this->variants);
-      /** @var \Drupal\webform\Plugin\WebformVariantBase $variant */
-      foreach ($this->variantsCollection as $variant) {
-        // Initialize the variant and pass in the webform.
-        $variant->setWebform($this);
-      }
-      $this->variantsCollection->sort();
-    }
-
-    /** @var \Drupal\webform\Plugin\WebformVariantPluginCollection $variants */
-    $variants = $this->variantsCollection;
-
-    // Clone the variants if they are being filtered.
-    if (isset($plugin_id) || isset($status) || isset($element_key)) {
-      /** @var \Drupal\webform\Plugin\WebformVariantPluginCollection $variants */
-      $variants = clone $this->variantsCollection;
-    }
-
-    // Filter the variants by plugin id.
-    // This is used to limit track and enforce a variants cardinality.
-    if (isset($plugin_id)) {
-      foreach ($variants as $instance_id => $variant) {
-        if ($variant->getPluginId() !== $plugin_id) {
-          $variants->removeInstanceId($instance_id);
-        }
-      }
-    }
-
-    // Filter the variants by status.
-    // This is used to limit track and enforce a variants cardinality.
-    if (isset($status)) {
-      foreach ($variants as $instance_id => $variant) {
-        if ($variant->getStatus() !== $status) {
-          $variants->removeInstanceId($instance_id);
-        }
-      }
-    }
-
-    // Filter the variants by element key.
-    if (isset($element_key)) {
-      foreach ($variants as $instance_id => $variant) {
-        if ($variant->getElementKey() !== $element_key) {
-          $variants->removeInstanceId($instance_id);
-        }
-      }
-    }
-
-    return $variants;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function addWebformVariant(WebformVariantInterface $variant) {
-    $variant->setWebform($this);
-    $variant_id = $variant->getVariantId();
-    $configuration = $variant->getConfiguration();
-    $this->getVariants()->addInstanceId($variant_id, $configuration);
-    $this->save();
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function updateWebformVariant(WebformVariantInterface $variant) {
-    $variant->setWebform($this);
-    $variant_id = $variant->getVariantId();
-    $configuration = $variant->getConfiguration();
-    $this->getVariants()->setInstanceConfiguration($variant_id, $configuration);
-    $this->save();
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function deleteWebformVariant(WebformVariantInterface $variant) {
-    $variant->setWebform($this);
-    $this->getVariants()->removeInstanceId($variant->getVariantId());
-    $this->save();
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function applyVariants(WebformSubmissionInterface $webform_submission = NULL, $variants = [], $force = FALSE) {
-    // Get variants from webform submission.
-    if ($webform_submission) {
-      // Make sure webform submission is associated with this webform.
-      if ($webform_submission->getWebform()->id() !== $this->id()) {
-        $t_args = [
-          '@sid' => $webform_submission->id(),
-          '@webform_id' => $this->id(),
-        ];
-        throw new \Exception($this->t('Variants can not be applied because the #@sid submission was not created using @webform_id', $t_args));
-      }
-      $variants += $this->getVariantsData($webform_submission);
-    }
-
-    // Apply variants.
-    $is_applied = FALSE;
-    $variant_element_keys = $this->getElementsVariant();
-    foreach ($variant_element_keys as $varient_element_key) {
-      if (!empty($variants[$varient_element_key])) {
-        $instance_id = $variants[$varient_element_key];
-        if ($this->applyVariant($varient_element_key, $instance_id, $force)) {
-          $is_applied = TRUE;
-        }
-      }
-    }
-    if ($is_applied) {
-      $this->setOverride();
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getVariantsData(WebformSubmissionInterface $webform_submission) {
-    $variants = [];
-    $element_keys = $this->getElementsVariant();
-    foreach ($element_keys as $element_key) {
-      $variants[$element_key] = $webform_submission->getElementData($element_key);
-    }
-    return $variants;
-  }
-
-  /**
-   * Apply webform variant.
-   *
-   * @param string $element_key
-   *   The variant element key.
-   * @param string $instance_id
-   *   The variant instance id.
-   * @param bool $force
-   *   Apply disabled variants. Defaults to FALSE.
-   *
-   * @return bool
-   *   Return TRUE is variant was applied.
-   */
-  public function applyVariant($element_key, $instance_id, $force = FALSE) {
-    $element = $this->getElement($element_key);
-    // Check that the webform has a variant instance.
-    if (!$this->getVariants()->has($instance_id)) {
-      $t_args = [
-        '@title' => $element['#title'],
-        '@key' => $element_key,
-        '@instance_id' => $instance_id,
-      ];
-      // Log warning for missing variant instances.
-      \Drupal::logger('webform')->warning("The '@instance_id' variant id is missing for the '@title (@key)' variant type. <strong>No variant settings have been applied.</strong>", $t_args);
-
-      // Display onscreen warning to users who can update the webform.
-      if (\Drupal::currentUser()->hasPermission('edit webform variants')) {
-        \Drupal::messenger()->addWarning($this->t("The '@instance_id' variant id is missing for the '@title (@key)' variant type. <strong>No variant settings have been applied.</strong>", $t_args));
-      }
-      return FALSE;
-    }
-
-    $variant_plugin_id = $element['#variant'];
-    $variant_plugin = $this->getVariant($instance_id);
-
-    // Check that the variant plugin id matches the element's variant plugin id.
-    if ($variant_plugin_id !== $variant_plugin->getPluginId()) {
-      return FALSE;
-    }
-
-    // Check that the variant plugin instance is enabled.
-    if (empty($force) && $variant_plugin->isDisabled()) {
-      return FALSE;
-    }
-
-    // Apply the variant.
-    $variant_plugin->applyVariant();
-  }
-
-  /****************************************************************************/
-  // URL.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   *
-   * Overriding so that URLs pointing to webform default to 'canonical'
-   * submission webform and not the back-end 'edit-form'.
-   */
-  public function url($rel = 'canonical', $options = []) {
-    // Do not remove this override: the default value of $rel is different.
-    return parent::url($rel, $options);
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * Overriding so that URLs pointing to webform default to 'canonical'
-   * submission webform and not the back-end 'edit-form'.
-   */
-  public function toUrl($rel = 'canonical', array $options = []) {
-    return parent::toUrl($rel, $options);
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * Overriding so that URLs pointing to webform default to 'canonical'
-   * submission webform and not the back-end 'edit-form'.
-   */
-  public function urlInfo($rel = 'canonical', array $options = []) {
-    return parent::urlInfo($rel, $options);
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * Overriding so that links to webform default to 'canonical' submission
-   * webform and not the back-end 'edit-form'.
-   */
-  public function toLink($text = NULL, $rel = 'canonical', array $options = []) {
-    return parent::toLink($text, $rel, $options);
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * Overriding so that links to webform default to 'canonical' submission
-   * webform and not the back-end 'edit-form'.
-   */
-  public function link($text = NULL, $rel = 'canonical', array $options = []) {
-    return parent::link($text, $rel, $options);
-  }
-
-  /****************************************************************************/
-  // Revisions.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isDefaultRevision() {
-    return TRUE;
-  }
-
-  /****************************************************************************/
-  // State.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getState($key, $default = NULL) {
-    $namespace = 'webform.webform.' . $this->id();
-    $values = \Drupal::state()->get($namespace, []);
-    return (isset($values[$key])) ? $values[$key] : $default;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setState($key, $value) {
-    $namespace = 'webform.webform.' . $this->id();
-    $values = \Drupal::state()->get($namespace, []);
-    $values[$key] = $value;
-    \Drupal::state()->set($namespace, $values);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function deleteState($key) {
-    $namespace = 'webform.webform.' . $this->id();
-    $values = \Drupal::state()->get($namespace, []);
-    unset($values[$key]);
-    \Drupal::state()->set($namespace, $values);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasState($key) {
-    $namespace = 'webform.webform.' . $this->id();
-    $values = \Drupal::state()->get($namespace, []);
-    return (isset($values[$key])) ? TRUE : FALSE;
-  }
-
-  /****************************************************************************/
-  // User data.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getUserData($key, $default = NULL) {
-    $account = \Drupal::currentUser();
-    /** @var \Drupal\user\UserDataInterface $user_data */
-    $user_data = \Drupal::service('user.data');
-    $values = $user_data->get('webform', $account->id(), $this->id());
-    return (isset($values[$key])) ? $values[$key] : $default;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setUserData($key, $value) {
-    $account = \Drupal::currentUser();
-    /** @var \Drupal\user\UserDataInterface $user_data */
-    $user_data = \Drupal::service('user.data');
-    $values = $user_data->get('webform', $account->id(), $this->id()) ?: [];
-    $values[$key] = $value;
-    $user_data->set('webform', $account->id(), $this->id(), $values);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function deleteUserData($key) {
-    $account = \Drupal::currentUser();
-    /** @var \Drupal\user\UserDataInterface $user_data */
-    $user_data = \Drupal::service('user.data');
-    $values = $user_data->get('webform', $account->id(), $this->id()) ?: [];
-    unset($values[$key]);
-    $user_data->set('webform', $account->id(), $this->id(), $values);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasUserData($key) {
-    $account = \Drupal::currentUser();
-    /** @var \Drupal\user\UserDataInterface $user_data */
-    $user_data = \Drupal::service('user.data');
-    $values = $user_data->get('webform', $account->id(), $this->id()) ?: [];
-    return (isset($values[$key])) ? TRUE : FALSE;
-  }
-
-  /****************************************************************************/
-  // Dependency.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function onDependencyRemoval(array $dependencies) {
-    $changed = parent::onDependencyRemoval($dependencies);
-
-    $handlers = $this->getHandlers();
-    if (!empty($handlers)) {
-      foreach ($handlers as $handler) {
-        $plugin_definition = $handler->getPluginDefinition();
-        $provider = $plugin_definition['provider'];
-        if (in_array($provider, $dependencies['module'])) {
-          $this->deleteWebformHandler($handler);
-          $changed = TRUE;
-        }
-      }
-    }
-
-    $variants = $this->getVariants();
-    if (!empty($variants)) {
-      foreach ($variants as $variant) {
-        $plugin_definition = $variant->getPluginDefinition();
-        $provider = $plugin_definition['provider'];
-        if (in_array($provider, $dependencies['module'])) {
-          $this->deleteWebformVariant($variant);
-          $changed = TRUE;
-        }
-      }
-    }
-
-    return $changed;
-  }
-
-  /****************************************************************************/
-  // Other.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) {
-    $a_label = $a->get('category') . $a->label();
-    $b_label = $b->get('category') . $b->label();
-    return strnatcasecmp($a_label, $b_label);
-  }
-
-  /**
-   * Define empty array iterator.
-   *
-   * See: Issue #2759267: Undefined method Webform::getIterator().
-   */
-  public function getIterator() {
-    return new \ArrayIterator([]);
-  }
-
-  /**
-   * Define empty to string method.
-   *
-   * See: Issue #2926903: Devel Tokens tab Broken when Webform Embedded in Node.
-   *
-   * @see https://www.drupal.org/project/webform/issues/2926903
-   */
-  public function __toString() {
-    return '';
-  }
-
-}
diff --git a/web/modules/webform/src/Entity/WebformOptions.php b/web/modules/webform/src/Entity/WebformOptions.php
index 77e42b752c..80bbe51de1 100644
--- a/web/modules/webform/src/Entity/WebformOptions.php
+++ b/web/modules/webform/src/Entity/WebformOptions.php
@@ -3,11 +3,11 @@
 namespace Drupal\webform\Entity;
 
 use Drupal\Core\Config\Entity\ConfigEntityInterface;
-use Drupal\Core\Serialization\Yaml;
 use Drupal\Core\Config\Entity\ConfigEntityBase;
 use Drupal\Core\Entity\EntityStorageInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\webform\Utility\WebformOptionsHelper;
+use Drupal\webform\Utility\WebformYaml;
 use Drupal\webform\WebformOptionsInterface;
 
 /**
@@ -133,7 +133,7 @@ public function set($property_name, $value) {
   public function getOptions() {
     if (!isset($this->optionsDecoded)) {
       try {
-        $options = Yaml::decode($this->options);
+        $options = WebformYaml::decode($this->options);
         // Since YAML supports simple values.
         $options = (is_array($options)) ? $options : [];
       }
@@ -151,7 +151,7 @@ public function getOptions() {
    * {@inheritdoc}
    */
   public function setOptions(array $options) {
-    $this->options = Yaml::encode($options);
+    $this->options = WebformYaml::encode($options);
     $this->optionsDecoded = NULL;
     return $this;
   }
diff --git a/web/modules/webform/src/Entity/WebformSubmission.php b/web/modules/webform/src/Entity/WebformSubmission.php
index 2e59b09e3f..b23c0c4204 100644
--- a/web/modules/webform/src/Entity/WebformSubmission.php
+++ b/web/modules/webform/src/Entity/WebformSubmission.php
@@ -246,6 +246,21 @@ public function label() {
     return PlainTextOutput::renderFromHtml($token_manager->replaceNoRenderContext($submission_label, $this));
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getLangcode() {
+    return $this->get('langcode')->value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setLangcode($langcode) {
+    $this->set('langcode', $langcode);
+    return $this;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -656,22 +671,22 @@ public function hasNotes() {
    */
   public function getState() {
     if (!$this->id()) {
-      return self::STATE_UNSAVED;
+      return WebformSubmissionInterface::STATE_UNSAVED;
     }
     elseif ($this->isConverting()) {
-      return self::STATE_CONVERTED;
+      return WebformSubmissionInterface::STATE_CONVERTED;
     }
     elseif ($this->isDraft()) {
-      return ($this->created->value === $this->changed->value) ? self::STATE_DRAFT_CREATED : self::STATE_DRAFT_UPDATED;
+      return ($this->created->value === $this->changed->value) ? WebformSubmissionInterface::STATE_DRAFT_CREATED : WebformSubmissionInterface::STATE_DRAFT_UPDATED;
     }
     elseif ($this->isLocked()) {
-      return self::STATE_LOCKED;
+      return WebformSubmissionInterface::STATE_LOCKED;
     }
     elseif ($this->completed->value === $this->changed->value) {
-      return self::STATE_COMPLETED;
+      return WebformSubmissionInterface::STATE_COMPLETED;
     }
     else {
-      return self::STATE_UPDATED;
+      return WebformSubmissionInterface::STATE_UPDATED;
     }
   }
 
@@ -772,7 +787,7 @@ public static function preCreate(EntityStorageInterface $storage, array &$values
       $entity_reference_manager = \Drupal::service('webform.entity_reference_manager');
 
       if ($webform_field_name = $entity_reference_manager->getFieldName($source_entity)) {
-        if ($source_entity->$webform_field_name->target_id == $webform->id() && $source_entity->$webform_field_name->default_data) {
+        if ($source_entity->$webform_field_name->target_id === $webform->id() && $source_entity->$webform_field_name->default_data) {
           $values['data'] += Yaml::decode($source_entity->$webform_field_name->default_data);
         }
       }
diff --git a/web/modules/webform/src/EntitySettings/WebformEntitySettingsAccessForm.php b/web/modules/webform/src/EntitySettings/WebformEntitySettingsAccessForm.php
index 43481afb50..c7f8222ed4 100644
--- a/web/modules/webform/src/EntitySettings/WebformEntitySettingsAccessForm.php
+++ b/web/modules/webform/src/EntitySettings/WebformEntitySettingsAccessForm.php
@@ -12,7 +12,7 @@
 class WebformEntitySettingsAccessForm extends WebformEntitySettingsBaseForm {
 
   /**
-   * Webform access rules manager.
+   * The webform access rules manager.
    *
    * @var \Drupal\webform\WebformAccessRulesManagerInterface
    */
diff --git a/web/modules/webform/src/EntitySettings/WebformEntitySettingsBaseForm.php b/web/modules/webform/src/EntitySettings/WebformEntitySettingsBaseForm.php
index fc132c42d9..dee92df201 100644
--- a/web/modules/webform/src/EntitySettings/WebformEntitySettingsBaseForm.php
+++ b/web/modules/webform/src/EntitySettings/WebformEntitySettingsBaseForm.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Entity\EntityForm;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Form\OptGroup;
 use Drupal\webform\Utility\WebformDialogHelper;
 use Drupal\webform\Utility\WebformElementHelper;
 
@@ -29,7 +30,7 @@ public function form(array $form, FormStateInterface $form_state) {
   protected function actions(array $form, FormStateInterface $form_state) {
     $actions = parent::actions($form, $form_state);
     // Only display delete button on Settings > General tab/form.
-    if ($this->operation != 'settings') {
+    if ($this->operation !== 'settings') {
       unset($actions['delete']);
     }
 
@@ -82,6 +83,12 @@ protected function setElementDescriptionsRecursive(array &$form, array $default_
         // Append default value to an element's description.
         $value = $default_settings["default_$key"];
         if (!is_array($value)) {
+          if (isset($element['#options'])) {
+            $flattened_options = OptGroup::flattenOptions($element['#options']);
+            if (isset($flattened_options[$value])) {
+              $value = $flattened_options[$value];
+            }
+          }
           $element['#description'] .= ($element['#description'] ? '<br /><br />' : '');
           $element['#description'] .= $this->t('Defaults to: %value', ['%value' => $value]);
         }
diff --git a/web/modules/webform/src/EntitySettings/WebformEntitySettingsFormForm.php b/web/modules/webform/src/EntitySettings/WebformEntitySettingsFormForm.php
index 8279d59fde..7133134825 100644
--- a/web/modules/webform/src/EntitySettings/WebformEntitySettingsFormForm.php
+++ b/web/modules/webform/src/EntitySettings/WebformEntitySettingsFormForm.php
@@ -352,10 +352,18 @@ public function form(array $form, FormStateInterface $form_state) {
     $form['wizard_settings']['wizard_progress_states'] = [
       '#type' => 'checkbox',
       '#title' => $this->t("Update wizard progress bar's pages based on conditions"),
-      '#description' => $this->t("If checked, the wizard's progress bar's pages will be hidden on shown based on each pages conditional logic."),
+      '#description' => $this->t("If checked, the wizard's progress bar's pages will be hidden or shown based on each pages conditional logic."),
       '#return_value' => TRUE,
       '#default_value' => $settings['wizard_progress_states'],
     ];
+    $form['wizard_settings']['wizard_auto_forward'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t("Auto-forward to next page when a page with a single click-able input is completed"),
+      '#description' => $this->t("If checked, the used will be moved to the next page when a single click-able input is checked (i.e. radios, rating, and image select)."),
+      '#return_value' => TRUE,
+      '#default_value' => $settings['wizard_auto_forward'],
+      '#access' => FALSE,
+    ];
     $form['wizard_settings']['wizard_confirmation'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Include confirmation page in progress'),
@@ -372,6 +380,38 @@ public function form(array $form, FormStateInterface $form_state) {
         ],
       ],
     ];
+    $form['wizard_settings']['wizard_toggle'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Display show/hide all wizard pages link'),
+      '#description' => $this->t('If checked, a hide/show all elements link will be added to this webform when there are wizard pages.'),
+      '#return_value' => TRUE,
+      '#default_value' => $settings['wizard_auto_forward'],
+      '#access' => FALSE,
+    ];
+    $form['wizard_settings']['wizard_toggle_show_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Wizard show all elements label'),
+      '#size' => 20,
+      '#default_value' => $settings['wizard_toggle_show_label'],
+      '#access' => FALSE,
+      '#states' => [
+        'visible' => [
+          ':input[name="wizard_toggle"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
+    $form['wizard_settings']['wizard_toggle_hide_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Wizard hide all elements label'),
+      '#size' => 20,
+      '#default_value' => $settings['wizard_toggle_hide_label'],
+      '#access' => FALSE,
+      '#states' => [
+        'visible' => [
+          ':input[name="wizard_toggle"]' => ['checked' => TRUE],
+        ],
+      ],
+    ];
     $form['wizard_settings']['wizard_start_label'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Wizard start label'),
@@ -402,6 +442,20 @@ public function form(array $form, FormStateInterface $form_state) {
       '#empty_option' => $this->t('- None -'),
       '#default_value' => $settings['wizard_track'],
     ];
+    $form['wizard_settings']['wizard_prev_button_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Wizard previous page button label'),
+      '#description' => $this->t('This is used for the previous page button within a wizard.'),
+      '#size' => 20,
+      '#default_value' => $settings['wizard_prev_button_label'],
+    ];
+    $form['wizard_settings']['wizard_next_button_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Wizard next page button label'),
+      '#description' => $this->t('This is used for the next page button within a wizard.'),
+      '#size' => 20,
+      '#default_value' => $settings['wizard_next_button_label'],
+    ];
 
     // Preview settings.
     $form['preview_settings'] = [
@@ -731,7 +785,7 @@ protected function getFormBehaviors() {
         'group' => $this->t('Validation'),
         'title' => $this->t('Disable client-side validation'),
         'all_description' => $this->t('Client-side validation is disabled for all forms.'),
-        'form_description' => $this->t('If checked, the <a href=":href">novalidate</a> attribute, which disables client-side validation, will be added to this form.', [':href' => 'http://www.w3schools.com/tags/att_form_novalidate.asp']),
+        'form_description' => $this->t('If checked, the <a href=":href">novalidate</a> attribute, which disables client-side validation, will be added to this form.', [':href' => 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form']),
       ],
       'form_disable_inline_errors' => [
         'group' => $this->t('Validation'),
@@ -755,7 +809,7 @@ protected function getFormBehaviors() {
       'form_disable_autocomplete' => [
         'group' => $this->t('Elements'),
         'title' => $this->t('Disable autocompletion'),
-        'form_description' => $this->t('If checked, the <a href=":href">autocomplete</a> attribute will be set to off, which disables autocompletion for all form elements.', [':href' => 'http://www.w3schools.com/tags/att_form_autocomplete.asp']),
+        'form_description' => $this->t('If checked, the <a href=":href">autocomplete</a> attribute will be set to off, which disables autocompletion for all form elements.', [':href' => 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form']),
       ],
       'form_details_toggle' => [
         'group' => $this->t('Elements'),
diff --git a/web/modules/webform/src/EntitySettings/WebformEntitySettingsGeneralForm.php b/web/modules/webform/src/EntitySettings/WebformEntitySettingsGeneralForm.php
index f1aed7a456..6922d25b2a 100644
--- a/web/modules/webform/src/EntitySettings/WebformEntitySettingsGeneralForm.php
+++ b/web/modules/webform/src/EntitySettings/WebformEntitySettingsGeneralForm.php
@@ -3,11 +3,14 @@
 namespace Drupal\webform\EntitySettings;
 
 use Drupal\Component\Serialization\Json;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Url;
 use Drupal\webform\Plugin\WebformHandlerInterface;
 use Drupal\webform\WebformMessageManagerInterface;
+use Drupal\webform\WebformThemeManagerInterface;
 use Drupal\webform\WebformThirdPartySettingsManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -30,6 +33,13 @@ class WebformEntitySettingsGeneralForm extends WebformEntitySettingsBaseForm {
    */
   protected $thirdPartySettingsManager;
 
+  /**
+   * The webform theme manager.
+   *
+   * @var \Drupal\webform\WebformThemeManagerInterface
+   */
+  protected $themeManager;
+
   /**
    * Constructs a WebformEntitySettingsGeneralForm.
    *
@@ -37,10 +47,13 @@ class WebformEntitySettingsGeneralForm extends WebformEntitySettingsBaseForm {
    *   The webform message manager.
    * @param \Drupal\webform\WebformThirdPartySettingsManagerInterface $third_party_settings_manager
    *   The webform third party settings manager.
+   * @param \Drupal\webform\WebformThemeManagerInterface $theme_manager
+   *   The webform theme manager.
    */
-  public function __construct(WebformMessageManagerInterface $message_manager, WebformThirdPartySettingsManagerInterface $third_party_settings_manager) {
+  public function __construct(WebformMessageManagerInterface $message_manager, WebformThirdPartySettingsManagerInterface $third_party_settings_manager, WebformThemeManagerInterface $theme_manager) {
     $this->messageManager = $message_manager;
     $this->thirdPartySettingsManager = $third_party_settings_manager;
+    $this->themeManager = $theme_manager;
   }
 
   /**
@@ -49,7 +62,8 @@ public function __construct(WebformMessageManagerInterface $message_manager, Web
   public static function create(ContainerInterface $container) {
     return new static(
       $container->get('webform.message_manager'),
-      $container->get('webform.third_party_settings_manager')
+      $container->get('webform.third_party_settings_manager'),
+      $container->get('webform.theme_manager')
     );
   }
 
@@ -194,7 +208,7 @@ public function form(array $form, FormStateInterface $form_state) {
       '#default_value' => $settings['page'],
     ];
     if ($this->moduleHandler->moduleExists('path') && $settings['page']) {
-      $t_args[':path_alias'] = Url::fromRoute('path.admin_overview')->toString();
+      $t_args[':path_alias'] = Url::fromRoute('entity.path_alias.collection')->toString();
       $form['page_settings']['page_message_warning'] = [
         '#type' => 'webform_message',
         '#message_type' => 'warning',
@@ -217,7 +231,7 @@ public function form(array $form, FormStateInterface $form_state) {
       ],
     ];
     if ($this->moduleHandler->moduleExists('path')) {
-      $t_args[':path_alias'] = Url::fromRoute('path.admin_overview')->toString();
+      $t_args[':path_alias'] = Url::fromRoute('entity.path_alias.collection')->toString();
       $form['page_settings']['page_submit_path'] = [
         '#type' => 'textfield',
         '#title' => $this->t('Webform URL alias'),
@@ -241,12 +255,12 @@ public function form(array $form, FormStateInterface $form_state) {
         ],
       ];
     }
-    $form['page_settings']['page_admin_theme'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Use the administration theme when displaying the webform as a page'),
-      '#description' => $this->t('If checked, when the webform is displayed as a page with a dedicated URL, it will use the administrative theme.'),
-      '#default_value' => $settings['page_admin_theme'],
-      '#return_value' => TRUE,
+    $form['page_settings']['page_theme_name'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Page theme'),
+      '#description' => $this->t('Select the theme that will be used when the webform is displayed as a page with a dedicated URL.'),
+      '#options' => $this->themeManager->getThemeNames(),
+      '#default_value' => $settings['page_theme_name'],
       '#states' => [
         'visible' => [
           ':input[name="page"]' => ['checked' => TRUE],
@@ -431,6 +445,49 @@ public function form(array $form, FormStateInterface $form_state) {
       ];
     }
 
+    // Share settings.
+    $form['share_settings'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Share settings'),
+      '#open' => TRUE,
+      '#access' => $this->moduleHandler->moduleExists('webform_share'),
+    ];
+    $share_behaviors = [
+      'share' => [
+        'title' => $this->t('Form sharing enabled'),
+        'all_description' => $this->t('Form sharing is enabled for all webforms.'),
+        'form_description' => $this->t('If checked, form sharing will be enabled for this webform.'),
+      ],
+      'share_node' => [
+        'title' => $this->t('Form sharing enabled for webform nodes'),
+        'all_description' => $this->t('Form sharing is enabled for all webforms node.'),
+        'form_description' => $this->t('If checked, form sharing will be enabled for webform nodes that use this webform.'),
+        'access' => $this->moduleHandler->moduleExists('webform_node'),
+      ],
+      'share_title' => [
+        'title' => $this->t('Display title on shared form'),
+        'form_description' => $this->t('If checked, the page title will displayed on this shared webform.'),
+      ],
+    ];
+    $form['share_settings']['behaviors'] = [];
+    $this->appendBehaviors($form['share_settings']['behaviors'], $share_behaviors, $settings, $default_settings);
+    $form['share_settings']['share_theme_name'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Shared form theme'),
+      '#description' => $this->t('Select the theme that will be used to render this shared webform.'),
+      '#options' => $this->themeManager->getThemeNames(),
+      '#default_value' => $settings['share_theme_name'],
+    ];
+    $form['share_settings']['share_page_body_attributes_container'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Page body attributes'),
+    ];
+    $form['share_settings']['share_page_body_attributes_container']['share_page_body_attributes'] = [
+      '#type' => 'webform_element_attributes',
+      '#title' => $this->t('Page body attributes'),
+      '#default_value' => $settings['share_page_body_attributes'],
+    ];
+
     // Advanced settings.
     $form['advanced_settings'] = [
       '#type' => 'details',
@@ -466,6 +523,26 @@ public function form(array $form, FormStateInterface $form_state) {
     return parent::form($form, $form_state);
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
+    $values = $form_state->getValues();
+
+    if ($this->entity instanceof EntityWithPluginCollectionInterface) {
+      // Do not manually update values represented by plugin collections.
+      $values = array_diff_key($values, $this->entity->getPluginCollections());
+    }
+
+    // Do not manually update third party settings.
+    // @see \Drupal\webform\EntitySettings\WebformEntitySettingsGeneralForm::save
+    unset($values['third_party_settings']);
+
+    foreach ($values as $key => $value) {
+      $entity->set($key, $value);
+    }
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/web/modules/webform/src/EntitySettings/WebformEntitySettingsSubmissionsForm.php b/web/modules/webform/src/EntitySettings/WebformEntitySettingsSubmissionsForm.php
index 717116671b..3d25494399 100644
--- a/web/modules/webform/src/EntitySettings/WebformEntitySettingsSubmissionsForm.php
+++ b/web/modules/webform/src/EntitySettings/WebformEntitySettingsSubmissionsForm.php
@@ -782,7 +782,7 @@ public function save(array $form, FormStateInterface $form_state) {
 
     // Set customize submission user columns.
     $values['submission_user_columns'] = array_values($values['submission_user_columns']);
-    if ($values['submission_user_columns'] == $webform_submission_storage->getUserDefaultColumnNames($webform)) {
+    if ($values['submission_user_columns'] === $webform_submission_storage->getUserDefaultColumnNames($webform)) {
       $values['submission_user_columns'] = [];
     }
 
diff --git a/web/modules/webform/src/EventSubscriber/WebformDefaultExceptionHtmlSubscriber.php b/web/modules/webform/src/EventSubscriber/WebformDefaultExceptionHtmlSubscriber.php
new file mode 100644
index 0000000000..96ed0af7f6
--- /dev/null
+++ b/web/modules/webform/src/EventSubscriber/WebformDefaultExceptionHtmlSubscriber.php
@@ -0,0 +1,325 @@
+<?php
+
+namespace Drupal\webform\EventSubscriber;
+
+use Drupal\Core\Cache\CacheableResponseInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\EventSubscriber\DefaultExceptionHtmlSubscriber;
+use Drupal\Core\Messenger\MessengerInterface;
+use Drupal\Core\Routing\RedirectDestinationInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\Url;
+use Drupal\webform\Element\WebformHtmlEditor;
+use Drupal\webform\Entity\Webform;
+use Drupal\webform\Entity\WebformSubmission;
+use Drupal\webform\WebformInterface;
+use Drupal\webform\WebformTokenManagerInterface;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpKernel\Event\ExceptionEvent;
+use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
+
+/**
+ * Event subscriber to redirect to login form when webform settings instruct to.
+ */
+class WebformDefaultExceptionHtmlSubscriber extends DefaultExceptionHtmlSubscriber {
+
+  use StringTranslationTrait;
+
+  /**
+   * The current account.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $account;
+
+  /**
+   * The configuration object factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * The webform token manager.
+   *
+   * @var \Drupal\webform\WebformTokenManagerInterface
+   */
+  protected $tokenManager;
+
+  /**
+   * The messenger.
+   *
+   * @var \Drupal\Core\Messenger\MessengerInterface
+   */
+  protected $messenger;
+
+  /**
+   * Constructs a new WebformExceptionHtmlSubscriber.
+   *
+   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
+   *   The HTTP kernel.
+   * @param \Psr\Log\LoggerInterface $logger
+   *   The logger service.
+   * @param \Drupal\Core\Routing\RedirectDestinationInterface $redirect_destination
+   *   The redirect destination service.
+   * @param \Symfony\Component\Routing\Matcher\UrlMatcherInterface $access_unaware_router
+   *   A router implementation which does not check access.
+   * @param \Drupal\Core\Session\AccountInterface $account
+   *   The current user.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The configuration object factory.
+   * @param \Drupal\Core\Render\RendererInterface $renderer
+   *   The renderer.
+   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
+   *   The messenger.
+   * @param \Drupal\webform\WebformTokenManagerInterface $token_manager
+   *   The webform token manager.
+   */
+  public function __construct(HttpKernelInterface $http_kernel, LoggerInterface $logger, RedirectDestinationInterface $redirect_destination, UrlMatcherInterface $access_unaware_router, AccountInterface $account, ConfigFactoryInterface $config_factory, RendererInterface $renderer, MessengerInterface $messenger, WebformTokenManagerInterface $token_manager) {
+    parent::__construct($http_kernel, $logger, $redirect_destination, $access_unaware_router);
+
+    $this->account = $account;
+    $this->configFactory = $config_factory;
+    $this->renderer = $renderer;
+    $this->messenger = $messenger;
+    $this->tokenManager = $token_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static function getPriority() {
+    // Execute before CustomPageExceptionHtmlSubscriber which is -50.
+    // @see \Drupal\Core\EventSubscriber\CustomPageExceptionHtmlSubscriber::getPriority
+    return -49;
+  }
+
+  /**
+   * Handles a 403 error for HTML.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
+   *   The event to process.
+   */
+  public function on403(ExceptionEvent $event) {
+    if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) {
+      return;
+    }
+
+    $this->on403RedirectEntityAccess($event);
+    $this->on403RedirectPrivateFileAccess($event);
+  }
+
+  /**
+   * Redirect to user login when access is denied to private webform file.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
+   *   The event to process.
+   *
+   * @see webform_file_download()
+   * @see \Drupal\webform\Plugin\WebformElement\WebformManagedFileBase::accessFileDownload
+   */
+  public function on403RedirectPrivateFileAccess(ExceptionEvent $event) {
+    $path = $event->getRequest()->getPathInfo();
+    // Make sure the user is trying to access a private webform file upload.
+    if (strpos($path, '/system/files/webform/') !== 0) {
+      return;
+    }
+
+    // Make private webform file upload is not a temporary file.
+    // @see \Drupal\webform\Plugin\WebformElement\WebformManagedFileBase::postSave
+    if (strpos($path, '/_sid_/') !== FALSE) {
+      return;
+    }
+
+    // Check that private file redirection is enabled.
+    if (!$this->configFactory->get('webform.settings')->get('file.file_private_redirect')) {
+      return;
+    }
+
+    $message = $this->configFactory->get('webform.settings')->get('file.file_private_redirect_message');
+    $this->redirectToLogin($event, $message);
+  }
+
+  /**
+   * Redirect to user login when access is denied for webform or submission.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
+   *   The event to process.
+   */
+  public function on403RedirectEntityAccess(ExceptionEvent $event) {
+    $url = Url::fromUserInput($event->getRequest()->getPathInfo());
+    if (!$url) {
+      return;
+    }
+
+    $route_parameters = $url->isRouted() ? $url->getRouteParameters() : [];
+    if (empty($route_parameters['webform']) && empty($route_parameters['webform_submission'])) {
+      return;
+    }
+
+    $config = $this->configFactory->get('webform.settings');
+
+    // If webform submission, handle login redirect.
+    if (!empty($route_parameters['webform_submission'])) {
+      $webform_submission = WebformSubmission::load($route_parameters['webform_submission']);
+      $webform = $webform_submission->getWebform();
+
+      $submission_access_denied_message = $webform->getSetting('submission_access_denied_message')
+        ?: $config->get('settings.default_submission_access_denied_message');
+
+      switch ($webform->getSetting('submission_access_denied')) {
+        case WebformInterface::ACCESS_DENIED_LOGIN:
+          $this->redirectToLogin($event, $submission_access_denied_message, $webform_submission);
+          break;
+
+        case WebformInterface::ACCESS_DENIED_PAGE:
+          // Must manually build access denied path so that base path is not
+          // included.
+          $this->makeSubrequest($event, '/admin/structure/webform/manage/' . $webform->id() . '/submission/' . $webform_submission->id() . '/access-denied', Response::HTTP_FORBIDDEN);
+          break;
+
+        case WebformInterface::ACCESS_DENIED_DEFAULT:
+        default:
+          // Make the default 403 request so that we can add cacheable dependencies.
+          $this->makeSubrequest($event, $this->getSystemSite403Path(), Response::HTTP_FORBIDDEN);
+          break;
+      }
+
+      // Add cacheable dependencies.
+      $response = $event->getResponse();
+      if ($response instanceof CacheableResponseInterface) {
+        $response->addCacheableDependency($webform);
+        $response->addCacheableDependency($webform_submission);
+        $response->addCacheableDependency($config);
+      }
+      return;
+    }
+
+    // If webform, handle access denied redirect or page.
+    if (!empty($route_parameters['webform'])) {
+      $webform = Webform::load($route_parameters['webform']);
+
+      $webform_access_denied_message = $webform->getSetting('form_access_denied_message')
+        ?: $config->get('settings.default_form_access_denied_message');
+
+      switch ($webform->getSetting('form_access_denied')) {
+        case WebformInterface::ACCESS_DENIED_LOGIN:
+          $this->redirectToLogin($event, $webform_access_denied_message, $webform);
+          break;
+
+        case WebformInterface::ACCESS_DENIED_PAGE:
+          // Must manually build access denied path so that base path is not
+          // included.
+          $this->makeSubrequest($event, '/webform/' . $webform->id() . '/access-denied', Response::HTTP_FORBIDDEN);
+          break;
+
+        case WebformInterface::ACCESS_DENIED_MESSAGE:
+          // Display message.
+          $this->setMessage($webform_access_denied_message, $webform);
+          // Make the default 403 request so that we can add cacheable dependencies.
+          $this->makeSubrequest($event, $this->getSystemSite403Path(), Response::HTTP_FORBIDDEN);
+          break;
+
+        case WebformInterface::ACCESS_DENIED_DEFAULT:
+        default:
+          // Make the default 403 request so that we can add cacheable dependencies.
+          $this->makeSubrequest($event, $this->getSystemSite403Path(), Response::HTTP_FORBIDDEN);
+          break;
+      }
+      // Add cacheable dependencies.
+      $response = $event->getResponse();
+      if ($response instanceof CacheableResponseInterface) {
+        $response->addCacheableDependency($webform);
+        $response->addCacheableDependency($config);
+      }
+      return;
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getHandledFormats() {
+    return ['html'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function onException(ExceptionEvent $event) {
+    // Only handle 403 exception.
+    // @see \Drupal\webform\EventSubscriber\WebformExceptionHtmlSubscriber::on403
+    $exception = $event->getException();
+    if ($exception instanceof HttpExceptionInterface && $exception->getStatusCode() === 403) {
+      parent::onException($event);
+    }
+  }
+
+  /**
+   * Get 403 path from system.site config.
+   *
+   * @return string
+   *   The custom 403 path or Drupal's default 403 path.
+   */
+  protected function getSystemSite403Path() {
+    return $this->configFactory->get('system.site')->get('page.403') ?: '/system/403';
+  }
+
+  /**
+   * Redirect to user login with destination and display custom message.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\ExceptionEvent $event
+   *   The event to process.
+   * @param null|string $message
+   *   (Optional) Message to be display on user login.
+   * @param null|\Drupal\Core\Entity\EntityInterface $entity
+   *   (Optional) Entity to be used when replacing tokens.
+   */
+  protected function redirectToLogin(ExceptionEvent $event, $message = NULL, EntityInterface $entity = NULL) {
+    // Display message.
+    if ($message) {
+      $this->setMessage($message, $entity);
+    }
+
+    // Only redirect anonymous users.
+    if ($this->account->isAuthenticated()) {
+      return;
+    }
+
+    $redirect_url = Url::fromRoute(
+      'user.login',
+      [],
+      ['absolute' => TRUE, 'query' => $this->redirectDestination->getAsArray()]
+    );
+    $event->setResponse(new RedirectResponse($redirect_url->toString()));
+  }
+
+  /**
+   * Display custom message.
+   *
+   * @param null|string $message
+   *   (Optional) Message to be display on user login.
+   * @param null|\Drupal\Core\Entity\EntityInterface $entity
+   *   (Optional) Entity to be used when replacing tokens.
+   */
+  protected function setMessage($message, EntityInterface $entity = NULL) {
+    $message = $this->tokenManager->replace($message, $entity);
+    $build = WebformHtmlEditor::checkMarkup($message);
+    $this->messenger->addStatus($this->renderer->renderPlain($build));
+  }
+
+}
diff --git a/web/modules/webform/src/EventSubscriber/WebformExceptionHtmlSubscriber.php b/web/modules/webform/src/EventSubscriber/WebformExceptionHtmlSubscriber.php
index 71dfb8f532..fd85cbfcbf 100644
--- a/web/modules/webform/src/EventSubscriber/WebformExceptionHtmlSubscriber.php
+++ b/web/modules/webform/src/EventSubscriber/WebformExceptionHtmlSubscriber.php
@@ -115,7 +115,7 @@ protected static function getPriority() {
    *   The event to process.
    */
   public function on403(GetResponseForExceptionEvent $event) {
-    if ($event->getRequestType() != HttpKernelInterface::MASTER_REQUEST) {
+    if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) {
       return;
     }
 
diff --git a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigAdvancedForm.php b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigAdvancedForm.php
index 6aebc28513..2317863553 100644
--- a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigAdvancedForm.php
+++ b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigAdvancedForm.php
@@ -121,8 +121,8 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#type' => 'checkbox',
       '#title' => $this->t('Save details open/close state'),
       '#description' => $this->t('If checked, all <a href=":details_href">Details</a> element\'s open/close state will be saved using <a href=":local_storage_href">Local Storage</a>.', [
-        ':details_href' => 'http://www.w3schools.com/tags/tag_details.asp',
-        ':local_storage_href' => 'http://www.w3schools.com/html/html5_webstorage.asp',
+        ':details_href' => 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details',
+        ':local_storage_href' => 'https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API',
       ]),
       '#return_value' => TRUE,
       '#default_value' => $config->get('ui.details_save'),
@@ -362,7 +362,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
 
       // Track if help is disabled.
       // @todo Figure out how to clear cached help block.
-      $is_help_disabled = ($config->getOriginal('ui.help_disabled') != $config->get('ui.help_disabled'));
+      $is_help_disabled = ($config->getOriginal('ui.help_disabled') !== $config->get('ui.help_disabled'));
 
       parent::submitForm($form, $form_state);
 
diff --git a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigElementsForm.php b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigElementsForm.php
index ade6c9b35e..4b23810e7a 100644
--- a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigElementsForm.php
+++ b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigElementsForm.php
@@ -44,7 +44,7 @@ class WebformAdminConfigElementsForm extends WebformAdminConfigBaseForm {
   protected $elementManager;
 
   /**
-   * The libraries manager.
+   * The webform libraries manager.
    *
    * @var \Drupal\webform\WebformLibrariesManagerInterface
    */
@@ -431,7 +431,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       $form['file']["default_{$file_type_name}_extensions"] = [
         '#type' => 'textfield',
         '#title' => $this->t('Default allowed @title extensions', ['@title' => $file_type_title]),
-        '#description' => $this->t('Separate extensions with a space and do not include the leading dot.'),
+        '#description' => $this->t('Separate extensions with a space or comma and do not include the leading dot.'),
         '#element_validate' => [[get_class($this), 'validateExtensions']],
         '#required' => TRUE,
         '#maxlength' => 256,
diff --git a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigExportersForm.php b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigExportersForm.php
index ac8c62679c..7026879119 100644
--- a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigExportersForm.php
+++ b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigExportersForm.php
@@ -90,7 +90,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#title' => $this->t('Temporary directory'),
       '#description' => $this->t('A local file system path where temporary export files will be stored. This directory should be persistent between requests and should not be accessible over the web.'),
       '#required' => TRUE,
-      '#default_value' => $config->get('export.temp_directory') ?: file_directory_temp(),
+      '#default_value' => $config->get('export.temp_directory') ?: $this->fileSystem->getTempDirectory(),
     ];
 
     // Export.
@@ -146,7 +146,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     $export = $this->submissionExporter->getValuesFromInput($values) + ['excluded_exporters' => $excluded_exporters];
 
     // Set custom temp directory.
-    $export['temp_directory'] = ($values['temp_directory'] === file_directory_temp()) ? '' : $values['temp_directory'];
+    $export['temp_directory'] = ($values['temp_directory'] === $this->fileSystem->getTempDirectory()) ? '' : $values['temp_directory'];
 
     // Update config and submit form.
     $config = $this->config('webform.settings');
diff --git a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigFormsForm.php b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigFormsForm.php
index 7dcd7c960d..a9d8259647 100644
--- a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigFormsForm.php
+++ b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigFormsForm.php
@@ -14,6 +14,7 @@
 use Drupal\webform\Utility\WebformArrayHelper;
 use Drupal\webform\WebformAddonsManagerInterface;
 use Drupal\webform\WebformInterface;
+use Drupal\webform\WebformThemeManagerInterface;
 use Drupal\webform\WebformTokenManagerInterface;
 use Drupal\webform\WebformThirdPartySettingsManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -58,6 +59,13 @@ class WebformAdminConfigFormsForm extends WebformAdminConfigBaseForm {
    */
   protected $addonsManager;
 
+  /**
+   * The webform theme manager.
+   *
+   * @var \Drupal\webform\WebformThemeManagerInterface
+   */
+  protected $themeManager;
+
   /**
    * {@inheritdoc}
    */
@@ -80,14 +88,17 @@ public function getFormId() {
    *   The webform third party settings manager.
    * @param \Drupal\webform\WebformAddonsManagerInterface $addons_manager
    *   The webform add-ons manager.
+   * @param \Drupal\webform\WebformThemeManagerInterface $theme_manager
+   *   The webform theme manager.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, WebformTokenManagerInterface $token_manager, WebformThirdPartySettingsManagerInterface $third_party_settings_manager, WebformAddonsManagerInterface $addons_manager) {
+  public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager, WebformTokenManagerInterface $token_manager, WebformThirdPartySettingsManagerInterface $third_party_settings_manager, WebformAddonsManagerInterface $addons_manager, WebformThemeManagerInterface $theme_manager) {
     parent::__construct($config_factory);
     $this->webformStorage = $entity_type_manager->getStorage('webform');
     $this->moduleHandler = $module_handler;
     $this->tokenManager = $token_manager;
     $this->thirdPartySettingsManager = $third_party_settings_manager;
     $this->addonsManager = $addons_manager;
+    $this->themeManager = $theme_manager;
   }
 
   /**
@@ -100,7 +111,8 @@ public static function create(ContainerInterface $container) {
       $container->get('entity_type.manager'),
       $container->get('webform.token_manager'),
       $container->get('webform.third_party_settings_manager'),
-      $container->get('webform.addons_manager')
+      $container->get('webform.addons_manager'),
+      $container->get('webform.theme_manager')
     );
   }
 
@@ -283,7 +295,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       'default_form_novalidate' => [
         'group' => $this->t('Validation'),
         'title' => $this->t('Disable client-side validation for all webforms'),
-        'description' => $this->t('If checked, the <a href=":href">novalidate</a> attribute, which disables client-side validation, will be added to all webforms.', [':href' => 'http://www.w3schools.com/tags/att_form_novalidate.asp']),
+        'description' => $this->t('If checked, the <a href=":href">novalidate</a> attribute, which disables client-side validation, will be added to all webforms.', [':href' => 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form']),
       ],
       'default_form_disable_inline_errors' => [
         'group' => $this->t('Validation'),
@@ -363,6 +375,20 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#size' => 20,
       '#default_value' => $settings['default_wizard_confirmation_label'],
     ];
+    $form['wizard_settings']['default_wizard_toggle_show_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Default wizard show all elements label'),
+      '#required' => TRUE,
+      '#size' => 20,
+      '#default_value' => $settings['default_wizard_toggle_show_label'],
+    ];
+    $form['wizard_settings']['default_wizard_toggle_hide_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Default wizard hide all elements label'),
+      '#required' => TRUE,
+      '#size' => 20,
+      '#default_value' => $settings['default_wizard_toggle_hide_label'],
+    ];
 
     // Preview settings.
     $form['preview_settings'] = [
@@ -500,6 +526,37 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#default_value' => $settings['default_ajax_speed'],
     ];
 
+    // Share settings.
+    $form['share_settings'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Form share settings'),
+      '#open' => TRUE,
+      '#tree' => TRUE,
+      '#access' => $this->moduleHandler->moduleExists('webform_share'),
+    ];
+    $form['share_settings']['default_share'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Enable form sharing'),
+      '#description' => $this->t('If checking, form sharing will be enabled for all webforms.'),
+      '#return_value' => TRUE,
+      '#default_value' => $settings['default_share'],
+    ];
+    $form['share_settings']['default_share_node'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Enable form sharing for webform nodes'),
+      '#description' => $this->t('If checking, form sharing will be enabled for all webform nodes.'),
+      '#return_value' => TRUE,
+      '#default_value' => $settings['default_share_node'],
+      '#access' => $this->moduleHandler->moduleExists('webform_node'),
+    ];
+    $form['share_settings']['default_share_theme_name'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Default shared form theme'),
+      '#description' => $this->t('Select the theme that will be used to render all shared webforms.'),
+      '#options' => $this->themeManager->getThemeNames(),
+      '#default_value' => $settings['default_share_theme_name'],
+    ];
+
     // Dialog settings.
     $form['dialog_settings'] = [
       '#type' => 'details',
@@ -666,12 +723,13 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       + $form_state->getValue('wizard_settings')
       + $form_state->getValue('preview_settings')
       + $form_state->getValue('confirmation_settings')
+      + $form_state->getValue('share_settings')
       + $form_state->getValue('ajax_settings')
       + $form_state->getValue('dialog_settings');
 
     // Track if we need to trigger an update of all webform paths
     // because the 'default_page_base_path' changed.
-    $update_paths = ($settings['default_page_base_path'] != $this->config('webform.settings')->get('settings.default_page_base_path')) ? TRUE : FALSE;
+    $update_paths = ($settings['default_page_base_path'] !== $this->config('webform.settings')->get('settings.default_page_base_path')) ? TRUE : FALSE;
 
     // Filter empty dialog options.
     foreach ($settings['dialog_options'] as $dialog_name => $dialog_options) {
diff --git a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigLibrariesForm.php b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigLibrariesForm.php
index e2b6a6b629..e3deee4496 100644
--- a/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigLibrariesForm.php
+++ b/web/modules/webform/src/Form/AdminConfig/WebformAdminConfigLibrariesForm.php
@@ -16,7 +16,7 @@
 class WebformAdminConfigLibrariesForm extends WebformAdminConfigBaseForm {
 
   /**
-   * The libraries manager.
+   * The webform libraries manager.
    *
    * @var \Drupal\webform\WebformLibrariesManagerInterface
    */
diff --git a/web/modules/webform/src/Form/WebformConfigEntityDeleteFormBase.php b/web/modules/webform/src/Form/WebformConfigEntityDeleteFormBase.php
index 6393b38a6a..94cf005c91 100644
--- a/web/modules/webform/src/Form/WebformConfigEntityDeleteFormBase.php
+++ b/web/modules/webform/src/Form/WebformConfigEntityDeleteFormBase.php
@@ -37,14 +37,14 @@ public function getBaseFormId() {
   public function getQuestion() {
     if ($this->isDialog()) {
       $t_args = [
-        '@entity-type' => $this->getEntity()->getEntityType()->getLowercaseLabel(),
+        '@entity-type' => $this->getEntity()->getEntityType()->getSingularLabel(),
         '@label' => $this->getEntity()->label(),
       ];
       return $this->t("Delete '@label' @entity-type?", $t_args);
     }
     else {
       $t_args = [
-        '@entity-type' => $this->getEntity()->getEntityType()->getLowercaseLabel(),
+        '@entity-type' => $this->getEntity()->getEntityType()->getSingularLabel(),
         '%label' => $this->getEntity()->label(),
       ];
       return $this->t('Delete %label @entity-type?', $t_args);
@@ -56,7 +56,7 @@ public function getQuestion() {
    */
   public function getWarning() {
     $t_args = [
-      '@entity-type' => $this->getEntity()->getEntityType()->getLowercaseLabel(),
+      '@entity-type' => $this->getEntity()->getEntityType()->getSingularLabel(),
       '%label' => $this->getEntity()->label(),
     ];
 
@@ -87,7 +87,7 @@ public function getDetails() {
    */
   public function getConfirmInput() {
     $t_args = [
-      '@entity-type' => $this->getEntity()->getEntityType()->getLowercaseLabel(),
+      '@entity-type' => $this->getEntity()->getEntityType()->getSingularLabel(),
       '%label' => $this->getEntity()->label(),
     ];
 
diff --git a/web/modules/webform/src/Form/WebformHandlerFormBase.php b/web/modules/webform/src/Form/WebformHandlerFormBase.php
index 8641d013d9..b430bbe42f 100644
--- a/web/modules/webform/src/Form/WebformHandlerFormBase.php
+++ b/web/modules/webform/src/Form/WebformHandlerFormBase.php
@@ -201,7 +201,7 @@ public function buildForm(array $form, FormStateInterface $form_state, WebformIn
       '#return_value' => TRUE,
       '#default_value' => $this->webformHandler->isEnabled(),
       // Disable broken plugins.
-      '#disabled' => ($this->webformHandler->getPluginId() == 'broken'),
+      '#disabled' => ($this->webformHandler->getPluginId() === 'broken'),
     ];
 
     $form['#parents'] = [];
diff --git a/web/modules/webform/src/Form/WebformResultsCustomForm.php b/web/modules/webform/src/Form/WebformResultsCustomForm.php
index dda67c17ea..3b3810eafd 100644
--- a/web/modules/webform/src/Form/WebformResultsCustomForm.php
+++ b/web/modules/webform/src/Form/WebformResultsCustomForm.php
@@ -84,7 +84,7 @@ public function getFormId() {
   protected $submissionStorage;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
@@ -511,7 +511,7 @@ protected function getDataMethod($method) {
   /**
    * Get the full key for the custom data.
    *
-   * @param $name
+   * @param string $name
    *   The name for the custom data.
    *
    * @return string
diff --git a/web/modules/webform/src/Form/WebformSubmissionDeleteForm.php b/web/modules/webform/src/Form/WebformSubmissionDeleteForm.php
index 86d120829c..53b671536e 100644
--- a/web/modules/webform/src/Form/WebformSubmissionDeleteForm.php
+++ b/web/modules/webform/src/Form/WebformSubmissionDeleteForm.php
@@ -37,7 +37,7 @@ class WebformSubmissionDeleteForm extends ContentEntityDeleteForm implements Web
   protected $sourceEntity;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
@@ -118,7 +118,7 @@ public function getQuestion() {
    */
   public function getWarning() {
     $t_args = [
-      '@entity-type' => $this->getEntity()->getEntityType()->getLowercaseLabel(),
+      '@entity-type' => $this->getEntity()->getEntityType()->getSingularLabel(),
       '%label' => $this->getEntity()->label(),
     ];
 
diff --git a/web/modules/webform/src/Form/WebformSubmissionResendForm.php b/web/modules/webform/src/Form/WebformSubmissionResendForm.php
index 45007f6f83..582423ca67 100644
--- a/web/modules/webform/src/Form/WebformSubmissionResendForm.php
+++ b/web/modules/webform/src/Form/WebformSubmissionResendForm.php
@@ -40,7 +40,7 @@ public function getFormId() {
   }
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/src/Form/WebformSubmissionsDeleteFormBase.php b/web/modules/webform/src/Form/WebformSubmissionsDeleteFormBase.php
index f27dd448f6..b12f40ed55 100644
--- a/web/modules/webform/src/Form/WebformSubmissionsDeleteFormBase.php
+++ b/web/modules/webform/src/Form/WebformSubmissionsDeleteFormBase.php
@@ -57,7 +57,7 @@ abstract class WebformSubmissionsDeleteFormBase extends WebformDeleteFormBase {
   protected $submissionStorage;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
@@ -213,7 +213,7 @@ public function batchProcess(WebformInterface $webform = NULL, EntityInterface $
     $context['message'] = $this->t('Deleting @count of @total submissions…', ['@count' => $context['sandbox']['progress'], '@total' => $context['sandbox']['max']]);
 
     // Track finished.
-    if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
+    if ($context['sandbox']['progress'] !== $context['sandbox']['max']) {
       $context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
     }
   }
diff --git a/web/modules/webform/src/Form/WebformVariantFormBase.php b/web/modules/webform/src/Form/WebformVariantFormBase.php
index c4ddbd8eac..ae8ea6bdbd 100644
--- a/web/modules/webform/src/Form/WebformVariantFormBase.php
+++ b/web/modules/webform/src/Form/WebformVariantFormBase.php
@@ -21,7 +21,7 @@ abstract class WebformVariantFormBase extends FormBase {
   use WebformDialogFormTrait;
 
   /**
-   * Machine name maxlenght.
+   * Machine name maxlength.
    */
   const MACHINE_NAME_MAXLENGHTH = 64;
 
@@ -189,7 +189,7 @@ public function buildForm(array $form, FormStateInterface $form_state, WebformIn
       '#return_value' => TRUE,
       '#default_value' => $this->webformVariant->isEnabled(),
       // Disable broken plugins.
-      '#disabled' => ($this->webformVariant->getPluginId() == 'broken'),
+      '#disabled' => ($this->webformVariant->getPluginId() === 'broken'),
     ];
 
     $form['#parents'] = [];
diff --git a/web/modules/webform/src/Form/WebformVariantViewForm.php b/web/modules/webform/src/Form/WebformVariantViewForm.php
index cd5ed3b1ef..8b6ba7f0c1 100644
--- a/web/modules/webform/src/Form/WebformVariantViewForm.php
+++ b/web/modules/webform/src/Form/WebformVariantViewForm.php
@@ -6,6 +6,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\webform\Utility\WebformElementHelper;
 use Drupal\webform\WebformInterface;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
 /**
  * Provides a view and tests form for webform variants.
@@ -52,9 +53,29 @@ public function buildForm(array $form, FormStateInterface $form_state, WebformIn
     $this->operation = $operation;
     $this->webform = $webform;
 
-    $t_args = [
-      '@operation' => ($operation === 'view') ? $this->t('view') : $this->t('test'),
-    ];
+    switch ($operation) {
+      case 'view':
+        $form['#rel'] = 'canonical';
+        $submit_label = $this->t('View');
+        $t_args = ['@operation' => $this->t('view')];
+        break;
+
+      case 'test':
+        $form['#rel'] = 'test-form';
+        $submit_label = $this->t('Test');
+        $t_args = ['@operation' => $this->t('test')];
+        break;
+
+      case 'share':
+        $form['#rel'] = 'share-embed';
+        $submit_label = $this->t('Share');
+        $t_args = ['@operation' => $this->t('share')];
+        break;
+
+      default:
+        throw new NotFoundHttpException();
+    }
+
     $form['description'] = [
       '#type' => 'container',
       'text' => [
@@ -93,7 +114,7 @@ public function buildForm(array $form, FormStateInterface $form_state, WebformIn
     $form['actions'] = ['#type' => 'actions'];
     $form['actions']['submit'] = [
       '#type' => 'submit',
-      '#value' => ($operation === 'view') ? $this->t('View') : $this->t('Test'),
+      '#value' => $submit_label,
       '#button_type' => 'primary',
     ];
     return $form;
@@ -130,7 +151,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     }
     $options = ['query' => $query];
 
-    $rel = ($this->operation === 'view') ? 'canonical' : 'test-form';
+    $rel = $form['#rel'];
     $redirect_url = $this->webform->toUrl($rel, $options);
     $form_state->setRedirectUrl($redirect_url);
   }
diff --git a/web/modules/webform/src/Plugin/Block/WebformSubmissionLimitBlock.php b/web/modules/webform/src/Plugin/Block/WebformSubmissionLimitBlock.php
index 14cd55183d..f82ad70dd9 100644
--- a/web/modules/webform/src/Plugin/Block/WebformSubmissionLimitBlock.php
+++ b/web/modules/webform/src/Plugin/Block/WebformSubmissionLimitBlock.php
@@ -55,7 +55,7 @@ class WebformSubmissionLimitBlock extends BlockBase implements ContainerFactoryP
   protected $entityTypeManager;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
@@ -143,7 +143,7 @@ public function blockForm($form, FormStateInterface $form_state) {
         'webform' => $this->t('Current webform'),
         'user' => $this->t('Current user'),
       ],
-      '#ajax' => self::getTokenAjaxSettings(),
+      '#ajax' => static::getTokenAjaxSettings(),
       '#default_value' => $this->configuration['type'],
       '#parents' => ['settings', 'type'],
     ];
@@ -151,7 +151,7 @@ public function blockForm($form, FormStateInterface $form_state) {
       '#title' => $this->t('Restrict limit and total submissions to current or specified source entity'),
       '#type' => 'checkbox',
       '#return_value' => TRUE,
-      '#ajax' => self::getTokenAjaxSettings(),
+      '#ajax' => static::getTokenAjaxSettings(),
       '#default_value' => $this->configuration['source_entity'],
       '#parents' => ['settings', 'source_entity'],
     ];
@@ -164,7 +164,7 @@ public function blockForm($form, FormStateInterface $form_state) {
     ];
 
     // Tokens.
-    $form['tokens'] = self::buildTokens($this->configuration['type'], $this->configuration['source_entity']);
+    $form['tokens'] = static::buildTokens($this->configuration['type'], $this->configuration['source_entity']);
 
     // Progress.
     $form['progress'] = [
@@ -384,7 +384,7 @@ protected function replaceTokens($text) {
    */
   protected function getLimit() {
     $name = ($this->configuration['source_entity']) ? 'entity_' : '';
-    $name .= ($this->configuration['type'] == 'user') ? 'limit_user' : 'limit_total';
+    $name .= ($this->configuration['type'] === 'user') ? 'limit_user' : 'limit_total';
     return $this->getWebform()->getSetting($name) ?: FALSE;
   }
 
@@ -396,7 +396,7 @@ protected function getLimit() {
    */
   protected function getInterval() {
     $name = ($this->configuration['source_entity']) ? 'entity_' : '';
-    $name .= ($this->configuration['type'] == 'user') ? 'limit_user_interval' : 'limit_total_interval';
+    $name .= ($this->configuration['type'] === 'user') ? 'limit_user_interval' : 'limit_total_interval';
     return $this->getWebform()->getSetting($name);
   }
 
@@ -503,7 +503,7 @@ protected function getSourceEntity() {
    *   The current user account or NULL if the user limit is not being displayed.
    */
   protected function getCurrentUser() {
-    return ($this->configuration['type'] == 'user') ? $this->currentUser : NULL;
+    return ($this->configuration['type'] === 'user') ? $this->currentUser : NULL;
   }
 
   /****************************************************************************/
@@ -529,7 +529,7 @@ public static function getTokenAjaxSettings() {
    */
   public static function tokenAjaxCallback(array &$form, FormStateInterface $form_state) {
     $settings = $form_state->getValue('settings');
-    return self::buildTokens($settings['type'], $settings['source_entity']);
+    return static::buildTokens($settings['type'], $settings['source_entity']);
   }
 
   /**
@@ -557,7 +557,7 @@ public static function buildTokens($type, $source_entity) {
     $token_types = ['limit', 'interval', 'total', 'remaining'];
     $rows = [];
     foreach ($token_types as $token_type) {
-      $token_name = self::getTokenName($token_type, $type, $source_entity);
+      $token_name = static::getTokenName($token_type, $type, $source_entity);
       $rows[] = [
         ['data' => '[' . $token_type . ']', 'style' => 'vertical-align: top'],
         [
diff --git a/web/modules/webform/src/Plugin/Condition/Webform.php b/web/modules/webform/src/Plugin/Condition/Webform.php
index 62b1514b06..0e710c2335 100644
--- a/web/modules/webform/src/Plugin/Condition/Webform.php
+++ b/web/modules/webform/src/Plugin/Condition/Webform.php
@@ -16,7 +16,7 @@
  * @Condition(
  *   id = "webform",
  *   label = @Translation("Webforms"),
- *   context = {
+ *   context_definitions = {
  *     "webform" = @ContextDefinition("entity:webform", label = @Translation("Webform"), required = FALSE),
  *     "webform_submission" = @ContextDefinition("entity:webform_submission", label = @Translation("Webform submission"), required = FALSE),
  *     "node" = @ContextDefinition("entity:node", label = @Translation("Node"), required = FALSE),
diff --git a/web/modules/webform/src/Plugin/DevelGenerate/WebformSubmissionDevelGenerate.php b/web/modules/webform/src/Plugin/DevelGenerate/WebformSubmissionDevelGenerate.php
index 1e8fabeb42..9174c0485a 100644
--- a/web/modules/webform/src/Plugin/DevelGenerate/WebformSubmissionDevelGenerate.php
+++ b/web/modules/webform/src/Plugin/DevelGenerate/WebformSubmissionDevelGenerate.php
@@ -208,10 +208,12 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
       $form['submitted'] = [
         '#type' => 'item',
         '#title' => $this->t('Submitted to'),
-        '#field_prefix' => '<div class="container-inline">',
-        '#field_suffix' => '</div>',
       ];
-      $form['submitted']['entity-type'] = [
+      $form['submitted']['container'] = [
+        '#prefix' => '<div class="container-inline">',
+        '#suffix' => '</div>',
+      ];
+      $form['submitted']['container']['entity-type'] = [
         '#type' => 'select',
         '#title' => $this->t('Entity type'),
         '#title_display' => 'invisible',
@@ -219,7 +221,7 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
         '#options' => $entity_types,
         '#default_value' => $this->getSetting('entity-type'),
       ];
-      $form['submitted']['entity-id'] = [
+      $form['submitted']['container']['entity-id'] = [
         '#type' => 'number',
         '#title' => $this->t('Entity id'),
         '#title_display' => 'invisible',
@@ -296,7 +298,7 @@ protected function generateSubmissions(array $values) {
       $start = time();
       for ($i = 1; $i <= $values['num']; $i++) {
         $this->generateSubmission($values);
-        if (function_exists('drush_log') && $i % drush_get_option('feedback', 1000) == 0) {
+        if (function_exists('drush_log') && $i % drush_get_option('feedback', 1000) === 0) {
           $now = time();
           $dt_args = [
             '@feedback' => drush_get_option('feedback', 1000),
@@ -409,7 +411,7 @@ public function validateDrushParams($args) {
       return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid webform name: @name', ['@name' => $webform_id]));
     }
 
-    if ($this->isNumber($values['num']) == FALSE) {
+    if ($this->isNumber($values['num']) === FALSE) {
       return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid number of submissions: @num', ['@num' => $values['num']]));
     }
 
diff --git a/web/modules/webform/src/Plugin/Field/FieldFormatter/WebformEntityReferenceLinkFormatter.php b/web/modules/webform/src/Plugin/Field/FieldFormatter/WebformEntityReferenceLinkFormatter.php
index ff9e73b731..a4db034597 100644
--- a/web/modules/webform/src/Plugin/Field/FieldFormatter/WebformEntityReferenceLinkFormatter.php
+++ b/web/modules/webform/src/Plugin/Field/FieldFormatter/WebformEntityReferenceLinkFormatter.php
@@ -9,6 +9,7 @@
 use Drupal\Core\Render\RendererInterface;
 use Drupal\webform\Element\WebformMessage;
 use Drupal\webform\Entity\WebformSubmission;
+use Drupal\webform\Plugin\WebformSourceEntity\QueryStringWebformSourceEntity;
 use Drupal\webform\WebformMessageManagerInterface;
 use Drupal\webform\WebformTokenManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -201,12 +202,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
         else {
           $link_entity = $entity;
         }
-        $link_options = [
-          'query' => [
-            'source_entity_type' => $source_entity->getEntityTypeId(),
-            'source_entity_id' => $source_entity->id(),
-          ],
-        ];
+        $link_options = QueryStringWebformSourceEntity::getRouteOptionsQuery($source_entity);
         $link = [
           '#type' => 'link',
           '#title' => ['#markup' => $this->tokenManager->replace($link_label, $link_entity)],
diff --git a/web/modules/webform/src/Plugin/Field/FieldFormatter/WebformEntityReferenceUrlFormatter.php b/web/modules/webform/src/Plugin/Field/FieldFormatter/WebformEntityReferenceUrlFormatter.php
index cfaf261321..b63a8a94de 100644
--- a/web/modules/webform/src/Plugin/Field/FieldFormatter/WebformEntityReferenceUrlFormatter.php
+++ b/web/modules/webform/src/Plugin/Field/FieldFormatter/WebformEntityReferenceUrlFormatter.php
@@ -3,6 +3,7 @@
 namespace Drupal\webform\Plugin\Field\FieldFormatter;
 
 use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\webform\Plugin\WebformSourceEntity\QueryStringWebformSourceEntity;
 
 /**
  * Plugin implementation of the 'Webform url' formatter.
@@ -30,12 +31,7 @@ public function viewElements(FieldItemListInterface $items, $langcode) {
     $entities = $this->getEntitiesToView($items, $langcode);
 
     foreach ($entities as $delta => $entity) {
-      $link_options = [
-        'query' => [
-          'source_entity_type' => $source_entity->getEntityTypeId(),
-          'source_entity_id' => $source_entity->id(),
-        ],
-      ];
+      $link_options = QueryStringWebformSourceEntity::getRouteOptionsQuery($source_entity);
 
       $link = [
         '#plain_text' => $entity->toUrl('canonical', $link_options)->toString(),
diff --git a/web/modules/webform/src/Plugin/Field/FieldType/WebformEntityReferenceItem.php b/web/modules/webform/src/Plugin/Field/FieldType/WebformEntityReferenceItem.php
index cafeb981f5..1d40b13ef0 100644
--- a/web/modules/webform/src/Plugin/Field/FieldType/WebformEntityReferenceItem.php
+++ b/web/modules/webform/src/Plugin/Field/FieldType/WebformEntityReferenceItem.php
@@ -112,9 +112,17 @@ public static function getPreconfiguredOptions() {
    * {@inheritdoc}
    */
   public function getSettableOptions(AccountInterface $account = NULL) {
-    /** @var \Drupal\webform\WebformEntityStorageInterface $webform_storage */
-    $webform_storage = \Drupal::service('entity_type.manager')->getStorage('webform');
-    return $webform_storage->getOptions(FALSE);
+    $options = parent::getSettableOptions($account);
+
+    // Remove all templates.
+    if ($options && \Drupal::moduleHandler()->moduleExists('webform_templates')) {
+      /** @var \Drupal\webform\WebformEntityStorageInterface $webform_storage */
+      $webform_storage = \Drupal::service('entity_type.manager')->getStorage('webform');
+      $webform_templates = $webform_storage->loadByProperties(['template' => TRUE]);
+      $options = array_diff_key($options, $webform_templates);
+    }
+
+    return $options;
   }
 
 }
diff --git a/web/modules/webform/src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php b/web/modules/webform/src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php
index b0b611ece5..509397d3dc 100644
--- a/web/modules/webform/src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php
+++ b/web/modules/webform/src/Plugin/Field/FieldWidget/WebformEntityReferenceWidgetTrait.php
@@ -101,9 +101,9 @@ public function formElement(FieldItemListInterface $items, $delta, array $elemen
     $weight = $element['target_id']['#weight'];
 
     // Get webform.
+    $target_id = NULL;
     if ($form_state->isRebuilding()) {
-      $user_input = $form_state->getUserInput();
-      $target_id = $user_input[$field_name][$delta]['target_id'];
+      $target_id = $form_state->getValue(array_merge($element['target_id']['#field_parents'], [$field_name, $delta, 'target_id']));
     }
     else {
       $target_id = $items[$delta]->target_id;
diff --git a/web/modules/webform/src/Plugin/WebformElement/BooleanBase.php b/web/modules/webform/src/Plugin/WebformElement/BooleanBase.php
index 8f9e33f115..6e8933be96 100644
--- a/web/modules/webform/src/Plugin/WebformElement/BooleanBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/BooleanBase.php
@@ -66,7 +66,7 @@ public function form(array $form, FormStateInterface $form_state) {
       '#type' => 'textfield',
       '#title' => $this->t('Return value'),
       '#description' => $this->t('The return value is what is submitted to the server and stored in the database when the element is checked. The default value and recommended return value is a TRUE boolean value.')
-        . $this->t('<br/><br/>')
+        . '<br/><br/>'
         . $this->t('<strong>The return value should only be customized when an external system or service expects a custom string value. (i.e. yes, checked, accepted, etc…)</strong>'),
       '#weight' => -20,
     ];
diff --git a/web/modules/webform/src/Plugin/WebformElement/Checkboxes.php b/web/modules/webform/src/Plugin/WebformElement/Checkboxes.php
index 136f5f0e26..348b3fc564 100644
--- a/web/modules/webform/src/Plugin/WebformElement/Checkboxes.php
+++ b/web/modules/webform/src/Plugin/WebformElement/Checkboxes.php
@@ -3,6 +3,7 @@
 namespace Drupal\webform\Plugin\WebformElement;
 
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\webform\Utility\WebformArrayHelper;
 use Drupal\webform\Utility\WebformOptionsHelper;
 use Drupal\webform\WebformSubmissionConditionsValidator;
 use Drupal\webform\WebformSubmissionInterface;
@@ -31,11 +32,25 @@ protected function defineDefaultProperties() {
       'options_display' => 'one_column',
       'options_description_display' => 'description',
       'options__properties' => [],
+      // Options all and none.
+      'options_all' => FALSE,
+      'options_all_value' => 'all',
+      'options_all_text' => (string) $this->t('All of the above'),
+      'options_none' => FALSE,
+      'options_none_value' => 'none',
+      'options_none_text' => (string) $this->t('None of the above'),
       // Wrapper.
       'wrapper_type' => 'fieldset',
     ] + parent::defineDefaultProperties();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineTranslatableProperties() {
+    return array_merge(parent::defineTranslatableProperties(), ['options_all_text', 'options_none_text']);
+  }
+
   /****************************************************************************/
 
   /**
@@ -52,15 +67,68 @@ public function hasMultipleValues(array $element) {
     return TRUE;
   }
 
+
+  /**
+   * {@inheritdoc}
+   */
+  public function initialize(array &$element) {
+    parent::initialize($element);
+
+    $option_types = ['options_all', 'options_none'];
+    foreach ($option_types as $option_type) {
+      if (!empty($element['#' . $option_type])) {
+        $element['#' . $option_type . '_value'] = $this->getElementProperty($element, $option_type . '_value');
+        $element['#' . $option_type . '_text'] = $this->getElementProperty($element, $option_type . '_text');
+        // Set #options for every element except 'webform_entity_checkboxes'.
+        // @see \Drupal\webform\Plugin\WebformElement\WebformEntityReferenceTrait::setOptions
+        if ($element['#type'] !== 'webform_entity_checkboxes') {
+          $element['#options'][$element['#' . $option_type . '_value']] = $element['#' . $option_type . '_text'];
+        }
+      }
+    }
+  }
+
   /**
    * {@inheritdoc}
    */
   public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
     parent::prepare($element, $webform_submission);
 
-    // Issue #3068998: Checkboxes validation UI is different than
-    // other elements.
+    // Set 'data-options-all' and 'data-options-all' attribute.
+    $option_types = ['options_all', 'options_none'];
+    foreach ($option_types as $option_type) {
+      if (!empty($element['#' . $option_type])) {
+        // If options are randomized, make sure the 'all' and 'none' checkboxes
+        // are always last.
+        if (!empty($element['#options_randomize'])) {
+          unset($element['#options'][$element['#' . $option_type . '_value']]);
+          $element['#options'][$element['#' . $option_type . '_value']] = $element['#' . $option_type . '_text'];
+        }
+        $element['#wrapper_attributes']['data-' . str_replace('_', '-', $option_type)] = $element['#' . $option_type . '_value'];
+      }
+    }
+
     $element['#attached']['library'][] = 'webform/webform.element.checkboxes';
+
+    if (!empty($element['#options_all']) || !empty($element['#options_none']))
+    $element['#element_validate'][] = [get_class($this), 'validateCheckAllOrNone'];
+
+  }
+
+  /**
+   * Form API callback. Handle check all or none option.
+   */
+  public static function validateCheckAllOrNone(array &$element, FormStateInterface $form_state, array &$completed_form) {
+    $values = $form_state->getValue($element['#parents'], []);
+    if (!empty($element['#options_all'])) {
+      // Remove options all value.
+      WebformArrayHelper::removeValue($values, $element['#options_all_value']);
+    }
+    elseif (!empty($element['#options_none']) && in_array($element['#options_none_value'], $values)) {
+      // Only allow none option to be submitted.
+      $values = [$element['#options_none_value']];
+    }
+    $form_state->setValueForElement($element, $values);
   }
 
   /**
@@ -109,6 +177,39 @@ public function form(array $form, FormStateInterface $form_state) {
     // Checkboxes must require > 2 options.
     $form['element']['multiple']['#min'] = 2;
 
+    // Include options all and none.
+    $option_types = [
+      'options_all' => $this->t('All'),
+      'options_none' => $this->t('None'),
+    ];
+    foreach ($option_types as $option_type => $option_label) {
+      if (!$this->hasProperty($option_type)) {
+        continue;
+      }
+
+      $t_args = ['@type' => $option_label];
+      $form['options'][$option_type] = [
+        '#type' => 'checkbox',
+        '#title' => $this->t("Include '@type of the above' option", $t_args),
+        '#return_value' => TRUE,
+      ];
+      $form['options'][$option_type . '_container'] = $this->getFormInlineContainer() + [
+        '#states' => [
+          'visible' => [[':input[name="properties[' . $option_type . ']"]' => ['checked' => TRUE]]],
+          'required' => [[':input[name="properties[' . $option_type . ']"]' => ['checked' => TRUE]]],
+        ],
+      ];
+      $form['options'][$option_type . '_container'][$option_type . '_value'] = [
+        '#type' => 'textfield',
+        '#title' => $this->t("@type option value", $t_args),
+
+      ];
+      $form['options'][$option_type . '_container'][$option_type . '_text'] = [
+        '#type' => 'textfield',
+        '#title' => $this->t("@type option text", $t_args),
+        '#attributes' => ['class' => ['webform-ui-element-form-inline--input-double-width']]
+      ];
+    }
     return $form;
   }
 
diff --git a/web/modules/webform/src/Plugin/WebformElement/ContainerBase.php b/web/modules/webform/src/Plugin/WebformElement/ContainerBase.php
index bc3295099a..b278ad7ec9 100644
--- a/web/modules/webform/src/Plugin/WebformElement/ContainerBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/ContainerBase.php
@@ -162,6 +162,15 @@ protected function formatHtmlItem(array $element, WebformSubmissionInterface $we
           '#children' => $children,
         ];
 
+      case 'container':
+        $attributes['class'][] = 'webform-container';
+        return [
+          '#type' => 'container',
+          '#id' => $element['#webform_id'],
+          '#attributes' => $attributes,
+          '#children' => $children,
+        ];
+
       case 'header':
       default:
         return [
@@ -208,7 +217,7 @@ protected function formatCustomItem($type, array &$element, WebformSubmissionInt
 
     // Parse children from template and children to context.
     $template = trim($element['#format_' . $name]);
-    if (strpos($template, 'children') != FALSE) {
+    if (strpos($template, 'children') !== FALSE) {
       /** @var \Drupal\webform\WebformSubmissionViewBuilderInterface $view_builder */
       $view_builder = \Drupal::entityTypeManager()->getViewBuilder('webform_submission');
       $context['children'] = $view_builder->buildElements($element, $webform_submission, $options, $name);
@@ -233,6 +242,7 @@ public function getItemFormats() {
       'fieldset' => $this->t('Fieldset'),
       'details' => $this->t('Details (opened)'),
       'details-closed' => $this->t('Details (closed)'),
+      'container' => $this->t('Container (no title)'),
     ];
   }
 
diff --git a/web/modules/webform/src/Plugin/WebformElement/DateBase.php b/web/modules/webform/src/Plugin/WebformElement/DateBase.php
index 85f94b9091..16dc75d28d 100644
--- a/web/modules/webform/src/Plugin/WebformElement/DateBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/DateBase.php
@@ -50,7 +50,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
     $element['#theme_wrappers'] = ['form_element'];
 
     // Must manually process #states.
-    // @see drupal_process_states().
+    // @see \Drupal\Core\Form\FormHelper::processStates
     if (!empty($element['#states'])) {
       $element['#attached']['library'][] = 'core/drupal.states';
       $element['#wrapper_attributes']['data-drupal-states'] = Json::encode($element['#states']);
diff --git a/web/modules/webform/src/Plugin/WebformElement/DateTime.php b/web/modules/webform/src/Plugin/WebformElement/DateTime.php
index ba66484006..55d0a2a66c 100644
--- a/web/modules/webform/src/Plugin/WebformElement/DateTime.php
+++ b/web/modules/webform/src/Plugin/WebformElement/DateTime.php
@@ -124,21 +124,6 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
     parent::prepare($element, $webform_submission);
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public static function afterBuild(array $element, FormStateInterface $form_state) {
-    $element = parent::afterBuild($element, $form_state);
-    // Date and time custom placeholder
-    if (isset($element['#date_date_placeholder'])) {
-      $element['date']['#attributes']['placeholder'] = $element['#date_date_placeholder'];
-    }
-    if (isset($element['#date_time_placeholder'])) {
-      $element['time']['#attributes']['placeholder'] = $element['#date_time_placeholder'];
-    }
-    return $element;
-  }
-
   /**
    * {@inheritdoc}
    */
diff --git a/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php b/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php
index 424986ff9c..de34a0d12a 100644
--- a/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php
@@ -633,17 +633,17 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
    */
   public function buildExportHeader(array $element, array $options) {
     $options_format = ($element['#webform_multiple'] ? $options['options_multiple_format'] : $options['options_single_format']);
-    if ($options_format == 'separate' && isset($element['#options'])) {
+    if ($options_format === 'separate' && isset($element['#options'])) {
       $header = [];
       foreach ($element['#options'] as $option_value => $option_text) {
         // Note: If $option_text is an array (typically a tableselect row)
         // always use $option_value.
-        $title = ($options['options_item_format'] == 'key' || is_array($option_text)) ? $option_value : $option_text;
+        $title = ($options['options_item_format'] === 'key' || is_array($option_text)) ? $option_value : $option_text;
         $header[] = $title;
       }
       // Add 'Other' option to header.
       if ($this instanceof WebformElementOtherInterface) {
-        $header[] = ($options['options_item_format'] == 'key') ? 'other' : $this->t('Other');
+        $header[] = ($options['options_item_format'] === 'key') ? 'other' : $this->t('Other');
       }
       return $this->prefixExportHeader($header, $element, $options);
     }
@@ -658,7 +658,7 @@ public function buildExportHeader(array $element, array $options) {
   public function buildExportRecord(array $element, WebformSubmissionInterface $webform_submission, array $export_options) {
     $element_options = (isset($element['#options'])) ? $element['#options'] : [];
     $options_format = ($element['#webform_multiple'] ? $export_options['options_multiple_format'] : $export_options['options_single_format']);
-    if ($options_format == 'separate') {
+    if ($options_format === 'separate') {
       $value = $this->getRawValue($element, $webform_submission);
 
       $record = [];
@@ -675,7 +675,7 @@ public function buildExportRecord(array $element, WebformSubmissionInterface $we
           unset($value[$option_value]);
           $record[] = ($deltas) ? ($deltas[$option_value] + 1) : 'X';
         }
-        elseif ($value == $option_value) {
+        elseif ($value === $option_value) {
           $value = '';
           $record[] = ($deltas) ? ($deltas[$option_value] + 1) : 'X';
         }
@@ -690,7 +690,7 @@ public function buildExportRecord(array $element, WebformSubmissionInterface $we
       return $record;
     }
     else {
-      if ($export_options['options_item_format'] == 'key') {
+      if ($export_options['options_item_format'] === 'key') {
         $element['#format'] = 'raw';
       }
       return parent::buildExportRecord($element, $webform_submission, $export_options);
@@ -810,6 +810,11 @@ public function getElementSelectorInputValue($selector, $trigger, array $element
         }
       }
       else {
+        // If the trigger is 'filled or 'empty' then return the value.
+        if ($trigger === 'filled' || $trigger === 'empty') {
+          return $value;
+        }
+
         if ($this->hasMultipleValues($element)) {
           // Return array of valid #options.
           return array_intersect($value, array_keys($options));
@@ -864,7 +869,9 @@ public function form(array $form, FormStateInterface $form_state) {
         'two_columns' => $this->t('Two columns'),
         'three_columns' => $this->t('Three columns'),
         'side_by_side' => $this->t('Side by side'),
-        'buttons' => $this->t('Buttons'),
+        'buttons' => $this->t('Buttons - flexbox'),
+        'buttons_horizontal' => $this->t('Buttons - horizontal'),
+        'buttons_vertical' => $this->t('Buttons - vertical'),
       ],
     ];
     $form['options']['options_display_container']['options_description_display'] = [
@@ -905,6 +912,16 @@ public function form(array $form, FormStateInterface $form_state) {
       ],
     ];
 
+    // Sort options (only applies to select menus).
+    // @see template_preprocess_select()
+    // @see webform_preprocess_select()
+    $form['options']['sort_options'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Sort options'),
+      '#description' => $this->t('Sort the options by their (translated) labels.'),
+      '#return_value' => TRUE,
+    ];
+
     $form['options']['options_randomize'] = [
       '#type' => 'checkbox',
       '#title' => $this->t('Randomize options'),
@@ -912,6 +929,12 @@ public function form(array $form, FormStateInterface $form_state) {
       '#return_value' => TRUE,
     ];
 
+    if ($this->hasProperty('options_randomize') && $this->hasProperty('sort_options')) {
+      $form['options']['options_randomize']['#states']['visible'] = [
+        ':input[name="properties[sort_options]"]' => ['checked' => FALSE],
+      ];
+    }
+
     // Other.
     $states_textfield_or_number = [
       'visible' => [
diff --git a/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php.orig b/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php.orig
deleted file mode 100644
index d57c7d7a8b..0000000000
--- a/web/modules/webform/src/Plugin/WebformElement/OptionsBase.php.orig
+++ /dev/null
@@ -1,1073 +0,0 @@
-<?php
-
-namespace Drupal\webform\Plugin\WebformElement;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Form\OptGroup;
-use Drupal\Core\Mail\MailFormatHelper;
-use Drupal\Core\Render\Markup;
-use Drupal\webform\Utility\WebformArrayHelper;
-use Drupal\webform\Utility\WebformElementHelper;
-use Drupal\webform\Utility\WebformOptionsHelper;
-use Drupal\webform\Plugin\WebformElementBase;
-use Drupal\webform\Plugin\WebformElementEntityReferenceInterface;
-use Drupal\webform\Plugin\WebformElementOtherInterface;
-use Drupal\webform\WebformSubmissionConditionsValidator;
-use Drupal\webform\WebformSubmissionInterface;
-
-/**
- * Provides a base 'options' element.
- */
-abstract class OptionsBase extends WebformElementBase {
-
-  use TextBaseTrait;
-
-  /**
-   * Export delta for multiple options.
-   *
-   * @var bool
-   */
-  protected $exportDelta = FALSE;
-
-  /**
-   * The other option base element type.
-   *
-   * @var string
-   */
-  protected $otherOptionType;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function defineDefaultProperties() {
-    $properties = [
-      // Options settings.
-      'options' => [],
-      'options_randomize' => FALSE,
-    ] + parent::defineDefaultProperties();
-
-    // Add other properties to elements that include the other text field.
-    if ($this->isOptionsOther()) {
-      $properties += [
-        'other__option_label' => $this->t('Other…'),
-        'other__type' => 'textfield',
-        'other__title' => '',
-        'other__placeholder' => $this->t('Enter other…'),
-        'other__description' => '',
-        // Text field or textarea.
-        'other__size' => '',
-        'other__maxlength' => '',
-        'other__field_prefix' => '',
-        'other__field_suffix' => '',
-        // Textarea.
-        'other__rows' => '',
-        // Number.
-        'other__min' => '',
-        'other__max' => '',
-        'other__step' => '',
-        // Counter.
-        'other__counter_type' => '',
-        'other__counter_minimum' => '',
-        'other__counter_minimum_message' => '',
-        'other__counter_maximum' => '',
-        'other__counter_maximum_message' => '',
-        // Wrapper.
-        'wrapper_type' => 'fieldset',
-      ];
-    }
-
-    return $properties;
-  }
-
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isMultiline(array $element) {
-    $items_format = $this->getItemsFormat($element);
-    if (strpos($items_format, 'checklist:') === 0) {
-      return TRUE;
-    }
-    else {
-      return parent::isMultiline($element);
-    }
-  }
-
-  /**
-   * Determine if the element plugin type includes an other option text field.
-   *
-   * @return bool
-   *   TRUE if the element plugin type includes an other option text field.
-   */
-  protected function isOptionsOther() {
-    return $this->getOptionsOtherType() ? TRUE : FALSE;
-  }
-
-  /**
-   * Get the other option base element type.
-   *
-   * @return string|null
-   *   The base element type (select|radios|checkboxes|buttons).
-   */
-  protected function getOptionsOtherType() {
-    if (isset($this->otherOptionType)) {
-      return $this->otherOptionType;
-    }
-
-    if (preg_match('/webform_(select|radios|checkboxes|buttons)_other$/', $this->getPluginId(), $match)) {
-      $this->otherOptionType = $match[1];
-    }
-    else {
-      $this->otherOptionType = FALSE;
-    }
-
-    return $this->otherOptionType;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function defineTranslatableProperties() {
-    return array_merge(
-      parent::defineTranslatableProperties(),
-      ['options', 'empty_option', 'option_label']
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRelatedTypes(array $element) {
-    $related_types = parent::getRelatedTypes($element);
-    // Remove entity reference elements.
-    $elements = $this->elementManager->getInstances();
-    foreach ($related_types as $type => $related_type) {
-      $element_instance = $elements[$type];
-      if ($element_instance instanceof WebformElementEntityReferenceInterface) {
-        unset($related_types[$type]);
-      }
-    }
-    return $related_types;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
-    $is_wrapper_fieldset = in_array($element['#type'], ['checkboxes', 'radios', 'webform_entity_checkboxes', 'webform_entity_radios', 'webform_term_checkboxes', 'webform_toggles', 'webform_buttons']);
-    if ($is_wrapper_fieldset) {
-      // Issue #2396145: Option #description_display for webform element fieldset
-      // is not changing anything.
-      // @see core/modules/system/templates/fieldset.html.twig
-      $is_description_display = (isset($element['#description_display'])) ? TRUE : FALSE;
-      $has_description = (!empty($element['#description'])) ? TRUE : FALSE;
-      if ($is_description_display && $has_description) {
-        $description = WebformElementHelper::convertToString($element['#description']);
-        switch ($element['#description_display']) {
-          case 'before':
-            $element += ['#field_prefix' => ''];
-            $element['#field_prefix'] = '<div class="description">' . $description . '</div>' . $element['#field_prefix'];
-            unset($element['#description']);
-            unset($element['#description_display']);
-            break;
-
-          case 'tooltip':
-            $element += ['#field_suffix' => ''];
-            $element['#field_suffix'] .= '<div class="description visually-hidden">' . $description . '</div>';
-            // @see \Drupal\Core\Render\Element\CompositeFormElementTrait
-            // @see \Drupal\webform\Plugin\WebformElementBase::prepare
-            $element['#attributes']['class'][] = 'js-webform-tooltip-element';
-            $element['#attributes']['class'][] = 'webform-tooltip-element';
-            $element['#attached']['library'][] = 'webform/webform.tooltip';
-            unset($element['#description']);
-            unset($element['#description_display']);
-            break;
-
-          case 'invisible':
-            $element += ['#field_suffix' => ''];
-            $element['#field_suffix'] .= '<div class="description visually-hidden">' . $description . '</div>';
-            unset($element['#description']);
-            unset($element['#description_display']);
-            break;
-        }
-      }
-    }
-
-    parent::prepare($element, $webform_submission);
-
-    // Randomize options.
-    if (isset($element['#options']) && !empty($element['#options_randomize'])) {
-      $element['#options'] = WebformElementHelper::randomize($element['#options']);
-    }
-
-    // Options description display must be set to trigger the description display.
-    if ($this->hasProperty('options_description_display') && empty($element['#options_description_display'])) {
-      $element['#options_description_display'] = $this->getDefaultProperty('options_description_display');
-    }
-
-    // Options display must be set to trigger the options display.
-    if ($this->hasProperty('options_display') && empty($element['#options_display'])) {
-      $element['#options_display'] = $this->getDefaultProperty('options_display');
-    }
-
-    // Make sure submitted value is not lost if the element's #options were
-    // altered after the submission was completed.
-    // This only applies to the main webforom element with a #webform_key
-    // and not a webform composite's sub elements.
-    $is_completed = $webform_submission && $webform_submission->isCompleted();
-    $has_default_value = (isset($element['#default_value']) && $element['#default_value'] !== '' && $element['#default_value'] !== NULL);
-    if ($is_completed && $has_default_value && !$this->isOptionsOther() && isset($element['#webform_key'])) {
-      if ($element['#default_value'] === $webform_submission->getElementData($element['#webform_key'])) {
-        $options = OptGroup::flattenOptions($element['#options']);
-        $default_values = (array) $element['#default_value'];
-        foreach ($default_values as $default_value) {
-          if (!isset($options[$default_value])) {
-            $element['#options'][$default_value] = $default_value;
-          }
-        }
-      }
-    }
-
-    // If the element is #required and the #default_value is an empty string
-    // we need to unset the #default_value to prevent the below error.
-    // 'An illegal choice has been detected'.
-    if (!empty($element['#required']) && isset($element['#default_value']) && $element['#default_value'] === '') {
-      unset($element['#default_value']);
-    }
-
-    // Process custom options properties.
-    if ($this->hasProperty('options__properties')) {
-      $this->setElementDefaultCallback($element, 'process');
-      $element['#process'][] = [get_class($this), 'processOptionsProperties'];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function prepareElementValidateCallbacks(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
-    if ($this->hasMultipleValues($element)) {
-      $element['#element_validate'][] = [get_class($this), 'validateMultipleOptions'];
-    }
-    parent::prepareElementValidateCallbacks($element, $webform_submission);
-  }
-
-  /**
-   * Processes options (custom) properties.
-   */
-  public static function processOptionsProperties(&$element, FormStateInterface $form_state, &$complete_form) {
-    if (empty($element['#options__properties'])) {
-      return $element;
-    }
-
-    foreach ($element['#options__properties'] as $option_key => $options__properties) {
-      if (!isset($element[$option_key])) {
-        continue;
-      }
-
-      // Remove ignored properties.
-      $options__properties = WebformElementHelper::removeIgnoredProperties($options__properties);
-
-      foreach ($options__properties as $property => $value) {
-        $option_element =& $element[$option_key];
-        if (in_array($property, ['#attributes', '#wrapper_attributes', '#label_attributes'])) {
-          // Apply attributes.
-          $option_element += [$property => []];
-          foreach ($value as $attribute_name => $attribute_value) {
-            // Merge attributes class.
-            if ($attribute_name === 'class' && isset($element[$option_key][$property][$attribute_name])) {
-              $option_element[$property][$attribute_name] = array_merge($element[$option_key][$property][$attribute_name], $attribute_value);
-            }
-            else {
-              $option_element[$property][$attribute_name] = $attribute_value;
-            }
-          }
-        }
-        else {
-          $option_element[$property] = $value;
-        }
-      }
-    }
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasMultipleWrapper() {
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setDefaultValue(array &$element) {
-    if (!isset($element['#default_value'])) {
-      return;
-    }
-
-    // Compensate for #default_value not being an array, for elements that
-    // allow for multiple #options to be selected/checked.
-    if ($this->hasMultipleValues($element) && !is_array($element['#default_value'])) {
-      $element['#default_value'] = [$element['#default_value']];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function formatHtmlItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $value = $this->getValue($element, $webform_submission, $options);
-
-    $format = $this->getItemFormat($element);
-    switch ($format) {
-      case 'raw':
-        return Markup::create($value);
-
-      case 'description':
-        if (isset($element['#options'])) {
-          $options_description = $this->hasProperty('options_description_display');
-          if ($options_description) {
-            $description = WebformOptionsHelper::getOptionDescription($value, $element['#options'], $options_description);
-            return ['#markup' => $description];
-          }
-        }
-        return '';
-
-      case 'value':
-      default:
-        if (isset($element['#options'])) {
-          $options_description = $this->hasProperty('options_description_display');
-          $value = WebformOptionsHelper::getOptionText($value, $element['#options'], $options_description);
-        }
-
-        // Build a render array that uses #plain_text so that
-        // HTML characters are escaped.
-        // @see \Drupal\Core\Render\Renderer::ensureMarkupIsSafe
-        if ($value === '0') {
-          // Issue #2765609: #plain_text doesn't render empty-like values
-          // (e.g. 0 and "0").
-          // Workaround: Use #markup until this issue is fixed.
-          // @todo Remove workaround once only Drupal 8.7.x is supported.
-          $build = ['#markup' => $value];
-        }
-        else {
-          $build = ['#plain_text' => $value];
-        }
-
-        $options += ['prefixing' => TRUE];
-        if ($options['prefixing']) {
-          if (isset($element['#field_prefix'])) {
-            $build['#prefix'] = $element['#field_prefix'];
-          }
-          if (isset($element['#field_suffix'])) {
-            $build['#suffix'] = $element['#field_suffix'];
-          }
-        }
-        return $build;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function formatTextItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $value = $this->getValue($element, $webform_submission, $options);
-
-    $format = $this->getItemFormat($element);
-    switch ($format) {
-      case 'raw':
-        return $value;
-
-      case 'description':
-        if (isset($element['#options'])) {
-          $options_description = $this->hasProperty('options_description_display');
-          if ($options_description) {
-            $description = WebformOptionsHelper::getOptionDescription($value, $element['#options'], $options_description);
-            if ($description) {
-              return MailFormatHelper::htmlToText($description);
-            }
-          }
-        }
-        return '';
-
-      case 'value':
-      default:
-        if (isset($element['#options'])) {
-          $options_description = $this->hasProperty('options_description_display');
-          $value = WebformOptionsHelper::getOptionText($value, $element['#options'], $options_description);
-        }
-
-        $options += ['prefixing' => TRUE];
-        if ($options['prefixing']) {
-          if (isset($element['#field_prefix'])) {
-            $value = strip_tags($element['#field_prefix']) . $value;
-          }
-          if (isset($element['#field_suffix'])) {
-            $value .= strip_tags($element['#field_suffix']);
-          }
-        }
-
-        return $value;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getItemFormats() {
-    return parent::getItemFormats() + [
-      'description' => $this->t('Option description'),
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getItemsDefaultFormat() {
-    return 'comma';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function formatHtmlItems(array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $format = $this->getItemsFormat($element);
-    if (strpos($format, 'checklist:') === 0) {
-      // Get checked/unchecked icons.
-      list(, $checked_type) = explode(':', $format);
-      switch ($checked_type) {
-        case 'crosses':
-          $checked = '✖ ';
-          $unchecked = '⚬ ';
-          break;
-
-        default:
-        case 'boxes':
-          $checked = Markup::create('<span style="font-size: 1.4em; line-height: 1em">☑</span> ');
-          $unchecked = Markup::create('<span style="font-size: 1.4em; line-height: 1em">☐</span> ');
-          break;
-      }
-
-      $value = (array) $this->getValue($element, $webform_submission, $options);
-      $values = array_combine($value, $value);
-
-      // Build list of checked and unchecked options.
-      $build = [];
-      $options_description = $this->hasProperty('options_description_display');
-      foreach ($element['#options'] as $option_value => $option_text) {
-        if ($options_description && strpos($option_text, WebformOptionsHelper::DESCRIPTION_DELIMITER) !== FALSE) {
-          list($option_text) = explode(WebformOptionsHelper::DESCRIPTION_DELIMITER, $option_text);
-        }
-        $build[$option_value] = [
-          '#prefix' => isset($values[$option_value]) ? $checked : $unchecked,
-          '#markup' => $option_text,
-          '#suffix' => '<br/>',
-        ];
-        unset($values[$option_value]);
-      }
-      // Append all remaining option values.
-      foreach ($values as $value) {
-        $build[$value] = [
-          '#prefix' => $checked,
-          '#markup' => $value,
-          '#suffix' => '<br/>',
-        ];
-      }
-      return $build;
-    }
-    else {
-      return parent::formatHtmlItems($element, $webform_submission, $options);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function formatTextItems(array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $format = $this->getItemsFormat($element);
-    if (strpos($format, 'checklist:') === 0) {
-      // Get checked/unchecked icons.
-      list(, $checked_type) = explode(':', $format);
-      switch ($checked_type) {
-        case 'crosses':
-          $checked = '✖';
-          $unchecked = '⚬';
-          break;
-
-        default:
-        case 'boxes':
-          $checked = '☑';
-          $unchecked = '☐';
-          break;
-      }
-
-      $value = (array) $this->getValue($element, $webform_submission, $options);
-      $values = array_combine($value, $value);
-
-      // Build list of checked and unchecked options.
-      $list = [];
-      $options_description = $this->hasProperty('options_description_display');
-      foreach ($element['#options'] as $option_value => $option_text) {
-        if ($options_description && strpos($option_text, WebformOptionsHelper::DESCRIPTION_DELIMITER) !== FALSE) {
-          list($option_text) = explode(WebformOptionsHelper::DESCRIPTION_DELIMITER, $option_text);
-        }
-        $list[] = ((isset($values[$option_value])) ? $checked : $unchecked) . ' ' . $option_text;
-        unset($values[$option_value]);
-      }
-      // Append all remaining option values.
-      foreach ($values as $value) {
-        $list[] = $checked . ' ' . $value;
-      }
-      return implode(PHP_EOL, $list);
-    }
-    else {
-        return parent::formatTextItems($element, $webform_submission, $options);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getItemsFormats() {
-    return parent::getItemsFormats() + [
-      'checklist:boxes' => $this->t('Checklist (☑/☐)'),
-      'checklist:crosses' => $this->t('Checklist (gi)'),
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preview() {
-    $element = parent::preview();
-    if ($this->hasProperty('options')) {
-      $element['#options'] = [
-        'one' => 'One',
-        'two' => 'Two',
-        'three' => 'Three',
-      ];
-    }
-    if ($this->hasProperty('options_display')) {
-      $element['#options_display'] = 'side_by_side';
-    }
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTableColumn(array $element) {
-    $key = $element['#webform_key'];
-    $columns = parent::getTableColumn($element);
-    $columns['element__' . $key]['sort'] = !$this->hasMultipleValues($element);
-    return $columns;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getExportDefaultOptions() {
-    return [
-      'options_single_format' => 'compact',
-      'options_multiple_format' => 'compact',
-      'options_item_format' => 'label',
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildExportOptionsForm(array &$form, FormStateInterface $form_state, array $export_options) {
-    parent::buildExportOptionsForm($form, $form_state, $export_options);
-    if (isset($form['options'])) {
-      return;
-    }
-
-    // Build format options with help.
-    $options_format_options = [
-      'compact' => $this->t('Compact, with the option values delimited by commas in one column.') .
-        WebformOptionsHelper::DESCRIPTION_DELIMITER .
-        $this->t('Compact options are more suitable for importing data into other systems.'),
-      'separate' => $this->t('Separate, with each possible option value in its own column.') .
-        WebformOptionsHelper::DESCRIPTION_DELIMITER .
-        $this->t('Separate options are more suitable for building reports, graphs, and statistics in a spreadsheet application. Ranking will be included for sortable option elements.'),
-    ];
-    $form['options'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Select menu, radio buttons, and checkboxes options'),
-      '#open' => TRUE,
-      '#weight' => -10,
-    ];
-    $form['options']['options_single_format'] = [
-      '#type' => 'radios',
-      '#title' => $this->t('Options single value format'),
-      '#description' => $this->t('Elements that collect a single option value include select menus, radios, and buttons.'),
-      '#options' => $options_format_options,
-      '#options_description_display' => 'help',
-      '#default_value' => $export_options['options_single_format'],
-    ];
-    $form['options']['options_multiple_format'] = [
-      '#type' => 'radios',
-      '#title' => $this->t('Options multiple values format'),
-      '#description' => $this->t('Elements that collect multiple option values include multi-select, checkboxes, and toggles.'),
-      '#options' => $options_format_options,
-      '#options_description_display' => 'help',
-      '#default_value' => $export_options['options_multiple_format'],
-    ];
-    $form['options']['options_item_format'] = [
-      '#type' => 'radios',
-      '#title' => $this->t('Options item format'),
-      '#options' => [
-        'label' => $this->t('Option labels, the human-readable value (label)'),
-        'key' => $this->t('Option values, the raw value stored in the database (key)'),
-      ],
-      '#default_value' => $export_options['options_item_format'],
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildExportHeader(array $element, array $options) {
-    $options_format = ($element['#webform_multiple'] ? $options['options_multiple_format'] : $options['options_single_format']);
-    if ($options_format == 'separate' && isset($element['#options'])) {
-      $header = [];
-      foreach ($element['#options'] as $option_value => $option_text) {
-        // Note: If $option_text is an array (typically a tableselect row)
-        // always use $option_value.
-        $title = ($options['options_item_format'] == 'key' || is_array($option_text)) ? $option_value : $option_text;
-        $header[] = $title;
-      }
-      // Add 'Other' option to header.
-      if ($this instanceof WebformElementOtherInterface) {
-        $header[] = ($options['options_item_format'] == 'key') ? 'other' : $this->t('Other');
-      }
-      return $this->prefixExportHeader($header, $element, $options);
-    }
-    else {
-      return parent::buildExportHeader($element, $options);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildExportRecord(array $element, WebformSubmissionInterface $webform_submission, array $export_options) {
-    $element_options = (isset($element['#options'])) ? $element['#options'] : [];
-    $options_format = ($element['#webform_multiple'] ? $export_options['options_multiple_format'] : $export_options['options_single_format']);
-    if ($options_format == 'separate') {
-      $value = $this->getRawValue($element, $webform_submission);
-
-      $record = [];
-      // Combine the values so that isset can be used instead of in_array().
-      // http://stackoverflow.com/questions/13483219/what-is-faster-in-array-or-isset
-      $deltas = FALSE;
-      if (is_array($value)) {
-        $value = array_combine($value, $value);
-        $deltas = ($this->exportDelta) ? array_flip(array_values($value)) : FALSE;
-      }
-      // Separate multiple values (i.e. options).
-      foreach ($element_options as $option_value => $option_text) {
-        if (is_array($value) && isset($value[$option_value])) {
-          unset($value[$option_value]);
-          $record[] = ($deltas) ? ($deltas[$option_value] + 1) : 'X';
-        }
-        elseif ($value == $option_value) {
-          $value = '';
-          $record[] = ($deltas) ? ($deltas[$option_value] + 1) : 'X';
-        }
-        else {
-          $record[] = '';
-        }
-      }
-      // Add 'Other' option to record.
-      if ($this instanceof WebformElementOtherInterface) {
-        $record[] = (is_array($value)) ? implode($export_options['multiple_delimiter'], $value) : $value;
-      }
-      return $record;
-    }
-    else {
-      if ($export_options['options_item_format'] == 'key') {
-        $element['#format'] = 'raw';
-      }
-      return parent::buildExportRecord($element, $webform_submission, $export_options);
-    }
-  }
-
-  /**
-   * Form API callback. Remove unchecked options from value array.
-   */
-  public static function validateMultipleOptions(array &$element, FormStateInterface $form_state, array &$completed_form) {
-    $values = $element['#value'] ?: [];
-    // Filter unchecked/unselected options whose value is 0.
-    $values = array_filter($values, function ($value) {
-      return $value !== 0;
-    });
-    $values = array_values($values);
-    $form_state->setValueForElement($element, $values);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function getElementSelectorInputsOptions(array $element) {
-    if ($other_type = $this->getOptionsOtherType()) {
-      list($type) = explode(' ', $this->getPluginLabel());
-      $title = $this->getAdminLabel($element);
-      $name = $other_type;
-
-      $inputs = [];
-      $inputs[$name] = $title . ' [' . $type . ']';
-      $inputs['other'] = $title . ' [' . $this->t('Other field') . ']';
-      return $inputs;
-    }
-    else {
-      return [];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * @see \Drupal\webform\Entity\Webform::getElementsSelectorOptions
-   */
-  public function getElementSelectorOptions(array $element) {
-    if ($this->hasMultipleValues($element) && $this->hasMultipleWrapper()) {
-      return [];
-    }
-
-    $plugin_id = $this->getPluginId();
-    $title = $this->getAdminLabel($element) . ' [' . $this->getPluginLabel() . ']';
-    $name = $element['#webform_key'];
-
-    if ($inputs = $this->getElementSelectorInputsOptions($element)) {
-      $selectors = [];
-      foreach ($inputs as $input_name => $input_title) {
-        $multiple = ($this->hasMultipleValues($element) && $input_name === 'select') ? '[]' : '';
-        $selectors[":input[name=\"{$name}[{$input_name}]$multiple\"]"] = $input_title;
-      }
-      return [$title => $selectors];
-    }
-    else {
-      $multiple = ($this->hasMultipleValues($element) && strpos($plugin_id, 'select') !== FALSE) ? '[]' : '';
-      return [":input[name=\"$name$multiple\"]" => $title];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementSelectorSourceValues(array $element) {
-    if ($this->hasMultipleValues($element) && $this->hasMultipleWrapper()) {
-      return [];
-    }
-
-    $plugin_id = $this->getPluginId();
-    $name = $element['#webform_key'];
-    $options = OptGroup::flattenOptions($element['#options']);
-    if ($this->getElementSelectorInputsOptions($element)) {
-      $other_type = $this->getOptionsOtherType();
-      $multiple = ($this->hasMultipleValues($element) && $other_type === 'select') ? '[]' : '';
-      return [":input[name=\"{$name}[$other_type]$multiple\"]" => $options];
-    }
-    else {
-      $multiple = ($this->hasMultipleValues($element) && strpos($plugin_id, 'select') !== FALSE) ? '[]' : '';
-      return [":input[name=\"$name$multiple\"]" => $options];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementSelectorInputValue($selector, $trigger, array $element, WebformSubmissionInterface $webform_submission) {
-    if ($this->isOptionsOther()) {
-      $input_name = WebformSubmissionConditionsValidator::getSelectorInputName($selector);
-      $other_type = WebformSubmissionConditionsValidator::getInputNameAsArray($input_name, 1);
-      $value = $this->getRawValue($element, $webform_submission);
-
-      // Handle edge case where the other element's value has
-      // not been processed.
-      // @see https://www.drupal.org/project/webform/issues/3000202
-      /** @var \Drupal\webform\Element\WebformOtherBase $class */
-      $class = $this->getFormElementClassDefinition();
-      $type = $class::getElementType();
-      if (is_array($value) && count($value) === 2 && isset($value[$type]) && isset($value['other'])) {
-        $value = $class::processValue($element, $value);
-      }
-
-      $options = OptGroup::flattenOptions($element['#options']);
-      if ($other_type === 'other') {
-        if ($this->hasMultipleValues($element)) {
-          $other_value = array_diff($value, array_keys($options));
-          return ($other_value) ? implode(', ', $other_value) : NULL;
-        }
-        else {
-          // Make sure other value is not valid option.
-          return ($value && !isset($options[$value])) ? $value : NULL;
-        }
-      }
-      else {
-        if ($this->hasMultipleValues($element)) {
-          // Return array of valid #options.
-          return array_intersect($value, array_keys($options));
-        }
-        else {
-          // Return valid #option.
-          return (isset($options[$value])) ? $value : NULL;
-        }
-      }
-    }
-    else {
-      return parent::getElementSelectorInputValue($selector, $trigger, $element, $webform_submission);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function form(array $form, FormStateInterface $form_state) {
-    $form = parent::form($form, $form_state);
-
-    $form['default']['default_value']['#description'] .= ' ' . $this->t('The default value of the field identified by its key.');
-
-    // Issue #2836374: Wrapper attributes are not supported by composite
-    // elements, this includes radios, checkboxes, and buttons.
-    if (preg_match('/(radios|checkboxes|buttons)/', $this->getPluginId())) {
-      $t_args = [
-        '@name' => mb_strtolower($this->getPluginLabel()),
-        ':href' => 'https://www.drupal.org/node/2836364',
-      ];
-      $form['element_attributes']['#description'] = $this->t('Please note: That the below custom element attributes will also be applied to the @name fieldset wrapper. (<a href=":href">Issue #2836374</a>)', $t_args);
-    }
-    // Options.
-    $form['options'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Element options'),
-      '#open' => TRUE,
-    ];
-    $form['options']['options'] = [
-      '#type' => 'webform_element_options',
-      '#title' => $this->t('Options'),
-      '#options_description' => $this->hasProperty('options_description_display'),
-      '#required' => TRUE,
-    ];
-
-    $form['options']['options_display_container'] = $this->getFormInlineContainer();
-    $form['options']['options_display_container']['options_display'] = [
-      '#title' => $this->t('Options display'),
-      '#type' => 'select',
-      '#options' => [
-        'one_column' => $this->t('One column'),
-        'two_columns' => $this->t('Two columns'),
-        'three_columns' => $this->t('Three columns'),
-        'side_by_side' => $this->t('Side by side'),
-        'buttons' => $this->t('Buttons'),
-      ],
-    ];
-    $form['options']['options_display_container']['options_description_display'] = [
-      '#title' => $this->t('Options description display'),
-      '#type' => 'select',
-      '#options' => [
-        'description' => $this->t('Description'),
-        'help' => $this->t('Help text'),
-      ],
-    ];
-    $form['options']['empty_option'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Empty option label'),
-      '#description' => $this->t('The label to show for the initial option denoting no selection in a select element.'),
-      '#states' => [
-        'visible' => [
-          ':input[name="properties[multiple][container][cardinality]"]' => ['value' => 'number'],
-          ':input[name="properties[multiple][container][cardinality_number]"]' => ['value' => 1],
-        ],
-      ],
-    ];
-    $default_empty_option = $this->configFactory->get('webform.settings')->get('element.default_empty_option');
-    if ($default_empty_option) {
-      $default_empty_option_required = $this->configFactory->get('webform.settings')->get('element.default_empty_option_required') ?: $this->t('- Select -');
-      $form['options']['empty_option']['#description'] .= '<br />' . $this->t('Required elements defaults to: %required', ['%required' => $default_empty_option_required]);
-      $default_empty_option_optional = $this->configFactory->get('webform.settings')->get('element.default_empty_option_optional') ?: $this->t('- None -');
-      $form['options']['empty_option']['#description'] .= '<br />' . $this->t('Optional elements defaults to: %optional', ['%optional' => $default_empty_option_optional]);
-    }
-    $form['options']['empty_value'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Empty option value'),
-      '#description' => $this->t('The value for the initial option denoting no selection in a select element, which is used to determine whether the user submitted a value or not.'),
-      '#states' => [
-        'visible' => [
-          ':input[name="properties[multiple][container][cardinality]"]' => ['value' => 'number'],
-          ':input[name="properties[multiple][container][cardinality_number]"]' => ['value' => 1],
-        ],
-      ],
-    ];
-
-    $form['options']['options_randomize'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Randomize options'),
-      '#description' => $this->t('Randomizes the order of the options when they are displayed in the webform.'),
-      '#return_value' => TRUE,
-    ];
-
-    // Other.
-    $states_textfield_or_number = [
-      'visible' => [
-        [':input[name="properties[other__type]"]' => ['value' => 'textfield']],
-        'or',
-        [':input[name="properties[other__type]"]' => ['value' => 'number']],
-      ],
-    ];
-    $states_textbase = [
-      'visible' => [
-        [':input[name="properties[other__type]"]' => ['value' => 'textfield']],
-        'or',
-        [':input[name="properties[other__type]"]' => ['value' => 'textarea']],
-      ],
-    ];
-    $states_textarea = [
-      'visible' => [
-        ':input[name="properties[other__type]"]' => ['value' => 'textarea'],
-      ],
-    ];
-    $states_number = [
-      'visible' => [
-        ':input[name="properties[other__type]"]' => ['value' => 'number'],
-      ],
-    ];
-    $form['options_other'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Other option settings'),
-    ];
-    $form['options_other']['other__type'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Other type'),
-      '#options' => [
-        'textfield' => $this->t('Text field'),
-        'textarea' => $this->t('Textarea'),
-        'number' => $this->t('Number'),
-      ],
-    ];
-    $form['options_other']['other__option_label'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Other option label'),
-    ];
-    $form['options_other']['other__title'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Other title'),
-    ];
-    $form['options_other']['other__placeholder'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Other placeholder'),
-    ];
-    $form['options_other']['other__description'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Other description'),
-    ];
-
-    $form['options_other']['other__field_container'] = $this->getFormInlineContainer();
-    $form['options_other']['other__field_container']['other__field_prefix'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Other field prefix'),
-      '#description' => $this->t('Text or code that is placed directly in front of the input. This can be used to prefix an input with a constant string. Examples: $, #, -.'),
-      '#size' => 10,
-      '#states' => $states_textfield_or_number,
-    ];
-    $form['options_other']['other__field_container']['other__field_suffix'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Other field suffix'),
-      '#description' => $this->t('Text or code that is placed directly after the input. This can be used to add a unit to an input. Examples: lb, kg, %.'),
-      '#size' => 10,
-      '#states' => $states_textfield_or_number,
-    ];
-    $form['options_other']['other__size_container'] = $this->getFormInlineContainer();
-    $form['options_other']['other__size_container']['other__size'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Other size'),
-      '#description' => $this->t('Leaving blank will use the default size.'),
-      '#min' => 1,
-      '#size' => 4,
-      '#states' => $states_textfield_or_number,
-    ];
-    $form['options_other']['other__size_container']['other__maxlength'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Other maxlength'),
-      '#description' => $this->t('Leaving blank will use the default maxlength.'),
-      '#min' => 1,
-      '#size' => 4,
-      '#states' => $states_textfield_or_number,
-    ];
-    $form['options_other']['other__size_container']['other__rows'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Other rows'),
-      '#description' => $this->t('Leaving blank will use the default rows.'),
-      '#min' => 1,
-      '#size' => 4,
-      '#states' => $states_textarea,
-    ];
-
-    $form['options_other']['other__number_container'] = $this->getFormInlineContainer();
-    $form['options_other']['other__number_container']['other__min'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Other minimum'),
-      '#description' => $this->t('Specifies the minimum value.'),
-      '#step' => 'any',
-      '#size' => 4,
-      '#states' => $states_number,
-    ];
-    $form['options_other']['other__number_container']['other__max'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Other maximum'),
-      '#description' => $this->t('Specifies the maximum value.'),
-      '#step' => 'any',
-      '#size' => 4,
-      '#states' => $states_number,
-    ];
-    $form['options_other']['other__number_container']['other__step'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Other steps'),
-      '#description' => $this->t('Specifies the legal number intervals. Leave blank to support any number interval.'),
-      '#step' => 'any',
-      '#size' => 4,
-      '#states' => $states_number,
-    ];
-
-    $form['options_other']['other__textbase_container'] = [
-      '#type' => 'container',
-      '#states' => $states_textbase,
-    ] + $this->buildCounterForm('other__', 'Other count');
-
-    // Add hide/show #format_items based on #multiple.
-    if ($this->supportsMultipleValues() && $this->hasProperty('multiple')) {
-      $form['display']['format_items']['#states'] = [
-        'visible' => [
-          [':input[name="properties[multiple]"]' => ['checked' => TRUE]],
-        ],
-      ];
-    }
-
-    $form['options_properties'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Options (custom) properties'),
-      '#access' => $this->currentUser->hasPermission('edit webform source'),
-    ];
-    $form['options_properties']['options__properties'] = [
-      '#type' => 'webform_codemirror',
-      '#mode' => 'yaml',
-      '#title' => $this->t('Options properties'),
-      '#description' => $this->t("Custom options properties must include the 'Option value' followed by option (element) properties prepended with a hash (#) character.") .
-        "<pre>option_value:
-  '#wrapper_attributes':
-    class:
-      - disabled
-  '#disabled': true</pre>" .
-        '<br /><br />' .
-        $this->t('These properties and callbacks are not allowed: @properties', ['@properties' => WebformArrayHelper::toString(WebformArrayHelper::addPrefix(WebformElementHelper::$ignoredProperties))]),
-    ];
-
-    return $form;
-  }
-
-}
diff --git a/web/modules/webform/src/Plugin/WebformElement/ProcessedText.php b/web/modules/webform/src/Plugin/WebformElement/ProcessedText.php
index a5e0d8ff0e..a8e897a8d4 100644
--- a/web/modules/webform/src/Plugin/WebformElement/ProcessedText.php
+++ b/web/modules/webform/src/Plugin/WebformElement/ProcessedText.php
@@ -107,7 +107,7 @@ public function form(array $form, FormStateInterface $form_state) {
    */
   protected function setConfigurationFormDefaultValue(array &$form, array &$element_properties, array &$property_element, $property_name) {
     // Apply element.format to the text (text_format) element and unset it.
-    if ($property_name == 'text') {
+    if ($property_name === 'text') {
       $property_element['#format'] = $element_properties['format'];
       unset($element_properties['format']);
     }
@@ -119,7 +119,7 @@ protected function setConfigurationFormDefaultValue(array &$form, array &$elemen
    * {@inheritdoc}
    */
   protected function getConfigurationFormProperty(array &$properties, $property_name, $property_value, array $element) {
-    if ($property_name == 'text') {
+    if ($property_name === 'text') {
       $properties['text'] = $property_value['value'];
       $properties['format'] = $property_value['format'];
     }
diff --git a/web/modules/webform/src/Plugin/WebformElement/Radios.php b/web/modules/webform/src/Plugin/WebformElement/Radios.php
index 2167ac0f9a..38b04fe2f3 100644
--- a/web/modules/webform/src/Plugin/WebformElement/Radios.php
+++ b/web/modules/webform/src/Plugin/WebformElement/Radios.php
@@ -58,7 +58,7 @@ public function setDefaultValue(array &$element) {
     // Unset empty string as default option to prevent '' === '0' issue.
     // @see \Drupal\Core\Render\Element\Radio::preRenderRadio
     if (isset($element['#default_value'])
-      && $element['#default_value'] == ''
+      && $element['#default_value'] === ''
       && !isset($element['#options'][$element['#default_value']])) {
       unset($element['#default_value']);
     }
diff --git a/web/modules/webform/src/Plugin/WebformElement/Select.php b/web/modules/webform/src/Plugin/WebformElement/Select.php
index 41381a8a7d..a0bf3662f6 100644
--- a/web/modules/webform/src/Plugin/WebformElement/Select.php
+++ b/web/modules/webform/src/Plugin/WebformElement/Select.php
@@ -29,6 +29,7 @@ protected function defineDefaultProperties() {
       'multiple_error' => '',
       'empty_option' => '',
       'empty_value' => '',
+      'sort_options' => FALSE,
       'select2' => FALSE,
       'choices' => FALSE,
       'chosen' => FALSE,
diff --git a/web/modules/webform/src/Plugin/WebformElement/Telephone.php b/web/modules/webform/src/Plugin/WebformElement/Telephone.php
index a555fd5f47..8e62d10cfe 100644
--- a/web/modules/webform/src/Plugin/WebformElement/Telephone.php
+++ b/web/modules/webform/src/Plugin/WebformElement/Telephone.php
@@ -89,8 +89,8 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
 
     // Add support for telephone_validation.module.
     if (\Drupal::moduleHandler()->moduleExists('telephone_validation')) {
-      $format = $this->getElementProperty($element, 'telephone_validation_format');
-      if ($format == \libphonenumber\PhoneNumberFormat::NATIONAL) {
+      $format = (int) $this->getElementProperty($element, 'telephone_validation_format');
+      if ($format === \libphonenumber\PhoneNumberFormat::NATIONAL) {
         $country = (array) $this->getElementProperty($element, 'telephone_validation_country');
       }
       else {
diff --git a/web/modules/webform/src/Plugin/WebformElement/TextBase.php b/web/modules/webform/src/Plugin/WebformElement/TextBase.php
index 189d2d0cab..6de4c85efc 100644
--- a/web/modules/webform/src/Plugin/WebformElement/TextBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/TextBase.php
@@ -54,7 +54,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
       && $this->librariesManager->isIncluded('jquery.textcounter')) {
 
       // Apply character min/max to min/max length.
-      if ($element['#counter_type'] == 'character') {
+      if ($element['#counter_type'] === 'character') {
         if (!empty($element['#counter_minimum'])) {
           $element['#minlength'] = $element['#counter_minimum'];
         }
@@ -170,9 +170,9 @@ public function form(array $form, FormStateInterface $form_state) {
     $form['validation']['pattern'] = [
       '#type' => 'webform_checkbox_value',
       '#title' => $this->t('Pattern'),
-      '#description' => $this->t('A <a href=":href">regular expression</a> that the element\'s value is checked against.', [':href' => 'http://www.w3schools.com/js/js_regexp.asp']),
+      '#description' => $this->t('A <a href=":href">regular expression</a> that the element\'s value is checked against.', [':href' => 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions']),
       '#value__title' => $this->t('Pattern regular expression'),
-      '#value__description' => $this->t('Enter a <a href=":href">regular expression</a> that the element\'s value should match.', [':href' => 'http://www.w3schools.com/js/js_regexp.asp']),
+      '#value__description' => $this->t('Enter a <a href=":href">regular expression</a> that the element\'s value should match.', [':href' => 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions']),
       '#value__maxlength' => NULL,
     ];
     $form['validation']['pattern_error'] = [
@@ -217,7 +217,7 @@ public static function validateCounter(array &$element, FormStateInterface $form
     // Display error.
     // @see \Drupal\Core\Form\FormValidator::performRequiredValidation
     $t_args = [
-      '@type' => ($type == 'character') ? t('characters') : t('words'),
+      '@type' => ($type === 'character') ? t('characters') : t('words'),
       '@name' => $element['#title'],
       '%max' => $max,
       '%min' => $min,
diff --git a/web/modules/webform/src/Plugin/WebformElement/TextBase.php.orig b/web/modules/webform/src/Plugin/WebformElement/TextBase.php.orig
deleted file mode 100644
index d158369e9b..0000000000
--- a/web/modules/webform/src/Plugin/WebformElement/TextBase.php.orig
+++ /dev/null
@@ -1,438 +0,0 @@
-<?php
-
-namespace Drupal\webform\Plugin\WebformElement;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\webform\Plugin\WebformElementBase;
-use Drupal\webform\Utility\WebformElementHelper;
-use Drupal\webform\Utility\WebformHtmlHelper;
-use Drupal\webform\Utility\WebformTextHelper;
-use Drupal\webform\WebformSubmissionInterface;
-
-/**
- * Provides a base 'text' (field) class.
- */
-abstract class TextBase extends WebformElementBase {
-
-  use TextBaseTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function defineDefaultProperties() {
-    return [
-      'readonly' => FALSE,
-      'size' => NULL,
-      'minlength' => NULL,
-      'maxlength' => NULL,
-      'placeholder' => '',
-      'autocomplete' => 'on',
-      'pattern' => '',
-      'pattern_error' => '',
-    ] + parent::defineDefaultProperties();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function defineTranslatableProperties() {
-    return array_merge(parent::defineTranslatableProperties(), ['counter_minimum_message', 'counter_maximum_message', 'pattern_error']);
-  }
-
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
-    parent::prepare($element, $webform_submission);
-
-    // Counter.
-    if (!empty($element['#counter_type'])
-      && (!empty($element['#counter_minimum']) || !empty($element['#counter_maximum']))
-      && $this->librariesManager->isIncluded('jquery.textcounter')) {
-
-      // Apply character min/max to min/max length.
-      if ($element['#counter_type'] == 'character') {
-        if (!empty($element['#counter_minimum'])) {
-          $element['#minlength'] = $element['#counter_minimum'];
-        }
-        if (!empty($element['#counter_maximum'])) {
-          $element['#maxlength'] = $element['#counter_maximum'];
-        }
-      }
-
-      // Set 'data-counter-*' attributes using '#counter_*' properties.
-      $data_attributes = [
-        'counter_type',
-        'counter_minimum',
-        'counter_minimum_message',
-        'counter_maximum',
-        'counter_maximum_message',
-      ];
-      foreach ($data_attributes as $data_attribute) {
-        if (!empty($element['#' . $data_attribute])) {
-          $element['#attributes']['data-' . str_replace('_', '-', $data_attribute)] = $element['#' . $data_attribute];
-        }
-      }
-
-      $element['#attributes']['class'][] = 'js-webform-counter';
-      $element['#attributes']['class'][] = 'webform-counter';
-      $element['#attached']['library'][] = 'webform/webform.element.counter';
-
-      $element['#element_validate'][] = [get_class($this), 'validateCounter'];
-    }
-
-    // Input mask.
-    if (!empty($element['#input_mask']) && $this->librariesManager->isIncluded('jquery.inputmask')) {
-      // See if the element mask is JSON by looking for 'name':, else assume it
-      // is a mask pattern.
-      $input_mask = $element['#input_mask'];
-      if (preg_match("/^'[^']+'\s*:/", $input_mask)) {
-        $element['#attributes']['data-inputmask'] = $input_mask;
-      }
-      else {
-        $element['#attributes']['data-inputmask-mask'] = $input_mask;
-      }
-      // Set input mask #pattern.
-      $input_masks = $this->getInputMasks();
-      if (isset($input_masks[$input_mask])
-        && isset($input_masks[$input_mask]['pattern']) &&
-        empty($element['#pattern'])) {
-        $element['#pattern'] = $input_masks[$input_mask]['pattern'];
-      }
-
-      $element['#attributes']['class'][] = 'js-webform-input-mask';
-      $element['#attached']['library'][] = 'webform/webform.element.inputmask';
-      $element['#element_validate'][] = [get_called_class(), 'validateInputMask'];
-    }
-
-    // Input hiding.
-    if (!empty($element['#input_hide'])) {
-      $element['#attributes']['class'][] = 'js-webform-input-hide';
-      $element['#attached']['library'][] = 'webform/webform.element.inputhide';
-    }
-
-    // Pattern validation.
-    // This override core's pattern validation to support unicode
-    // and a custom error message.
-    if (isset($element['#pattern'])) {
-      $element['#attributes']['pattern'] = $element['#pattern'];
-      $element['#element_validate'][] = [get_called_class(), 'validatePattern'];
-
-      // Set pattern error message using #pattern_error.
-      // @see Drupal.behaviors.webformRequiredError
-      // @see webform.form.js
-      if (!empty($element['#pattern_error'])) {
-        $element['#attributes']['data-webform-pattern-error'] = WebformHtmlHelper::toPlainText($element['#pattern_error']);
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function form(array $form, FormStateInterface $form_state) {
-    $form = parent::form($form, $form_state);
-
-    // Input mask.
-    $form['form']['input_mask'] = [
-      '#type' => 'webform_select_other',
-      '#title' => $this->t('Input masks'),
-      '#description' => $this->t('An <a href=":href">inputmask</a> helps the user with the element by ensuring a predefined format.', [':href' => 'https://github.com/RobinHerbots/jquery.inputmask']),
-      '#other__option_label' => $this->t('Custom…'),
-      '#other__placeholder' => $this->t('Enter input mask…'),
-      '#other__description' => $this->t('(9 = numeric; a = alphabetical; * = alphanumeric)'),
-      '#empty_option' => $this->t('- None -'),
-      '#options' => $this->getInputMaskOptions(),
-    ];
-    if ($this->librariesManager->isExcluded('jquery.inputmask')) {
-      $form['form']['input_mask']['#access'] = FALSE;
-    }
-
-    // Input hiding.
-    $form['form']['input_hide'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Input hiding'),
-      '#description' => $this->t('Hide the input of the element when the input is not being focused.'),
-      '#return_value' => TRUE,
-    ];
-
-    // Pattern.
-    $form['validation']['pattern'] = [
-      '#type' => 'webform_checkbox_value',
-      '#title' => $this->t('Pattern'),
-      '#description' => $this->t('A <a href=":href">regular expression</a> that the element\'s value is checked against.', [':href' => 'http://www.w3schools.com/js/js_regexp.asp']),
-      '#value__title' => $this->t('Pattern regular expression'),
-      '#value__description' => $this->t('Enter a <a href=":href">regular expression</a> that the element\'s value should match.', [':href' => 'http://www.w3schools.com/js/js_regexp.asp']),
-      '#value__maxlength' => NULL,
-    ];
-    $form['validation']['pattern_error'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Pattern message'),
-      '#description' => $this->t('If set, this message will be used when a pattern is not matched, instead of the default "@message" message.', ['@message' => t('%name field is not in the right format.')]),
-      '#states' => [
-        'visible' => [
-          ':input[name="properties[pattern][checkbox]"]' => ['checked' => TRUE],
-        ],
-      ],
-    ];
-
-    // Counter.
-    $form['validation'] += $this->buildCounterForm();
-
-    if (isset($form['form']['maxlength'])) {
-      $form['form']['maxlength']['#description'] .= ' ' . $this->t('If character counter is enabled, maxlength will automatically be set to the count maximum.');
-      $form['form']['maxlength']['#states'] = [
-        'invisible' => [
-          ':input[name="properties[counter_type]"]' => ['value' => 'character'],
-        ],
-      ];
-    }
-
-    return $form;
-  }
-
-  /**
-   * Form API callback. Validate (word/character) counter.
-   */
-  public static function validateCounter(array &$element, FormStateInterface $form_state) {
-    $value = $element['#value'];
-    if ($value === '') {
-      return;
-    }
-
-    $type = $element['#counter_type'];
-    $max = (!empty($element['#counter_maximum'])) ? $element['#counter_maximum'] : NULL;
-    $min = (!empty($element['#counter_minimum'])) ? $element['#counter_minimum'] : NULL;
-
-    // Display error.
-    // @see \Drupal\Core\Form\FormValidator::performRequiredValidation
-    $t_args = [
-      '@type' => ($type == 'character') ? t('characters') : t('words'),
-      '@name' => $element['#title'],
-      '%max' => $max,
-      '%min' => $min,
-    ];
-
-    // Get character/word count.
-    if ($type === 'character') {
-      $length = mb_strlen($value);
-      $t_args['%length'] = $length;
-    }
-    // Validate word count.
-    elseif ($type === 'word') {
-      $length = WebformTextHelper::wordCount($value);
-      $t_args['%length'] = $length;
-    }
-
-    // Validate character/word count.
-    if ($max && $length > $max) {
-      $form_state->setError($element, t('@name cannot be longer than %max @type but is currently %length @type long.', $t_args));
-    }
-    elseif ($min && $length < $min) {
-      $form_state->setError($element, t('@name must be longer than %min @type but is currently %length @type long.', $t_args));
-    }
-  }
-
-  /**
-   * Form API callback. Validate input mask and display required error message.
-   *
-   * Makes sure a required element's value doesn't include the default
-   * input mask as the submitted value.
-   *
-   * Applies only to the currency input mask.
-   */
-  public static function validateInputMask(&$element, FormStateInterface $form_state, &$complete_form) {
-    // Set required error when input mask is submitted.
-    if (!empty($element['#required'])
-      && static::isDefaultInputMask($element, $element['#value'])) {
-      WebformElementHelper::setRequiredError($element, $form_state);
-    }
-  }
-
-  /**
-   * Check if an element's value is the input mask's default value.
-   *
-   * @param array $element
-   *   An element.
-   * @param string $value
-   *   A value.
-   *
-   * @return bool
-   *   TRUE if an element's value is the input mask's default value.
-   */
-  public static function isDefaultInputMask(array $element, $value) {
-    if (empty($element['#input_mask']) || $value === '') {
-      return FALSE;
-    }
-
-    $input_mask = $element['#input_mask'];
-    $input_masks = [
-      "'alias': 'currency'" => '$ 0.00',
-    ];
-    return (isset($input_masks[$input_mask]) && $input_masks[$input_mask] === $value) ? TRUE : FALSE;
-  }
-
-  /**
-   * Form API callback. Validate unicode pattern and display a custom error.
-   *
-   * @see https://www.drupal.org/project/drupal/issues/2633550
-   */
-  public static function validatePattern(&$element, FormStateInterface $form_state, &$complete_form) {
-    if ($element['#value'] !== '') {
-      // PHP: Convert JavaScript-escaped Unicode characters to PCRE
-      // escape sequence format.
-      // @see https://bytefreaks.net/programming-2/php-programming-2/php-convert-javascript-escaped-unicode-characters-to-html-hex-references˚
-      $pcre_pattern = preg_replace('/\\\\u([a-fA-F0-9]{4})/', '\\x{\\1}', $element['#pattern']);
-      $pattern = '{^(?:' . $pcre_pattern . ')$}u';
-      if (!preg_match($pattern, $element['#value'])) {
-        if (!empty($element['#pattern_error'])) {
-          $form_state->setError($element, WebformHtmlHelper::toHtmlMarkup($element['#pattern_error']));
-        }
-        else {
-          $form_state->setError($element, t('%name field is not in the right format.', ['%name' => $element['#title']]));
-        }
-      }
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
-    parent::validateConfigurationForm($form, $form_state);
-    $properties = $this->getConfigurationFormProperties($form, $form_state);
-
-    // Validate #pattern's regular expression.
-    // @see \Drupal\Core\Render\Element\FormElement::validatePattern
-    // @see http://stackoverflow.com/questions/4440626/how-can-i-validate-regex
-    if (!empty($properties['#pattern'])) {
-      set_error_handler('_webform_entity_element_validate_rendering_error_handler');
-
-      // PHP: Convert JavaScript-escaped Unicode characters to PCRE escape
-      // sequence format.
-      // @see https://bytefreaks.net/programming-2/php-programming-2/php-convert-javascript-escaped-unicode-characters-to-html-hex-references
-      $pcre_pattern = preg_replace('/\\\\u([a-fA-F0-9]{4})/', '\\x{\\1}', $properties['#pattern']);
-
-      if (preg_match('{^(?:' . $pcre_pattern . ')$}u', NULL) === FALSE) {
-        $form_state->setErrorByName('pattern', t('Pattern %pattern is not a valid regular expression.', ['%pattern' => $properties['#pattern']]));
-      }
-
-      set_error_handler('_drupal_error_handler');
-    }
-
-    // Validate #counter_maximum.
-    if (!empty($properties['#counter_type']) && empty($properties['#counter_maximum']) && empty($properties['#counter_minimum'])) {
-      $form_state->setErrorByName('counter_minimum', t('Counter minimum or maximum is required.'));
-      $form_state->setErrorByName('counter_maximum', t('Counter minimum or maximum is required.'));
-    }
-  }
-
-  /****************************************************************************/
-  // Input masks.
-  /****************************************************************************/
-
-  /**
-   * Get input masks.
-   *
-   * @return array
-   *   An associative array keyed my input mask contain input mask title,
-   *   example, and patterh.
-   */
-  protected function getInputMasks() {
-    $input_masks = [
-      "'alias': 'currency'" => [
-        'title' => $this->t('Currency'),
-        'example' => '$ 9.99',
-        'pattern' => '^\$ [0-9]{1,3}(,[0-9]{3})*.\d\d$',
-      ],
-      "'alias': 'datetime'" => [
-        'title' => $this->t('Date'),
-        'example' => '2007-06-09\'T\'17:46:21',
-      ],
-      "'alias': 'decimal'" => [
-        'title' => $this->t('Decimal'),
-        'example' => '1.234',
-        'pattern' => '^\d+(\.\d+)?$',
-      ],
-      "'alias': 'email'" => [
-        'title' => $this->t('Email'),
-        'example' => 'example@example.com',
-      ],
-      "'alias': 'ip'" => [
-        'title' => $this->t('IP address'),
-        'example' => '255.255.255.255',
-        'pattern' => '^\d\d\d\.\d\d\d\.\d\d\d\.\d\d\d$',
-      ],
-      '[9-]AAA-999' => [
-        'title' => $this->t('License plate'),
-        'example' => '[9-]AAA-999',
-      ],
-      "'alias': 'mac'" => [
-        'title' => $this->t('MAC address'),
-        'example' => '99-99-99-99-99-99',
-        'pattern' => '^\d\d-\d\d-\d\d-\d\d-\d\d-\d\d$',
-      ],
-      "'alias': 'percentage'" => [
-        'title' => $this->t('Percentage'),
-        'example' => '99 %',
-        'pattern' => '^\d+ %$',
-      ],
-      '(999) 999-9999' => [
-        'title' => $this->t('Phone'),
-        'example' => '(999) 999-9999',
-        'pattern' => '^\(\d\d\d\) \d\d\d-\d\d\d\d$',
-      ],
-      '999-99-9999' => [
-        'title' => $this->t('Social Security Number (SSN)'),
-        'example' => '999-99-9999',
-        'pattern' => '^\d\d\d-\d\d-\d\d\d\d$',
-      ],
-      "'alias': 'vin'" => [
-        'title' => $this->t('Vehicle identification number (VIN)'),
-        'example' => 'JA3AY11A82U020534',
-      ],
-      '99999[-9999]' => [
-        'title' => $this->t('ZIP Code'),
-        'example' => '99999[-9999]',
-        'pattern' => '^\d\d\d\d\d(-\d\d\d\d)?$',
-      ],
-      "'casing': 'upper'" => [
-        'title' => $this->t('Uppercase'),
-        'example' => 'UPPERCASE',
-      ],
-      "'casing': 'lower'" => [
-        'title' => $this->t('Lowercase'),
-        'example' => 'lowercase',
-      ],
-    ];
-
-    // Get input masks.
-    $modules = \Drupal::moduleHandler()->getImplementations('webform_element_input_masks');
-    foreach ($modules as $module) {
-      $input_masks += \Drupal::moduleHandler()->invoke($module, 'webform_element_input_masks');
-    }
-
-    // Alter input masks.
-    \Drupal::moduleHandler()->alter('webform_element_input_masks', $input_masks);
-
-    return $input_masks;
-  }
-
-  /**
-   * Get input masks as select menu options.
-   *
-   * @return array
-   *   An associative array of options.
-   */
-  protected function getInputMaskOptions() {
-    $input_masks = $this->getInputMasks();
-    $options = [];
-    foreach ($input_masks as $input_mask => $settings) {
-      $options[$input_mask] = $settings['title'] . (!empty($settings['example']) ? ' - ' . $settings['example'] : '');
-    }
-    return $options;
-  }
-
-}
diff --git a/web/modules/webform/src/Plugin/WebformElement/TextFormat.php b/web/modules/webform/src/Plugin/WebformElement/TextFormat.php
index 29aab249d0..d6fd56ee21 100644
--- a/web/modules/webform/src/Plugin/WebformElement/TextFormat.php
+++ b/web/modules/webform/src/Plugin/WebformElement/TextFormat.php
@@ -188,6 +188,13 @@ public static function preRenderFixTextFormatStates(array $element) {
     return $element;
   }
 
+  /**
+   * @inheritDoc
+   */
+  public static function trustedCallbacks() {
+    return array_merge(parent::trustedCallbacks(), ['preRenderFixTextFormatStates']);
+  }
+
   /**
    * {@inheritdoc}
    */
diff --git a/web/modules/webform/src/Plugin/WebformElement/View.php b/web/modules/webform/src/Plugin/WebformElement/View.php
index 63117e99a5..d57d270d8d 100644
--- a/web/modules/webform/src/Plugin/WebformElement/View.php
+++ b/web/modules/webform/src/Plugin/WebformElement/View.php
@@ -5,6 +5,7 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\views\Entity\View as ViewEntity;
 use Drupal\webform\Element\WebformMessage as WebformMessageElement;
+use Drupal\webform\Plugin\WebformElementDisplayOnInterface;
 
 /**
  * Provides a hidden 'view' element.
@@ -27,7 +28,7 @@ protected function defineDefaultProperties() {
       'name' => '',
       'display_id' => '',
       'arguments' => [],
-      'display_on' => static::DISPLAY_ON_BOTH,
+      'display_on' => WebformElementDisplayOnInterface::DISPLAY_ON_BOTH,
     ] + parent::defineDefaultProperties();
   }
 
@@ -70,7 +71,7 @@ public function form(array $form, FormStateInterface $form_state) {
       '#message_storage' => WebformMessageElement::STORAGE_SESSION,
       '#states' => [
         'visible' => [
-          ':input[name="properties[display_on]"]' => ['!value' => static::DISPLAY_ON_VIEW],
+          ':input[name="properties[display_on]"]' => ['!value' => WebformElementDisplayOnInterface::DISPLAY_ON_VIEW],
         ],
       ],
     ];
@@ -157,7 +158,7 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form
     $display_on = (!empty($properties['#display_on']))
       ? $properties['#display_on']
       : $this->getDefaultProperty('display_on');
-    if (in_array($display_on, [static::DISPLAY_ON_BOTH, static::DISPLAY_ON_FORM])) {
+    if (in_array($display_on, [WebformElementDisplayOnInterface::DISPLAY_ON_BOTH, WebformElementDisplayOnInterface::DISPLAY_ON_FORM])) {
       if (isset($display['display_options']['filters'])) {
         $filters = $display['display_options']['filters'];
       }
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformActions.php b/web/modules/webform/src/Plugin/WebformElement/WebformActions.php
index 7fd93db9f3..e35c65fbb4 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformActions.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformActions.php
@@ -111,10 +111,10 @@ public function form(array $form, FormStateInterface $form_state) {
       '#type' => 'fieldset',
       '#title' => $this->t('Buttons'),
     ];
-    $draft_enabled = ($webform->getSetting('draft') != WebformInterface::DRAFT_NONE);
+    $draft_enabled = ($webform->getSetting('draft') !== WebformInterface::DRAFT_NONE);
     $reset_enabled = $webform->getSetting('form_reset');
     $wizard_enabled = $webform->hasWizardPages();
-    $preview_enabled = ($webform->getSetting('preview') != DRUPAL_DISABLED);
+    $preview_enabled = ($webform->getSetting('preview') !== DRUPAL_DISABLED);
 
     $buttons = [
       'submit' => [
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformCheckboxesOther.php b/web/modules/webform/src/Plugin/WebformElement/WebformCheckboxesOther.php
index c68a54fcc1..26540911eb 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformCheckboxesOther.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformCheckboxesOther.php
@@ -18,6 +18,22 @@
  */
 class WebformCheckboxesOther extends Checkboxes implements WebformElementOtherInterface {
 
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineDefaultProperties() {
+    $properties = parent::defineDefaultProperties();
+    // Remove 'All of the above' options.
+    unset(
+      $properties['options_all'],
+      $properties['options_all_value'],
+      $properties['options_all_text']
+    );
+    return $properties;
+  }
+
+  /****************************************************************************/
+
   /**
    * {@inheritdoc}
    */
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformCompositeBase.php b/web/modules/webform/src/Plugin/WebformElement/WebformCompositeBase.php
index b11b243193..1d8b4aa661 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformCompositeBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformCompositeBase.php
@@ -7,7 +7,9 @@
 use Drupal\Core\Render\Element as RenderElement;
 use Drupal\Core\Render\Element;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\file\Entity\File;
 use Drupal\webform\Entity\WebformOptions;
+use Drupal\webform\Plugin\WebformElementAttachmentInterface;
 use Drupal\webform\Plugin\WebformElementComputedInterface;
 use Drupal\webform\Plugin\WebformElementEntityReferenceInterface;
 use Drupal\webform\Utility\WebformArrayHelper;
@@ -20,7 +22,7 @@
 /**
  * Provides a base for composite elements.
  */
-abstract class WebformCompositeBase extends WebformElementBase {
+abstract class WebformCompositeBase extends WebformElementBase implements WebformElementAttachmentInterface {
 
   /**
    * Composite elements defined in the webform composite form element.
@@ -511,7 +513,7 @@ protected function formatCompositeHtmlItems(array $element, WebformSubmissionInt
     $composite_elements = $this->getInitializedCompositeElement($element);
     foreach (RenderElement::children($composite_elements) as $composite_key) {
       $composite_element = $composite_elements[$composite_key];
-      $composite_title = (isset($composite_element['#title']) && $format != 'raw') ? $composite_element['#title'] : $composite_key;
+      $composite_title = (isset($composite_element['#title']) && $format !== 'raw') ? $composite_element['#title'] : $composite_key;
       $composite_value = $this->formatCompositeHtml($element, $webform_submission, ['composite_key' => $composite_key] + $options);
       if ($composite_value !== '') {
         $items[$composite_key] = [
@@ -547,7 +549,7 @@ protected function formatCompositeTextItems(array $element, WebformSubmissionInt
     foreach (RenderElement::children($composite_elements) as $composite_key) {
       $composite_element = $composite_elements[$composite_key];
 
-      $composite_title = (isset($composite_element['#title']) && $format != 'raw') ? $composite_element['#title'] : $composite_key;
+      $composite_title = (isset($composite_element['#title']) && $format !== 'raw') ? $composite_element['#title'] : $composite_key;
 
       $composite_value = $this->formatCompositeText($element, $webform_submission, ['composite_key' => $composite_key] + $options);
       if (is_array($composite_value)) {
@@ -735,7 +737,7 @@ public function buildExportHeader(array $element, array $options) {
         continue;
       }
 
-      if ($options['header_format'] == 'label' && !empty($composite_element['#title'])) {
+      if ($options['header_format'] === 'label' && !empty($composite_element['#title'])) {
         $header[] = $composite_element['#title'];
       }
       else {
@@ -753,7 +755,7 @@ public function buildExportRecord(array $element, WebformSubmissionInterface $we
     $value = $this->getValue($element, $webform_submission);
 
     if ($this->hasMultipleValues($element)) {
-      $element['#format'] = ($export_options['header_format'] == 'label') ? 'list' : 'raw';
+      $element['#format'] = ($export_options['header_format'] === 'label') ? 'list' : 'raw';
       $export_options['multiple_delimiter'] = PHP_EOL . '---' . PHP_EOL;
       return parent::buildExportRecord($element, $webform_submission, $export_options);
     }
@@ -766,7 +768,7 @@ public function buildExportRecord(array $element, WebformSubmissionInterface $we
         continue;
       }
 
-      if ($export_options['composite_element_item_format'] == 'label' && $composite_element['#type'] != 'textfield' && !empty($composite_element['#options'])) {
+      if ($export_options['composite_element_item_format'] === 'label' && $composite_element['#type'] !== 'textfield' && !empty($composite_element['#options'])) {
         $record[] = WebformOptionsHelper::getOptionText($value[$composite_key], $composite_element['#options']);
       }
       else {
@@ -1099,7 +1101,7 @@ protected function buildCompositeElementsTable(array $form, FormStateInterface $
         ];
       }
 
-      if ($type == 'tel') {
+      if ($type === 'tel') {
         $row['settings']['data'][$composite_key . '__type'] = [
           '#type' => 'select',
           '#title' => $this->t('@title type', $t_args),
@@ -1482,4 +1484,40 @@ public static function isSupportedElementType($type) {
     return TRUE;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getAttachments(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    $data = $webform_submission->getData();
+
+    // Get file ids.
+    $fids = [];
+    $composite_elements_managed_files = $this->getManagedFiles($element);
+    foreach ($composite_elements_managed_files as $composite_key) {
+      $fids = array_merge($fids, $this->getManagedFileIdsFromData($element, $data, $composite_key));
+    }
+
+    if (!$fids) {
+      return [];
+    }
+
+    // Get attachments.
+    $attachments = [];
+    $files = File::loadMultiple($fids);
+    foreach ($files as $file) {
+      $attachments[] = [
+        'filecontent' => file_get_contents($file->getFileUri()),
+        'filename' => $file->getFilename(),
+        'filemime' => $file->getMimeType(),
+        // File URIs that are not supported return FALSE, when this happens
+        // still use the file's URI as the file's path.
+        'filepath' => \Drupal::service('file_system')->realpath($file->getFileUri()) ?: $file->getFileUri(),
+        // URI is used when debugging or resending messages.
+        // @see \Drupal\webform\Plugin\WebformHandler\EmailWebformHandler::buildAttachments
+        '_fileurl' => file_create_url($file->getFileUri()),
+      ];
+    }
+    return $attachments;
+  }
+
 }
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformComputedBase.php b/web/modules/webform/src/Plugin/WebformElement/WebformComputedBase.php
index cd4a060944..086b1afdc8 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformComputedBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformComputedBase.php
@@ -27,7 +27,7 @@ protected function defineDefaultProperties() {
       // Element settings.
       'title' => '',
       // Markup settings.
-      'display_on' => static::DISPLAY_ON_BOTH,
+      'display_on' => WebformElementDisplayOnInterface::DISPLAY_ON_BOTH,
       // Description/Help.
       'help' => '',
       'help_title' => '',
@@ -73,7 +73,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
     parent::prepare($element, $webform_submission);
 
     // Hide element if it should not be displayed on 'form'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_FORM)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_FORM)) {
       $element['#access'] = FALSE;
     }
   }
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformDisplayOnTrait.php b/web/modules/webform/src/Plugin/WebformElement/WebformDisplayOnTrait.php
index 42ec456e25..a5ddba0cd0 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformDisplayOnTrait.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformDisplayOnTrait.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\webform\Plugin\WebformElement;
 
+use Drupal\webform\Plugin\WebformElementDisplayOnInterface;
 use Drupal\webform\WebformSubmissionInterface;
 
 /**
@@ -16,7 +17,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
     parent::prepare($element, $webform_submission);
 
     // Hide element if it should not be displayed on 'form'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_FORM)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_FORM)) {
       $element['#access'] = FALSE;
     }
   }
@@ -26,7 +27,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
    */
   public function buildHtml(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
     // Hide element if it should not be displayed on 'view'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_VIEW)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_VIEW)) {
       return [];
     }
 
@@ -38,7 +39,7 @@ public function buildHtml(array $element, WebformSubmissionInterface $webform_su
    */
   public function buildText(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
     // Hide element if it should not be displayed on 'view'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_VIEW)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_VIEW)) {
       return [];
     }
     return parent::buildText($element, $webform_submission, $options);
@@ -57,7 +58,7 @@ public function buildText(array $element, WebformSubmissionInterface $webform_su
    */
   protected function isDisplayOn(array $element, $display_on) {
     $element_display_on = (isset($element['#display_on'])) ? $element['#display_on'] : $this->getDefaultProperty('display_on');
-    return ($element_display_on == static::DISPLAY_ON_BOTH || $element_display_on == $display_on) ? TRUE : FALSE;
+    return ($element_display_on === WebformElementDisplayOnInterface::DISPLAY_ON_BOTH || $element_display_on === $display_on) ? TRUE : FALSE;
   }
 
   /**
@@ -71,12 +72,12 @@ protected function isDisplayOn(array $element, $display_on) {
    */
   protected function getDisplayOnOptions($none = FALSE) {
     $options = [
-      static::DISPLAY_ON_FORM => $this->t('form only'),
-      static::DISPLAY_ON_VIEW => $this->t('viewed submission only'),
-      static::DISPLAY_ON_BOTH => $this->t('both form and viewed submission'),
+      WebformElementDisplayOnInterface::DISPLAY_ON_FORM => $this->t('form only'),
+      WebformElementDisplayOnInterface::DISPLAY_ON_VIEW => $this->t('viewed submission only'),
+      WebformElementDisplayOnInterface::DISPLAY_ON_BOTH => $this->t('both form and viewed submission'),
     ];
     if ($none) {
-      $options[static::DISPLAY_ON_NONE] = $this->t('none');
+      $options[WebformElementDisplayOnInterface::DISPLAY_ON_NONE] = $this->t('none');
     }
     return $options;
   }
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformEntityOptionsTrait.php b/web/modules/webform/src/Plugin/WebformElement/WebformEntityOptionsTrait.php
index 8ddedc28a5..f44591766d 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformEntityOptionsTrait.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformEntityOptionsTrait.php
@@ -23,12 +23,24 @@ protected function defineDefaultProperties() {
       $properties['options'],
       $properties['options_description_display']
     );
-    if ($this->getPluginId() === 'webform_entity_radios') {
-      unset(
-        $properties['format_items'],
-        $properties['format_items_html'],
-        $properties['format_items_text']
-      );
+    switch ($this->getPluginId()) {
+      case 'webform_entity_checkboxes':
+        // Remove 'None of the above' options.
+        unset(
+          $properties['options_none'],
+          $properties['options_none_value'],
+          $properties['options_none_text']
+        );
+        break;
+
+      case 'webform_entity_radios':
+        // Remove format multiple items.
+        unset(
+          $properties['format_items'],
+          $properties['format_items_html'],
+          $properties['format_items_text']
+        );
+        break;
     }
     return $properties;
   }
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformEntityReferenceTrait.php b/web/modules/webform/src/Plugin/WebformElement/WebformEntityReferenceTrait.php
index 31635907c3..34272ce9fe 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformEntityReferenceTrait.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformEntityReferenceTrait.php
@@ -29,7 +29,7 @@ public function getRelatedTypes(array $element) {
     $elements = $this->elementManager->getInstances();
     foreach ($elements as $element_name => $element_instance) {
       // Skip self.
-      if ($plugin_id == $element_instance->getPluginId()) {
+      if ($plugin_id === $element_instance->getPluginId()) {
         continue;
       }
       if ($element_instance instanceof WebformElementEntityReferenceInterface) {
@@ -108,7 +108,7 @@ protected function formatTextItem(array $element, WebformSubmissionInterface $we
         return $entity->id();
 
       case 'breadcrumb':
-        if ($entity->getEntityTypeId() == 'taxonomy_term') {
+        if ($entity->getEntityTypeId() === 'taxonomy_term') {
           /** @var \Drupal\taxonomy\TermStorageInterface $taxonomy_storage */
           $taxonomy_storage = \Drupal::entityTypeManager()->getStorage('taxonomy_term');
           $parents = $taxonomy_storage->loadAllParents($entity->id());
@@ -262,7 +262,7 @@ public function buildExportHeader(array $element, array $options) {
     if (!$this->hasMultipleValues($element)) {
       $default_options = $this->getExportDefaultOptions();
       $header = isset($options['entity_reference_items']) ? $options['entity_reference_items'] : $default_options['entity_reference_items'];
-      if ($options['header_format'] == 'label') {
+      if ($options['header_format'] === 'label') {
         foreach ($header as $index => $column) {
           switch ($column) {
             case 'id':
@@ -342,7 +342,7 @@ public function buildExportRecord(array $element, WebformSubmissionInterface $we
       return $record;
     }
     else {
-      if ($entity_reference_items == ['id']) {
+      if ($entity_reference_items === ['id']) {
         $element['#format'] = 'raw';
       }
       return parent::buildExportRecord($element, $webform_submission, $export_options);
@@ -369,6 +369,11 @@ protected function setOptions(array &$element, array $settings = []) {
     }
 
     WebformEntityTrait::setOptions($element, $settings);
+
+    // Set options all after entity options are defined.
+    if (!empty($element['#options_all'])) {
+      $element['#options'][$element['#options_all_value']] = $element['#options_all_text'];
+    }
   }
 
   /**
@@ -442,7 +447,7 @@ public function form(array $form, FormStateInterface $form_state) {
       $selection_settings = (!empty($user_input['properties']['selection_settings'])) ? $user_input['properties']['selection_settings'] : [];
       // If the default selection handler has changed when need to update its
       // value.
-      if (strpos($selection_handler, 'default:') === 0 && $selection_handler != "default:$target_type") {
+      if (strpos($selection_handler, 'default:') === 0 && $selection_handler !== "default:$target_type") {
         $selection_handler = "default:$target_type";
         $selection_settings = [];
         NestedArray::setValue($form_state->getUserInput(), ['properties', 'selection_handler'], $selection_handler);
@@ -467,9 +472,9 @@ public function form(array $form, FormStateInterface $form_state) {
     // "Warning: Invalid argument supplied for foreach()
     // in Drupal\Core\Render\Element\Checkboxes::valueCallback()"
     // @see \Drupal\user\Plugin\EntityReferenceSelection\UserSelection::buildConfigurationForm
-    if ($target_type == 'user'
+    if ($target_type === 'user'
       && isset($selection_settings['filter']['type'])
-      && $selection_settings['filter']['type'] == 'role'
+      && $selection_settings['filter']['type'] === 'role'
       && empty($selection_settings['filter']['role'])) {
       $selection_settings['filter']['role'] = [];
     }
@@ -544,7 +549,7 @@ public function form(array $form, FormStateInterface $form_state) {
     );
 
     // Remove auto create, except for entity_autocomplete.
-    if ($this->getPluginId() != 'entity_autocomplete' || $target_type != 'taxonomy_term') {
+    if ($this->getPluginId() !== 'entity_autocomplete' || $target_type !== 'taxonomy_term') {
       unset(
         $form['entity_reference']['selection_settings']['auto_create'],
         $form['entity_reference']['selection_settings']['auto_create_bundle']
@@ -608,7 +613,7 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form
     if (isset($values['selection_settings']['target_bundles']) && empty($values['selection_settings']['target_bundles'])) {
       unset($values['selection_settings']['target_bundles']);
     }
-    if (isset($values['selection_settings']['sort']['field']) && $values['selection_settings']['sort']['field'] == '_none') {
+    if (isset($values['selection_settings']['sort']['field']) && $values['selection_settings']['sort']['field'] === '_none') {
       unset($values['selection_settings']['sort']);
     }
     // Convert auto_create and include_anonymous into boolean.
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformFlexbox.php b/web/modules/webform/src/Plugin/WebformElement/WebformFlexbox.php
index 5edb22e6d6..d05ad56ab9 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformFlexbox.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformFlexbox.php
@@ -11,7 +11,7 @@
  * @WebformElement(
  *   id = "webform_flexbox",
  *   default_key = "flexbox",
- *   api = "http://www.w3schools.com/css/css3_flexbox.asp",
+ *   api = "https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox",
  *   label = @Translation("Flexbox layout"),
  *   description = @Translation("Provides a flex(ible) box container used to layout elements in multiple columns."),
  *   category = @Translation("Containers"),
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformHorizontalRule.php b/web/modules/webform/src/Plugin/WebformElement/WebformHorizontalRule.php
index 28748379bb..df4df436f9 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformHorizontalRule.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformHorizontalRule.php
@@ -31,7 +31,7 @@ protected function defineDefaultProperties() {
       'states' => [],
       'attributes' => [],
       // Markup settings.
-      'display_on' => static::DISPLAY_ON_FORM,
+      'display_on' => WebformElementDisplayOnInterface::DISPLAY_ON_FORM,
     ];
   }
 
@@ -58,7 +58,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
     parent::prepare($element, $webform_submission);
 
     // Hide element if it should not be displayed on 'form'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_FORM)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_FORM)) {
       $element['#access'] = FALSE;
     }
   }
@@ -68,7 +68,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
    */
   public function buildHtml(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
     // Hide element if it should not be displayed on 'view'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_VIEW)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_VIEW)) {
       return [];
     }
 
@@ -80,7 +80,7 @@ public function buildHtml(array $element, WebformSubmissionInterface $webform_su
    */
   public function buildText(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
     // Hide element if it should not be displayed on 'view'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_VIEW)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_VIEW)) {
       return [];
     }
 
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformImageFile.php b/web/modules/webform/src/Plugin/WebformElement/WebformImageFile.php
index e452302cd2..a7480bc256 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformImageFile.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformImageFile.php
@@ -180,7 +180,9 @@ public function getAttachments(array $element, WebformSubmissionInterface $webfo
         'filecontent' => file_get_contents($file_uri),
         'filename' => $file->getFilename(),
         'filemime' => $file->getMimeType(),
-        'filepath' => \Drupal::service('file_system')->realpath($file_uri),
+        // File URIs that are not supported return FALSE, when this happens
+        // still use the file's URI as the file's path.
+        'filepath' => \Drupal::service('file_system')->realpath($file->getFileUri()) ?: $file->getFileUri(),
         // URL is used when debugging or resending messages.
         // @see \Drupal\webform\Plugin\WebformHandler\EmailWebformHandler::buildAttachments
         '_fileurl' => $file_url,
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformLikert.php b/web/modules/webform/src/Plugin/WebformElement/WebformLikert.php
index 462089967a..99d2942967 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformLikert.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformLikert.php
@@ -144,7 +144,7 @@ protected function formatHtmlItem(array $element, WebformSubmissionInterface $we
           ];
           foreach ($element['#answers'] as $answer_value => $answer_text) {
             $row[$answer_value] = [
-              'data' => ($question_value == $answer_value) ? ['#markup' => '&#10007;'] : '',
+              'data' => ($question_value === $answer_value) ? ['#markup' => '&#10007;'] : '',
               'align' => 'center',
               'width' => $width,
             ];
@@ -261,7 +261,7 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
   public function buildExportHeader(array $element, array $options) {
     $header = [];
     foreach ($element['#questions'] as $key => $label) {
-      $header[] = ($options['header_format'] == 'key') ? $key : $label;
+      $header[] = ($options['header_format'] === 'key') ? $key : $label;
     }
     return $this->prefixExportHeader($header, $element, $options);
   }
@@ -275,7 +275,7 @@ public function buildExportRecord(array $element, WebformSubmissionInterface $we
     $record = [];
     foreach ($element['#questions'] as $question_key => $question_label) {
       $answer_value = (isset($value[$question_key])) ? $value[$question_key] : NULL;
-      if ($export_options['likert_answers_format'] == 'key') {
+      if ($export_options['likert_answers_format'] === 'key') {
         $record[] = $answer_value;
       }
       else {
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformLocationBase.php b/web/modules/webform/src/Plugin/WebformElement/WebformLocationBase.php
index 6e468b38a5..2a9f8a5c5c 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformLocationBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformLocationBase.php
@@ -46,7 +46,7 @@ protected function defineDefaultProperties() {
     foreach ($composite_elements as $composite_key => $composite_element) {
       $properties[$composite_key . '__title'] = (string) $composite_element['#title'];
       // The value is always visible and supports a custom placeholder.
-      if ($composite_key == 'value') {
+      if ($composite_key === 'value') {
         $properties[$composite_key . '__placeholder'] = '';
       }
       else {
@@ -65,7 +65,7 @@ public function initialize(array &$element) {
     // Hide all composite elements by default.
     $composite_elements = $this->getCompositeElements();
     foreach ($composite_elements as $composite_key => $composite_element) {
-      if ($composite_key != 'value' && !isset($element['#' . $composite_key . '__access'])) {
+      if ($composite_key !== 'value' && !isset($element['#' . $composite_key . '__access'])) {
         $element['#' . $composite_key . '__access'] = FALSE;
       }
     }
@@ -82,7 +82,7 @@ public function form(array $form, FormStateInterface $form_state) {
     $form['composite']['geolocation'] = [
       '#type' => 'checkbox',
       '#title' => $this->t("Use the browser's Geolocation as the default value"),
-      '#description' => $this->t('The <a href="http://www.w3schools.com/html/html5_geolocation.asp">HTML Geolocation API</a> is used to get the geographical position of a user. Since this can compromise privacy, the position is not available unless the user approves it.'),
+      '#description' => $this->t('The <a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API">HTML Geolocation API</a> is used to get the geographical position of a user. Since this can compromise privacy, the position is not available unless the user approves it.'),
       '#return_value' => TRUE,
     ];
     $form['composite']['hidden'] = [
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformManagedFileBase.php b/web/modules/webform/src/Plugin/WebformElement/WebformManagedFileBase.php
index 2379fd2264..11b48c02a2 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformManagedFileBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformManagedFileBase.php
@@ -295,14 +295,22 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
     if ($file_limit) {
       $element_validate[] = [get_class($this), 'validateManagedFileLimit'];
     }
-    // NOTE: Using array_splice() to make sure that self::validateManagedFile
+    // NOTE: Using array_splice() to make sure that static::validateManagedFile
     // is executed before all other validation hooks are executed but after
     // \Drupal\file\Element\ManagedFile::validateManagedFile.
     array_splice($element['#element_validate'], 1, 0, $element_validate);
 
     // Upload validators.
+    // @see webform_preprocess_file_upload_help
     $element['#upload_validators']['file_validate_size'] = [$this->getMaxFileSize($element)];
     $element['#upload_validators']['file_validate_extensions'] = [$this->getFileExtensions($element)];
+    // Define 'webform_file_validate_extensions' which allows file
+    // extensions within webforms to be comma-delimited. The
+    // 'webform_file_validate_extensions' will be ignored by file_validate().
+    // @see file_validate()
+    // Issue #3136578: Comma-separate the list of allowed file extensions.
+    // @see https://www.drupal.org/project/drupal/issues/3136578
+    $element['#upload_validators']['webform_file_validate_extensions'] = [];
     $element['#upload_validators']['webform_file_validate_name_length'] = [];
 
     // Add file upload help to the element as #description, #help, or #more.
@@ -662,7 +670,9 @@ protected function getMaxFileSize(array $element) {
    *   File extensions.
    */
   protected function getFileExtensions(array $element = NULL) {
-    return (!empty($element['#file_extensions'])) ? $element['#file_extensions'] : $this->getDefaultFileExtensions();
+    $extensions = (!empty($element['#file_extensions'])) ? $element['#file_extensions'] : $this->getDefaultFileExtensions();
+    $extensions = str_replace(',', ' ', $extensions);
+    return $extensions;
   }
 
   /**
@@ -812,7 +822,7 @@ public static function processManagedFile(&$element, FormStateInterface $form_st
       $preview_element = ['#format' => $element['#file_preview']] + $element;
 
       // Convert '#theme': file_link to a container with a file preview.
-      $fids = (array) $webform_submission->getElementData($element['#webform_key']) ?: [];
+      $fids = (isset($element['#webform_key'])) ? (array) $webform_submission->getElementData($element['#webform_key']) : [];
       foreach ($fids as $delta => $fid) {
         $child_key = 'file_' . $fid;
         // Make sure the child element exists.
@@ -1089,7 +1099,7 @@ public function form(array $form, FormStateInterface $form_state) {
     $form['file']['file_extensions'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Allowed file extensions'),
-      '#description' => $this->t('Separate extensions with a space and do not include the leading dot.') . '<br/><br/>' .
+      '#description' => $this->t('Separate extensions with a space or comma and do not include the leading dot.') . '<br/><br/>' .
         $this->t('Defaults to: %value', ['%value' => $this->getDefaultFileExtensions()]),
       '#maxlength' => 255,
     ];
@@ -1256,7 +1266,7 @@ public function addFiles(array $element, WebformSubmissionInterface $webform_sub
       $destination_uri = $this->getFileDestinationUri($element, $file, $webform_submission);
 
       // Save file if there is a new destination URI.
-      if ($source_uri != $destination_uri) {
+      if ($source_uri !== $destination_uri) {
         $destination_uri = $this->fileSystem->move($source_uri, $destination_uri);
         $file->setFileUri($destination_uri);
         $file->setFileName($this->fileSystem->basename($destination_uri));
@@ -1377,7 +1387,7 @@ public static function accessFileDownload($uri) {
     $usage = $file_usage->listUsage($file);
     foreach ($usage as $module => $entity_types) {
       // Check for Webform module.
-      if ($module != 'webform') {
+      if ($module !== 'webform') {
         continue;
       }
 
@@ -1385,7 +1395,7 @@ public static function accessFileDownload($uri) {
         $entity_ids = array_keys($counts);
 
         // Check for webform submission entity type.
-        if ($entity_type != 'webform_submission' || empty($entity_ids)) {
+        if ($entity_type !== 'webform_submission' || empty($entity_ids)) {
           continue;
         }
 
@@ -1474,7 +1484,7 @@ public function getAttachments(array $element, WebformSubmissionInterface $webfo
         'filecontent' => file_get_contents($file->getFileUri()),
         'filename' => $file->getFilename(),
         'filemime' => $file->getMimeType(),
-        // File URIs that are not supportted return FALSE, when this happens
+        // File URIs that are not supported return FALSE, when this happens
         // still use the file's URI as the file's path.
         'filepath' => \Drupal::service('file_system')->realpath($file->getFileUri()) ?: $file->getFileUri(),
         // URI is used when debugging or resending messages.
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformMapping.php b/web/modules/webform/src/Plugin/WebformElement/WebformMapping.php
index 0aeff62e95..0c242ee824 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformMapping.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformMapping.php
@@ -244,7 +244,7 @@ public function preview() {
   public function buildExportHeader(array $element, array $options) {
     $header = [];
     foreach ($element['#source'] as $key => $label) {
-      $header[] = ($options['header_format'] == 'key') ? $key : $label;
+      $header[] = ($options['header_format'] === 'key') ? $key : $label;
     }
     return $this->prefixExportHeader($header, $element, $options);
   }
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformMarkupBase.php b/web/modules/webform/src/Plugin/WebformElement/WebformMarkupBase.php
index e6047a1798..0e09570320 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformMarkupBase.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformMarkupBase.php
@@ -20,7 +20,7 @@ abstract class WebformMarkupBase extends WebformElementBase implements WebformEl
   protected function defineDefaultProperties() {
     return [
       // Markup settings.
-      'display_on' => static::DISPLAY_ON_FORM,
+      'display_on' => WebformElementDisplayOnInterface::DISPLAY_ON_FORM,
     ] + $this->defineDefaultBaseProperties();
   }
 
@@ -59,7 +59,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
     parent::prepare($element, $webform_submission);
 
     // Hide element if it should not be displayed on 'form'.
-    if ($this->hasProperty('display_on') && !$this->isDisplayOn($element, static::DISPLAY_ON_FORM)) {
+    if ($this->hasProperty('display_on') && !$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_FORM)) {
       $element['#access'] = FALSE;
     }
 
@@ -74,7 +74,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
    */
   public function buildHtml(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
     // Hide element if it should not be displayed on 'view'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_VIEW)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_VIEW)) {
       return [];
     }
 
@@ -99,7 +99,7 @@ public function buildHtml(array $element, WebformSubmissionInterface $webform_su
    */
   public function buildText(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
     // Hide element if it should not be displayed on 'view'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_VIEW)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_VIEW)) {
       return [];
     }
 
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformMore.php b/web/modules/webform/src/Plugin/WebformElement/WebformMore.php
index 17a4d4adb4..30208d2f59 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformMore.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformMore.php
@@ -3,6 +3,7 @@
 namespace Drupal\webform\Plugin\WebformElement;
 
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\webform\Plugin\WebformElementDisplayOnInterface;
 
 /**
  * Provides a 'item' element.
@@ -25,7 +26,7 @@ protected function defineDefaultProperties() {
       'more' => '',
       'attributes' => [],
       // Markup settings.
-      'display_on' => static::DISPLAY_ON_FORM,
+      'display_on' => WebformElementDisplayOnInterface::DISPLAY_ON_FORM,
     ] + $this->defineDefaultBaseProperties();
   }
 
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformSame.php b/web/modules/webform/src/Plugin/WebformElement/WebformSame.php
index 9edf94a551..5dc3cbd3af 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformSame.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformSame.php
@@ -46,7 +46,6 @@ public function form(array $form, FormStateInterface $form_state) {
     $form = parent::form($form, $form_state);
 
     // Get element's as options.
-    // @todo Add more element types that should ignored.
     $ignored_types = [
       'webform_same',
     ];
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformSection.php b/web/modules/webform/src/Plugin/WebformElement/WebformSection.php
index e75c014e04..2da5fb5355 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformSection.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformSection.php
@@ -31,6 +31,7 @@ protected function defineDefaultProperties() {
       // Title.
       'title_tag' => \Drupal::config('webform.settings')->get('element.default_section_title_tag'),
       'title_display' => '',
+      'title_attributes' => [],
       'help_display' => '',
     ] + parent::defineDefaultProperties();
   }
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformSignature.php b/web/modules/webform/src/Plugin/WebformElement/WebformSignature.php
index f48779122d..4b99f87d20 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformSignature.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformSignature.php
@@ -228,7 +228,7 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
    * {@inheritdoc}
    */
   public function buildExportRecord(array $element, WebformSubmissionInterface $webform_submission, array $export_options) {
-    $element['#format'] = ($export_options['signature_format'] == 'status') ? 'image' : 'raw';
+    $element['#format'] = ($export_options['signature_format'] === 'status') ? 'image' : 'raw';
     return [$this->formatText($element, $webform_submission, $export_options)];
   }
 
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformTermSelect.php b/web/modules/webform/src/Plugin/WebformElement/WebformTermSelect.php
index 4f7d79814c..8a2f6c5afa 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformTermSelect.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformTermSelect.php
@@ -34,7 +34,8 @@ protected function defineDefaultProperties() {
     ] + parent::defineDefaultProperties();
     unset(
       $properties['options'],
-      $properties['options_randomize']
+      $properties['options_randomize'],
+      $properties['sort_options']
     );
     return $properties;
   }
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformTime.php b/web/modules/webform/src/Plugin/WebformElement/WebformTime.php
index 97e3c53b45..f5d6076b8f 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformTime.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformTime.php
@@ -11,7 +11,7 @@
  *
  * @WebformElement(
  *   id = "webform_time",
- *   api = "http://www.w3schools.com/tags/tag_time.asp",
+ *   api = "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time",
  *   label = @Translation("Time"),
  *   description = @Translation("Provides a form element for time selection."),
  *   category = @Translation("Date/time elements"),
@@ -64,7 +64,7 @@ protected function formatTextItem(array $element, WebformSubmissionInterface $we
     }
 
     $format = $this->getItemFormat($element);
-    if ($format == 'value') {
+    if ($format === 'value') {
       $time_format = (isset($element['#time_format'])) ? $element['#time_format'] : 'H:i';
       return static::formatTime($time_format, strtotime($value));
     }
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformVariant.php b/web/modules/webform/src/Plugin/WebformElement/WebformVariant.php
index de646ae64b..8575b89987 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformVariant.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformVariant.php
@@ -55,7 +55,7 @@ protected function defineDefaultProperties() {
       'variant' => '',
       'prepopulate' => TRUE,
       'randomize' => FALSE,
-      'display_on' => static::DISPLAY_ON_NONE,
+      'display_on' => WebformElementDisplayOnInterface::DISPLAY_ON_NONE,
     ] + $this->defineDefaultBaseProperties();
     unset(
       $properties['states'],
@@ -89,7 +89,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
     parent::prepare($element, $webform_submission);
 
     // Hide element if it should not be displayed on 'form'.
-    if ($this->hasProperty('display_on') && !$this->isDisplayOn($element, static::DISPLAY_ON_FORM)) {
+    if ($this->hasProperty('display_on') && !$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_FORM)) {
       $element['#access'] = FALSE;
     }
 
@@ -104,7 +104,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
    */
   public function buildHtml(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
     // Hide element if it should not be displayed on 'view'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_VIEW)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_VIEW)) {
       return [];
     }
 
@@ -116,7 +116,7 @@ public function buildHtml(array $element, WebformSubmissionInterface $webform_su
    */
   public function buildText(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
     // Hide element if it should not be displayed on 'view'.
-    if (!$this->isDisplayOn($element, static::DISPLAY_ON_VIEW)) {
+    if (!$this->isDisplayOn($element, WebformElementDisplayOnInterface::DISPLAY_ON_VIEW)) {
       return [];
     }
 
@@ -222,9 +222,9 @@ public function form(array $form, FormStateInterface $form_state) {
     ];
     $display_on_form_states = [
       'visible' => [
-        [':input[name="properties[display_on]"]' => ['value' => static::DISPLAY_ON_FORM]],
+        [':input[name="properties[display_on]"]' => ['value' => WebformElementDisplayOnInterface::DISPLAY_ON_FORM]],
         'or',
-       [':input[name="properties[display_on]"]' => ['value' => static::DISPLAY_ON_BOTH]],
+       [':input[name="properties[display_on]"]' => ['value' => WebformElementDisplayOnInterface::DISPLAY_ON_BOTH]],
       ],
     ];
     $form['element_description']['#states'] = $display_on_form_states;
@@ -235,9 +235,9 @@ public function form(array $form, FormStateInterface $form_state) {
 
     $display_on_view_states = [
       'visible' => [
-        [':input[name="properties[display_on]"]' => ['value' => static::DISPLAY_ON_VIEW]],
+        [':input[name="properties[display_on]"]' => ['value' => WebformElementDisplayOnInterface::DISPLAY_ON_VIEW]],
         'or',
-       [':input[name="properties[display_on]"]' => ['value' => static::DISPLAY_ON_BOTH]],
+       [':input[name="properties[display_on]"]' => ['value' => WebformElementDisplayOnInterface::DISPLAY_ON_BOTH]],
       ],
     ];
     $form['display']['#states'] = $display_on_view_states;
diff --git a/web/modules/webform/src/Plugin/WebformElement/WebformWizardPage.php b/web/modules/webform/src/Plugin/WebformElement/WebformWizardPage.php
index f268d05add..bb994527d2 100644
--- a/web/modules/webform/src/Plugin/WebformElement/WebformWizardPage.php
+++ b/web/modules/webform/src/Plugin/WebformElement/WebformWizardPage.php
@@ -16,6 +16,7 @@
  *   label = @Translation("Wizard page"),
  *   description = @Translation("Provides an element to display multiple form elements as a page in a multi-step form wizard."),
  *   category = @Translation("Wizard"),
+ *   hidden = TRUE,
  * )
  */
 class WebformWizardPage extends Details implements WebformElementWizardPageInterface {
@@ -29,6 +30,8 @@ protected function defineDefaultProperties() {
       'open' => FALSE,
       'prev_button_label' => '',
       'next_button_label' => '',
+      // Attributes.
+      'attributes' => [],
       // Submission display.
       'format' => $this->getItemDefaultFormat(),
       'format_html' => '',
@@ -114,13 +117,13 @@ public function form(array $form, FormStateInterface $form_state) {
       '#type' => 'textfield',
       '#title' => $this->t('Previous page button label'),
       '#description' => $this->t('This is used for the Next Page button on the page before this page break.') . '<br /><br />' .
-      $this->t('Defaults to: %value', ['%value' => $this->getDefaultSettings($webform, 'wizard_prev_button_label')]),
+      $this->t('Defaults to: %value', ['%value' => $webform->getSetting('wizard_prev_button_label', TRUE)]),
     ];
     $form['wizard_page']['next_button_label'] = [
       '#type' => 'textfield',
       '#title' => $this->t('Next page button label'),
       '#description' => $this->t('This is used for the Previous Page button on the page after this page break.') . '<br /><br />' .
-      $this->t('Defaults to: %value', ['%value' => $this->getDefaultSettings($webform, 'wizard_next_button_label')]),
+      $this->t('Defaults to: %value', ['%value' => $webform->getSetting('wizard_next_button_label', TRUE)]),
     ];
 
     // Wizard pages only support visible or hidden state.
@@ -139,9 +142,12 @@ public function form(array $form, FormStateInterface $form_state) {
    *
    * @return string
    *   The setting's value.
+   *
+   * @deprecated Scheduled for removal in Webform 8.x-6.x
+   *   Use \Drupal\webform\Webform::getSetting instead.
    */
   protected function getDefaultSettings(WebformInterface $webform, $name) {
-    return $webform->getSetting($name) ?: \Drupal::config('webform.settings')->get("settings.default_$name");
+    return $webform->getSetting($name, TRUE);
   }
 
   /**
diff --git a/web/modules/webform/src/Plugin/WebformElementBase.php b/web/modules/webform/src/Plugin/WebformElementBase.php
index fa0f88e8ae..d359c52482 100644
--- a/web/modules/webform/src/Plugin/WebformElementBase.php
+++ b/web/modules/webform/src/Plugin/WebformElementBase.php
@@ -15,7 +15,7 @@
 use Drupal\Core\Messenger\MessengerTrait;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Render\ElementInfoManagerInterface;
-use Drupal\Core\Render\Markup;
+use Drupal\Core\Security\TrustedCallbackInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Url;
@@ -51,7 +51,7 @@
  * @see \Drupal\webform\Plugin\WebformElementManagerInterface
  * @see plugin_api
  */
-class WebformElementBase extends PluginBase implements WebformElementInterface {
+class WebformElementBase extends PluginBase implements WebformElementInterface, TrustedCallbackInterface {
 
   use StringTranslationTrait;
   use MessengerTrait;
@@ -108,7 +108,7 @@ class WebformElementBase extends PluginBase implements WebformElementInterface {
   protected $tokenManager;
 
   /**
-   * The libraries manager.
+   * The webform libraries manager.
    *
    * @var \Drupal\webform\WebformLibrariesManagerInterface
    */
@@ -270,6 +270,7 @@ protected function defineDefaultMultipleProperties() {
       'multiple__add_more_button_label' => (string) $this->t('Add'),
       'multiple__add_more_input' => TRUE,
       'multiple__add_more_input_label' => (string) $this->t('more items'),
+      'multiple__item_label' => (string) $this->t('item'),
       'multiple__no_items_message' => (string) $this->t('No items entered. Please add items below.'),
       'multiple__sorting' => TRUE,
       'multiple__operations' => TRUE,
@@ -612,12 +613,12 @@ public function isMultiline(array $element) {
     }
 
     // Check if custom items template has HTML block tags.
-    if ($items_format == 'custom' && isset($element['#format_items_html']) && WebformHtmlHelper::hasBlockTags($element['#format_items_html'])) {
+    if ($items_format === 'custom' && isset($element['#format_items_html']) && WebformHtmlHelper::hasBlockTags($element['#format_items_html'])) {
       return TRUE;
     }
 
     // Check if custom item template has HTML block tags.
-    if ($item_format == 'custom' && isset($element['#format_html']) && WebformHtmlHelper::hasBlockTags($element['#format_html'])) {
+    if ($item_format === 'custom' && isset($element['#format_html']) && WebformHtmlHelper::hasBlockTags($element['#format_html'])) {
       return TRUE;
     }
 
@@ -686,7 +687,7 @@ public function getRelatedTypes(array $element) {
     $elements = $this->elementManager->getInstances();
     foreach ($elements as $element_name => $element_instance) {
       // Skip self.
-      if ($plugin_id == $element_instance->getPluginId()) {
+      if ($plugin_id === $element_instance->getPluginId()) {
         continue;
       }
 
@@ -697,18 +698,18 @@ public function getRelatedTypes(array $element) {
 
       // Compare element base (abstract) class.
       $element_instance_parent_classes = WebformReflectionHelper::getParentClasses($element_instance, 'WebformElementBase');
-      if ($parent_classes[1] != $element_instance_parent_classes[1]) {
+      if ($parent_classes[1] !== $element_instance_parent_classes[1]) {
         continue;
       }
 
       // Compare container, supports/has multiple values, and multiline.
-      if ($is_container != $element_instance->isContainer($element)) {
+      if ($is_container !== $element_instance->isContainer($element)) {
         continue;
       }
-      if ($has_multiple_values != $element_instance->hasMultipleValues($element)) {
+      if ($has_multiple_values !== $element_instance->hasMultipleValues($element)) {
         continue;
       }
-      if ($is_multiline != $element_instance->isMultiline($element)) {
+      if ($is_multiline !== $element_instance->isMultiline($element)) {
         continue;
       }
 
@@ -792,7 +793,7 @@ public function prepare(array &$element, WebformSubmissionInterface $webform_sub
     // Add inline title display support.
     // Inline fieldset layout is handled via webform_preprocess_fieldset().
     // @see webform_preprocess_fieldset()
-    if (isset($element['#title_display']) && $element['#title_display'] == 'inline') {
+    if (isset($element['#title_display']) && $element['#title_display'] === 'inline') {
       // Store reference to unset #title_display.
       $element['#_title_display'] = $element['#title_display'];
       unset($element['#title_display']);
@@ -1908,7 +1909,7 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
    * {@inheritdoc}
    */
   public function buildExportHeader(array $element, array $export_options) {
-    if ($export_options['header_format'] == 'label') {
+    if ($export_options['header_format'] === 'label') {
       return [$this->getAdminLabel($element)];
     }
     else {
@@ -1934,7 +1935,7 @@ protected function prefixExportHeader(array $header, array $element, array $expo
       return $header;
     }
 
-    if ($export_options['header_format'] == 'label') {
+    if ($export_options['header_format'] === 'label') {
       $prefix = $this->getAdminLabel($element) . $export_options['header_prefix_label_delimiter'];
     }
     else {
@@ -2079,7 +2080,7 @@ public static function validateUniqueMultiple(array &$element, FormStateInterfac
     }
 
     // Compare number of values to unique number of values.
-    if (count($value) != count(array_unique($value))) {
+    if (count($value) !== count(array_unique($value))) {
       $duplicates = WebformArrayHelper::getDuplicates($value);
 
       if (isset($element['#unique_error'])) {
@@ -2759,7 +2760,7 @@ public function form(array $form, FormStateInterface $form_state) {
     $form['flex'] = [
       '#type' => 'details',
       '#title' => $this->t('Flexbox item'),
-      '#description' => $this->t('Learn more about using <a href=":href">flexbox layouts</a>.', [':href' => 'http://www.w3schools.com/css/css3_flexbox.asp']),
+      '#description' => $this->t('Learn more about using <a href=":href">flexbox layouts</a>.', [':href' => 'https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox']),
     ];
     $flex_range = range(0, 12);
     $form['flex']['flex'] = [
@@ -2862,6 +2863,11 @@ public function form(array $form, FormStateInterface $form_state) {
       '#title' => $this->t('Table header label'),
       '#description' => $this->t('This is used as the table header for this webform element when displaying multiple values.'),
     ];
+    $form['multiple']['multiple__item_label'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Item label'),
+      '#description' => $this->t('This is used by the add/remove (+/-) icons.'),
+    ];
     $form['multiple']['multiple__no_items_message'] = [
       '#type' => 'webform_html_editor',
       '#title' => $this->t('No items message'),
@@ -3032,6 +3038,20 @@ public function form(array $form, FormStateInterface $form_state) {
       '#attributes__description' => $this->t("Enter additional attributes to be added to the details' summary."),
     ];
 
+    /* Title attributes */
+
+    $form['title_attributes'] = [
+      '#type' => 'details',
+      '#title' => $this->t('Title attributes'),
+    ];
+    $form['title_attributes']['title_attributes'] = [
+      '#type' => 'webform_element_attributes',
+      '#title' => $this->t('Title'),
+      '#class__description' => $this->t("Apply classes to the title tag."),
+      '#style__description' => $this->t("Apply custom styles to the  title tag."),
+      '#attributes__description' => $this->t("Enter additional attributes to be added to the title tag."),
+    ];
+
     /* Submission display */
     $has_edit_twig_access = WebformTwigExtension::hasEditTwigAccess();
 
@@ -3311,7 +3331,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
 
     // Set fieldset weights so that they appear first.
     foreach ($form as &$element) {
-      if (is_array($element) && !isset($element['#weight']) && isset($element['#type']) && $element['#type'] == 'fieldset') {
+      if (is_array($element) && !isset($element['#weight']) && isset($element['#type']) && $element['#type'] === 'fieldset') {
         $element['#weight'] = -20;
       }
     }
@@ -3407,6 +3427,7 @@ protected function buildConfigurationFormTabs(array $form, FormStateInterface $f
           'element_attributes',
           'label_attributes',
           'summary_attributes',
+          'title_attributes',
           'display',
           'admin',
           'options_properties',
@@ -3450,7 +3471,7 @@ protected function setConfigurationFormDefaultValueRecursive(array &$form, array
       // Skip Entity reference element 'selection_settings'.
       // @see \Drupal\webform\Plugin\WebformElement\WebformEntityReferenceTrait::form
       // @todo Fix entity reference Ajax and move code WebformEntityReferenceTrait.
-      if (!empty($property_element['#tree']) && $property_name == 'selection_settings') {
+      if (!empty($property_element['#tree']) && $property_name === 'selection_settings') {
         unset($element_properties[$property_name]);
         $property_element['#parents'] = ['properties', $property_name];
         $has_input = TRUE;
@@ -3532,13 +3553,13 @@ protected function setConfigurationFormDefaultValue(array &$form, array &$elemen
       default:
         // Convert default_value array into a comma delimited list.
         // This is applicable to elements that support #multiple #options.
-        if (is_array($default_value) && $property_name == 'default_value' && !$this->isComposite()) {
+        if (is_array($default_value) && $property_name === 'default_value' && !$this->isComposite()) {
           $property_element['#default_value'] = implode(', ', $default_value);
         }
-        elseif (is_bool($default_value) && $property_name == 'default_value') {
+        elseif (is_bool($default_value) && $property_name === 'default_value') {
           $property_element['#default_value'] = $default_value ? 1 : 0;
         }
-        elseif (is_null($default_value) && $property_name == 'default_value') {
+        elseif (is_null($default_value) && $property_name === 'default_value') {
           $property_element['#default_value'] = (string) $default_value;
         }
         else {
@@ -3561,7 +3582,7 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form
     $ignored_properties = WebformElementHelper::getIgnoredProperties($properties);
     foreach ($ignored_properties as $ignored_property => $ignored_message) {
       // Display custom messages.
-      if ($ignored_property != $ignored_message) {
+      if ($ignored_property !== $ignored_message) {
         unset($ignored_properties[$ignored_property]);
         $form_state->setErrorByName('custom', $ignored_message);
       }
@@ -3675,7 +3696,7 @@ public function getConfigurationFormProperties(array &$form, FormStateInterface
    *   The element whose properties are being updated.
    */
   protected function getConfigurationFormProperty(array &$properties, $property_name, $property_value, array $element) {
-    if ($property_name == 'default_value' && is_string($property_value) && $property_value && $this->hasMultipleValues($element)) {
+    if ($property_name === 'default_value' && is_string($property_value) && $property_value && $this->hasMultipleValues($element)) {
       $properties[$property_name] = preg_split('/\s*,\s*/', $property_value);
     }
   }
@@ -3697,4 +3718,11 @@ protected function hasCompositeFormElementWrapper() {
     return FALSE;
   }
 
+  /**
+   * @inheritDoc
+   */
+  public static function trustedCallbacks() {
+    return ['preRenderFixStatesWrapper', 'preRenderFixFlexboxWrapper', 'preRenderWebformCompositeFormElement'];
+  }
+
 }
diff --git a/web/modules/webform/src/Plugin/WebformElementBase.php.orig b/web/modules/webform/src/Plugin/WebformElementBase.php.orig
deleted file mode 100644
index 907fa0fd14..0000000000
--- a/web/modules/webform/src/Plugin/WebformElementBase.php.orig
+++ /dev/null
@@ -1,3700 +0,0 @@
-<?php
-
-namespace Drupal\webform\Plugin;
-
-use Drupal\Component\Plugin\PluginBase;
-use Drupal\Component\Utility\NestedArray;
-use Drupal\Component\Utility\Xss;
-use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Form\OptGroup;
-use Drupal\Core\Link;
-use Drupal\Core\Messenger\MessengerTrait;
-use Drupal\Core\Render\Element;
-use Drupal\Core\Render\ElementInfoManagerInterface;
-use Drupal\Core\Render\Markup;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\Core\Url;
-use Drupal\webform\Element\WebformCompositeFormElementTrait;
-use Drupal\webform\Element\WebformHtmlEditor;
-use Drupal\webform\Element\WebformMessage;
-use Drupal\webform\Entity\WebformOptions;
-use Drupal\webform\Plugin\WebformElement\Checkbox;
-use Drupal\webform\Plugin\WebformElement\Checkboxes;
-use Drupal\webform\Plugin\WebformElement\ContainerBase;
-use Drupal\webform\Plugin\WebformElement\Details;
-use Drupal\webform\Plugin\WebformElement\WebformCompositeBase;
-use Drupal\webform\Twig\WebformTwigExtension;
-use Drupal\webform\Utility\WebformArrayHelper;
-use Drupal\webform\Utility\WebformElementHelper;
-use Drupal\webform\Utility\WebformFormHelper;
-use Drupal\webform\Utility\WebformHtmlHelper;
-use Drupal\webform\Utility\WebformOptionsHelper;
-use Drupal\webform\Utility\WebformReflectionHelper;
-use Drupal\webform\WebformInterface;
-use Drupal\webform\WebformLibrariesManagerInterface;
-use Drupal\webform\WebformSubmissionConditionsValidator;
-use Drupal\webform\WebformSubmissionInterface;
-use Drupal\webform\WebformTokenManagerInterface;
-use Psr\Log\LoggerInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Provides a base class for a webform element.
- *
- * @see \Drupal\webform\Plugin\WebformElementInterface
- * @see \Drupal\webform\Plugin\WebformElementManager
- * @see \Drupal\webform\Plugin\WebformElementManagerInterface
- * @see plugin_api
- */
-class WebformElementBase extends PluginBase implements WebformElementInterface {
-
-  use StringTranslationTrait;
-  use MessengerTrait;
-  use WebformCompositeFormElementTrait;
-  use WebformEntityInjectionTrait;
-
-  /**
-   * A logger instance.
-   *
-   * @var \Psr\Log\LoggerInterface
-   */
-  protected $logger;
-
-  /**
-   * The configuration factory.
-   *
-   * @var \Drupal\Core\Config\ConfigFactoryInterface
-   */
-  protected $configFactory;
-
-  /**
-   * The current user.
-   *
-   * @var \Drupal\Core\Session\AccountInterface
-   */
-  protected $currentUser;
-
-  /**
-   * The entity type manager.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
-   */
-  protected $entityTypeManager;
-
-  /**
-   * A element info manager.
-   *
-   * @var \Drupal\Core\Render\ElementInfoManagerInterface
-   */
-  protected $elementInfo;
-
-  /**
-   * The webform element manager.
-   *
-   * @var \Drupal\webform\Plugin\WebformElementManagerInterface
-   */
-  protected $elementManager;
-
-  /**
-   * The token manager.
-   *
-   * @var \Drupal\webform\WebformTokenManagerInterface
-   */
-  protected $tokenManager;
-
-  /**
-   * The libraries manager.
-   *
-   * @var \Drupal\webform\WebformLibrariesManagerInterface
-   */
-  protected $librariesManager;
-
-  /**
-   * The webform submission storage.
-   *
-   * @var \Drupal\webform\WebformSubmissionStorageInterface
-   */
-  protected $submissionStorage;
-
-  /**
-   * An associative array of an element's default properties names and values.
-   *
-   * @var array
-   */
-  protected $defaultProperties;
-
-  /**
-   * An indexed array of an element's translated properties.
-   *
-   * @var array
-   */
-  protected $translatableProperties;
-
-  /**
-   * Constructs a WebformElementBase object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Psr\Log\LoggerInterface $logger
-   *   A logger instance.
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
-   *   The configuration factory.
-   * @param \Drupal\Core\Session\AccountInterface $current_user
-   *   The current user.
-   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
-   *   The entity type manager.
-   * @param \Drupal\Core\Render\ElementInfoManagerInterface $element_info
-   *   The element info manager.
-   * @param \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager
-   *   The webform element manager.
-   * @param \Drupal\webform\WebformTokenManagerInterface $token_manager
-   *   The webform token manager.
-   * @param \Drupal\webform\WebformLibrariesManagerInterface $libraries_manager
-   *   The webform libraries manager.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, LoggerInterface $logger, ConfigFactoryInterface $config_factory, AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager, ElementInfoManagerInterface $element_info, WebformElementManagerInterface $element_manager, WebformTokenManagerInterface $token_manager, WebformLibrariesManagerInterface $libraries_manager) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->logger = $logger;
-    $this->configFactory = $config_factory;
-    $this->currentUser = $current_user;
-    $this->entityTypeManager = $entity_type_manager;
-    $this->elementInfo = $element_info;
-    $this->elementManager = $element_manager;
-    $this->tokenManager = $token_manager;
-    $this->librariesManager = $libraries_manager;
-    $this->submissionStorage = $entity_type_manager->getStorage('webform_submission');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('logger.factory')->get('webform'),
-      $container->get('config.factory'),
-      $container->get('current_user'),
-      $container->get('entity_type.manager'),
-      $container->get('plugin.manager.element_info'),
-      $container->get('plugin.manager.webform.element'),
-      $container->get('webform.token_manager'),
-      $container->get('webform.libraries_manager')
-    );
-  }
-
-  /****************************************************************************/
-  // Property definitions.
-  /****************************************************************************/
-
-  /**
-   * Define an element's default properties.
-   *
-   * @return array
-   *   An associative array contain an the element's default properties.
-   */
-  protected function defineDefaultProperties() {
-    $properties = [
-      // Element settings.
-      'title' => '',
-      'default_value' => '',
-      // Description/Help.
-      'help' => '',
-      'help_title' => '',
-      'description' => '',
-      'more' => '',
-      'more_title' => '',
-      // Form display.
-      'title_display' => '',
-      'description_display' => '',
-      'help_display' => '',
-      'field_prefix' => '',
-      'field_suffix' => '',
-      'disabled' => FALSE,
-      // Form validation.
-      'required' => FALSE,
-      'required_error' => '',
-      // Attributes.
-      'wrapper_attributes' => [],
-      'label_attributes' => [],
-      'attributes' => [],
-      // Submission display.
-      'format' => $this->getItemDefaultFormat(),
-      'format_html' => '',
-      'format_text' => '',
-      'format_items' => $this->getItemsDefaultFormat(),
-      'format_items_html' => '',
-      'format_items_text' => '',
-      'format_attributes' => [],
-    ];
-
-    // Unique validation.
-    if (!$this->isComposite()) {
-      $properties += [
-        'unique' => FALSE,
-        'unique_user' => FALSE,
-        'unique_entity' => FALSE,
-        'unique_error' => '',
-      ];
-    }
-
-    $properties += $this->defineDefaultBaseProperties();
-
-    return $properties;
-  }
-
-  /**
-   * Define default multiple properties used by most elements.
-   *
-   * @return array
-   *   An associative array containing default multiple properties.
-   */
-  protected function defineDefaultMultipleProperties() {
-    return [
-      'multiple' => FALSE,
-      'multiple__header_label' => '',
-      'multiple__min_items' => NULL,
-      'multiple__empty_items' => 1,
-      'multiple__add_more' => TRUE,
-      'multiple__add_more_items' => 1,
-      'multiple__add_more_button_label' => (string) $this->t('Add'),
-      'multiple__add_more_input' => TRUE,
-      'multiple__add_more_input_label' => (string) $this->t('more items'),
-      'multiple__no_items_message' => (string) $this->t('No items entered. Please add items below.'),
-      'multiple__sorting' => TRUE,
-      'multiple__operations' => TRUE,
-    ];
-  }
-
-  /**
-   * Define default base properties used by all elements.
-   *
-   * @return array
-   *   An associative array containing base properties used by all elements.
-   */
-  protected function defineDefaultBaseProperties() {
-    return [
-      // Administration.
-      'admin_title' => '',
-      'prepopulate' => FALSE,
-      'private' => FALSE,
-      // Flexbox.
-      'flex' => 1,
-      // Conditional logic.
-      'states' => [],
-      'states_clear' => TRUE,
-      // Element access.
-      'access_create_roles' => ['anonymous', 'authenticated'],
-      'access_create_users' => [],
-      'access_create_permissions' => [],
-      'access_update_roles' => ['anonymous', 'authenticated'],
-      'access_update_users' => [],
-      'access_update_permissions' => [],
-      'access_view_roles' => ['anonymous', 'authenticated'],
-      'access_view_users' => [],
-      'access_view_permissions' => [],
-    ];
-  }
-
-  /**
-   * Define an element's translatable properties.
-   *
-   * @return array
-   *   An array containing an element's translatable properties.
-   */
-  protected function defineTranslatableProperties() {
-    return [
-      'title',
-      'label',
-      'help',
-      'help_title',
-      'more',
-      'more_title',
-      'description',
-      'field_prefix',
-      'field_suffix',
-      'required_error',
-      'unique_error',
-      'admin_title',
-      'placeholder',
-      'markup',
-      'test',
-      'default_value',
-      'header_label',
-      'add_more_button_label',
-      'add_more_input_label',
-      'no_items_message',
-    ];
-  }
-
-  /****************************************************************************/
-  // Property methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDefaultProperties() {
-    if (!isset($this->defaultProperties)) {
-      $properties = $this->defineDefaultProperties();
-      $definition = $this->getPluginDefinition();
-      \Drupal::moduleHandler()->alter(
-        'webform_element_default_properties',
-        $properties,
-        $definition
-      );
-      $this->defaultProperties = $properties;
-    }
-    return $this->defaultProperties;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTranslatableProperties() {
-    if (!isset($this->translatableProperties)) {
-      $properties = $this->defineTranslatableProperties();
-      $definition = $this->getPluginDefinition();
-      \Drupal::moduleHandler()->alter(
-        'webform_element_translatable_properties',
-        $properties,
-        $definition
-      );
-      $this->translatableProperties = array_unique($properties);
-    }
-    return $this->translatableProperties;
-  }
-
-  /**
-   * Get default multiple properties used by most elements.
-   *
-   * @return array
-   *   An associative array containing default multiple properties.
-   *
-   * @deprecated Scheduled for removal in Webform 8.x-6.x
-   *   Use \Drupal\webform\Plugin\WebformElementBase::defineDefaultBaseProperties instead.
-   */
-  protected function getDefaultMultipleProperties() {
-    @trigger_error('\Drupal\webform\Plugin\WebformElementBase::getDefaultMultipleProperties is scheduled for removal in Webform 8.x-6.x. Use \Drupal\webform\Plugin\WebformElementBase::defineDefaultBaseProperties instead.', E_USER_DEPRECATED);
-    return $this->defineDefaultBaseProperties();
-  }
-
-  /**
-   * Get default base properties used by all elements.
-   *
-   * @return array
-   *   An associative array containing base properties used by all elements.
-   *
-   * @deprecated Scheduled for removal in Webform 8.x-6.x
-   *   Use \Drupal\webform\Plugin\WebformElementBase::defineDefaultBaseProperties instead.
-   */
-  protected function getDefaultBaseProperties() {
-    @trigger_error('\Drupal\webform\Plugin\WebformElementBase::getDefaultBaseProperties is scheduled for removal in Webform 8.x-6.x. Use \Drupal\webform\Plugin\WebformElementBase::defineDefaultBaseProperties instead.', E_USER_DEPRECATED);
-    return $this->defineDefaultBaseProperties();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasProperty($property_name) {
-    $default_properties = $this->getDefaultProperties();
-    return array_key_exists($property_name, $default_properties);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDefaultProperty($property_name) {
-    $default_properties = $this->getDefaultProperties();
-    return (array_key_exists($property_name, $default_properties)) ? $default_properties[$property_name] : NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementProperty(array $element, $property_name) {
-    return (isset($element["#$property_name"])) ? $element["#$property_name"] : $this->getDefaultProperty($property_name);
-  }
-
-  /**
-   * Set element's default callback.
-   *
-   * This makes sure that an element's default callback is not clobbered by
-   * any additional callbacks.
-   *
-   * @param array $element
-   *   A render element.
-   * @param string $callback_name
-   *   A render element's callback.
-   */
-  protected function setElementDefaultCallback(array &$element, $callback_name) {
-    $callback_name = ($callback_name[0] !== '#') ? '#' . $callback_name : $callback_name;
-    $callback_value = $this->getElementInfoDefaultProperty($element, $callback_name) ?: [];
-    if (!empty($element[$callback_name])) {
-      $element[$callback_name] = array_merge($callback_value, $element[$callback_name]);
-    }
-    else {
-      $element[$callback_name] = $callback_value;
-    }
-  }
-
-  /**
-   * Get a render element's default property.
-   *
-   * @param array $element
-   *   A render element.
-   * @param string $property_name
-   *   An element's property name.
-   *
-   * @return mixed
-   *   A render element's default value, or NULL if
-   *   property does not exist.
-   */
-  protected function getElementInfoDefaultProperty(array $element, $property_name) {
-    if (!isset($element['#type'])) {
-      return NULL;
-    }
-    $property_name = ($property_name[0] !== '#') ? '#' . $property_name : $property_name;
-    $type = $element['#type'];
-    return $this->elementInfo->getInfoProperty($type, $property_name, NULL)
-      ?: $this->elementInfo->getInfoProperty("webform_$type", $property_name, NULL);
-  }
-
-  /****************************************************************************/
-  // Definition and meta data methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormElementClassDefinition() {
-    $definition = $this->elementInfo->getDefinition($this->getBaseId());
-    return $definition['class'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPluginApiUrl() {
-    return (!empty($this->pluginDefinition['api'])) ? Url::fromUri($this->pluginDefinition['api']) : NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPluginApiLink() {
-    $api_url = $this->getPluginApiUrl();
-    return ($api_url) ? Link::fromTextAndUrl($this->getPluginLabel(), $api_url) : NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPluginLabel() {
-    return $this->pluginDefinition['label'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPluginDescription() {
-    return $this->pluginDefinition['description'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPluginCategory() {
-    return $this->pluginDefinition['category'] ?: $this->t('Other elements');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTypeName() {
-    return $this->pluginDefinition['id'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDefaultKey() {
-    return (isset($this->pluginDefinition['default_key'])) ? $this->pluginDefinition['default_key'] : NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isInput(array $element) {
-    return (!empty($element['#type'])) ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasWrapper(array $element) {
-    return $this->hasProperty('wrapper_attributes');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isContainer(array $element) {
-    return ($this->isInput($element)) ? FALSE : TRUE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isRoot() {
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasManagedFiles(array $element) {
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function supportsMultipleValues() {
-    return $this->hasProperty('multiple');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasMultipleWrapper() {
-    return TRUE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasMultipleValues(array $element) {
-    if ($this->hasProperty('multiple')) {
-      if (isset($element['#multiple'])) {
-        return $element['#multiple'];
-      }
-      else {
-        $default_property = $this->getDefaultProperties();
-        return $default_property['multiple'];
-      }
-    }
-    else {
-      return FALSE;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isMultiline(array $element) {
-    $item_format = $this->getItemFormat($element);
-    $items_format = $this->getItemsFormat($element);
-
-    // Check is multi value element.
-    if ($this->hasMultipleValues($element) && in_array($items_format, ['ol', 'ul', 'hr', 'custom'])) {
-      return TRUE;
-    }
-
-    // Check if custom items template has HTML block tags.
-    if ($items_format == 'custom' && isset($element['#format_items_html']) && WebformHtmlHelper::hasBlockTags($element['#format_items_html'])) {
-      return TRUE;
-    }
-
-    // Check if custom item template has HTML block tags.
-    if ($item_format == 'custom' && isset($element['#format_html']) && WebformHtmlHelper::hasBlockTags($element['#format_html'])) {
-      return TRUE;
-    }
-
-    return $this->pluginDefinition['multiline'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isComposite() {
-    return $this->pluginDefinition['composite'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isHidden() {
-    return $this->pluginDefinition['hidden'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isExcluded() {
-    return $this->configFactory->get('webform.settings')->get('element.excluded_elements.' . $this->pluginDefinition['id']) ? TRUE : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isEnabled() {
-    return !$this->isExcluded();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isDisabled() {
-    return !$this->isEnabled();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getInfo() {
-    return $this->elementInfo->getInfo($this->getBaseId());
-  }
-
-  /****************************************************************************/
-  // Element relationship methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRelatedTypes(array $element) {
-    $types = [];
-
-    $parent_classes = WebformReflectionHelper::getParentClasses($this, 'WebformElementBase');
-
-    $plugin_id = $this->getPluginId();
-    $is_container = $this->isContainer($element);
-    $has_multiple_values = $this->hasMultipleValues($element);
-    $is_multiline = $this->isMultiline($element);
-
-    $elements = $this->elementManager->getInstances();
-    foreach ($elements as $element_name => $element_instance) {
-      // Skip self.
-      if ($plugin_id == $element_instance->getPluginId()) {
-        continue;
-      }
-
-      // Skip disabled or hidden.
-      if ($element_instance->isDisabled() || $element_instance->isHidden()) {
-        continue;
-      }
-
-      // Compare element base (abstract) class.
-      $element_instance_parent_classes = WebformReflectionHelper::getParentClasses($element_instance, 'WebformElementBase');
-      if ($parent_classes[1] != $element_instance_parent_classes[1]) {
-        continue;
-      }
-
-      // Compare container, supports/has multiple values, and multiline.
-      if ($is_container != $element_instance->isContainer($element)) {
-        continue;
-      }
-      if ($has_multiple_values != $element_instance->hasMultipleValues($element)) {
-        continue;
-      }
-      if ($is_multiline != $element_instance->isMultiline($element)) {
-        continue;
-      }
-
-      $types[$element_name] = $element_instance->getPluginLabel();
-    }
-
-    asort($types);
-    return $types;
-  }
-
-  /****************************************************************************/
-  // Element rendering methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function initialize(array &$element) {
-    // Set element options.
-    if (isset($element['#options'])) {
-      $element['#options'] = WebformOptions::getElementOptions($element);
-    }
-
-    // Set #admin_title to #title without any HTML markup.
-    if (!empty($element['#title']) && empty($element['#admin_title'])) {
-      $element['#admin_title'] = strip_tags($element['#title']);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function prepare(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
-    $attributes_property = ($this->hasWrapper($element)) ? '#wrapper_attributes' : '#attributes';
-    if ($webform_submission) {
-      // Add webform and webform_submission IDs to every element.
-      $element['#webform'] = $webform_submission->getWebform()->id();
-      $element['#webform_submission'] = $webform_submission->id();
-
-      // Check is the element is disabled and hide it.
-      if ($this->isDisabled()) {
-        if ($webform_submission->getWebform()->access('edit')) {
-          $this->displayDisabledWarning($element);
-        }
-        $element['#access'] = FALSE;
-      }
-
-      // Apply element specific access rules.
-      $operation = ($webform_submission->isCompleted()) ? 'update' : 'create';
-      // Make sure the webform and submission is set before
-      // checking access rules.
-      $this->setEntities($webform_submission);
-      $element['#access'] = $this->checkAccessRules($operation, $element);
-    }
-
-    // Enable webform template preprocessing enhancements.
-    // @see \Drupal\webform\Utility\WebformElementHelper::isWebformElement
-    $element['#webform_element'] = TRUE;
-
-    // Add #allowed_tags.
-    $allowed_tags = $this->configFactory->get('webform.settings')->get('element.allowed_tags');
-    switch ($allowed_tags) {
-      case 'admin':
-        $element['#allowed_tags'] = Xss::getAdminTagList();
-        break;
-
-      case 'html':
-        $element['#allowed_tags'] = Xss::getHtmlTagList();
-        break;
-
-      default:
-        $element['#allowed_tags'] = preg_split('/ +/', $allowed_tags);
-        break;
-    }
-
-    // Add autocomplete attribute.
-    if (isset($element['#autocomplete'])) {
-      $element['#attributes']['autocomplete'] = $element['#autocomplete'];
-    }
-
-    // Add inline title display support.
-    // Inline fieldset layout is handled via webform_preprocess_fieldset().
-    // @see webform_preprocess_fieldset()
-    if (isset($element['#title_display']) && $element['#title_display'] == 'inline') {
-      // Store reference to unset #title_display.
-      $element['#_title_display'] = $element['#title_display'];
-      unset($element['#title_display']);
-      $element['#wrapper_attributes']['class'][] = 'webform-element--title-inline';
-    }
-
-    // Check markup properties.
-    $markup_properties = [
-      '#description',
-      '#help',
-      '#more',
-      '#multiple__no_items_message',
-    ];
-    foreach ($markup_properties as $markup_property) {
-      if (isset($element[$markup_property]) && !is_array($element[$markup_property])) {
-        $element[$markup_property] = WebformHtmlEditor::checkMarkup($element[$markup_property]);
-      }
-    }
-
-    // Add default description display.
-    $default_description_display = $this->configFactory->get('webform.settings')->get('element.default_description_display');
-    if ($default_description_display && !isset($element['#description_display']) && $this->hasProperty('description_display')) {
-      $element['#description_display'] = $default_description_display;
-    }
-
-    // Add tooltip description display support.
-    if (isset($element['#description_display']) && $element['#description_display'] === 'tooltip') {
-      $element['#description_display'] = 'invisible';
-      $element[$attributes_property]['class'][] = 'js-webform-tooltip-element';
-      $element[$attributes_property]['class'][] = 'webform-tooltip-element';
-      $element['#attached']['library'][] = 'webform/webform.tooltip';
-    }
-
-    // Add .webform-has-field-prefix and .webform-has-field-suffix class.
-    if (!empty($element['#field_prefix'])) {
-      $element[$attributes_property]['class'][] = 'webform-has-field-prefix';
-    }
-    if (!empty($element['#field_suffix'])) {
-      $element[$attributes_property]['class'][] = 'webform-has-field-suffix';
-    }
-
-    // Add 'data-webform-states-no-clear' attribute if #states_clear is FALSE.
-    if (isset($element['#states_clear']) && $element['#states_clear'] === FALSE) {
-      $element[$attributes_property]['data-webform-states-no-clear'] = TRUE;
-    }
-
-    // Set element's #element_validate callback so that is not replaced when
-    // we append additional #element_validate callbacks.
-    $this->setElementDefaultCallback($element, 'element_validate');
-    $this->prepareElementValidateCallbacks($element, $webform_submission);
-
-    if ($this->isInput($element)) {
-      // Handle #readonly support.
-      // @see \Drupal\Core\Form\FormBuilder::handleInputElement
-      if (!empty($element['#readonly'])) {
-        $element['#attributes']['readonly'] = 'readonly';
-        if ($this->hasProperty('wrapper_attributes')) {
-          $element['#wrapper_attributes']['class'][] = 'webform-readonly';
-        }
-      }
-
-      // Set custom required error message as 'data-required-error' attribute.
-      // @see Drupal.behaviors.webformRequiredError
-      // @see webform.form.js
-      if (!empty($element['#required_error'])) {
-        $element['#attributes']['data-webform-required-error'] = WebformHtmlHelper::toPlainText($element['#required_error']);
-        $element['#required_error'] = WebformHtmlHelper::toHtmlMarkup($element['#required_error']);
-      }
-    }
-
-    // Replace tokens for all properties.
-    if ($webform_submission) {
-      $this->replaceTokens($element, $webform_submission);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function finalize(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
-    // Set element's #element_validate callback so that is not replaced when
-    // we append additional #pre_render callbacks.
-    $this->setElementDefaultCallback($element, 'pre_render');
-    $this->prepareElementPreRenderCallbacks($element, $webform_submission);
-
-    // Prepare composite element.
-    $this->prepareCompositeFormElement($element);
-
-    // Prepare multiple element.
-    $this->prepareMultipleWrapper($element);
-
-    // Prepare #states and flexbox wrapper.
-    $this->prepareWrapper($element);
-
-    // Set hidden element #after_build handler.
-    $this->setElementDefaultCallback($element, 'after_build');
-    $element['#after_build'][] = [get_class($this), 'hiddenElementAfterBuild'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function alterForm(array &$element, array &$form, FormStateInterface $form_state) {
-    // Do nothing.
-  }
-
-  /**
-   * Webform element #after_build callback.
-   *
-   * Wrap #element_validate so that we suppress element validation errors.
-   */
-  public static function hiddenElementAfterBuild(array $element, FormStateInterface $form_state) {
-    if (!isset($element['#access']) || $element['#access']) {
-      return $element;
-    }
-
-    // Disabled #required validation for hidden elements.
-    $element['#required'] = FALSE;
-
-    return WebformElementHelper::setElementValidate($element);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function checkAccessRules($operation, array $element, AccountInterface $account = NULL) {
-    // Respect elements that already have their #access set to FALSE.
-    if (isset($element['#access']) && $element['#access'] === FALSE) {
-      return FALSE;
-    }
-
-    // Get the current user, webform, and webform submission.
-    $account = $account ?: $this->currentUser;
-    $webform = $this->getWebform();
-    $webform_submission = $this->getWebformSubmission();
-
-    // If webform is missing, throw an exception.
-    if (!$webform) {
-      throw new \Exception("Webform entity is required to check and element's access (rules).");
-    }
-
-    // If #private, check that the current user can 'view any submission'.
-    if (!empty($element['#private']) && !$webform->access('submission_view_any', $account)) {
-      return FALSE;
-    }
-
-    // Check webform and other modules access results.
-    $access_result = $this->checkAccessRule($element, $operation, $account)
-      ? AccessResult::allowed()
-      : AccessResult::neutral();
-
-    // Allow webform handlers to adjust the access and/or directly set an
-    // element's #access to FALSE.
-    $handler_result = $webform->invokeHandlers('accessElement', $element, $operation, $account, $webform_submission);
-    $access_result = $access_result->orIf($handler_result);
-
-    // Allow modules to adjust the element's access.
-    $context = [
-      'webform' => $webform,
-      'webform_submission' => $webform_submission,
-    ];
-    $modules = \Drupal::moduleHandler()
-      ->getImplementations('webform_element_access');
-    foreach ($modules as $module) {
-      $hook = $module . '_webform_element_access';
-      $hook_result = $hook($operation, $element, $account, $context);
-      $access_result = $access_result->orIf($hook_result);
-    }
-
-    // Grant access as provided by webform, webform handler(s) and/or
-    // hook_webform_element_access() implementation.
-    return $access_result->isAllowed();
-  }
-
-  /**
-   * Checks an access rule against a user account's roles and id.
-   *
-   * @param array $element
-   *   The element.
-   * @param string $operation
-   *   The operation.
-   * @param \Drupal\Core\Session\AccountInterface $account
-   *   The user session for which to check access.
-   *
-   * @return bool
-   *   The access result. Returns a TRUE if access is allowed.
-   *
-   * @see \Drupal\webform\Entity\Webform::checkAccessRule
-   */
-  protected function checkAccessRule(array $element, $operation, AccountInterface $account) {
-    // If no access rules are set return NULL (no opinion).
-    // @see \Drupal\webform\Plugin\WebformElementBase::defaultBaseProperties
-    if (!isset($element['#access_' . $operation . '_roles'])
-      && !isset($element['#access_' . $operation . '_users'])
-      && !isset($element['#access_' . $operation . '_permissions'])) {
-      return TRUE;
-    }
-
-    // If access roles are not set then use the anonymous and authenticated
-    // roles from the element's default properties.
-    // @see \Drupal\webform\Plugin\WebformElementBase::defaultBaseProperties
-    if (!isset($element['#access_' . $operation . '_roles'])) {
-      $element['#access_' . $operation . '_roles'] = $this->getDefaultProperty('access_' . $operation . '_roles') ?: [];
-    }
-    if (array_intersect($element['#access_' . $operation . '_roles'], $account->getRoles())) {
-      return TRUE;
-    }
-
-    if (isset($element['#access_' . $operation . '_users']) && in_array($account->id(), $element['#access_' . $operation . '_users'])) {
-      return TRUE;
-    }
-
-    if (isset($element['#access_' . $operation . '_permissions'])) {
-      foreach ($element['#access_' . $operation . '_permissions'] as $permission) {
-        if ($account->hasPermission($permission)) {
-          return TRUE;
-        }
-      }
-    }
-
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function replaceTokens(array &$element, EntityInterface $entity = NULL) {
-    foreach ($element as $key => $value) {
-      // Only replace tokens in properties.
-      if (Element::child($key)) {
-        continue;
-      }
-
-      // Ignore tokens in #template and #format_* properties.
-      if (in_array($key, ['#template', '#format_html', '#format_text', 'format_items_html', 'format_items_text'])) {
-        continue;
-      }
-
-      $element[$key] = $this->tokenManager->replaceNoRenderContext($value, $entity);
-    }
-  }
-
-  /**
-   * Prepare an element's validation callbacks.
-   *
-   * @param array $element
-   *   An element.
-   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
-   *   A webform submission.
-   */
-  protected function prepareElementValidateCallbacks(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
-    // Validation callbacks are only applicable to inputs.
-    if (!$this->isInput($element)) {
-      return;
-    }
-
-    // Add webform element #minlength, #multiple, and/or #unique
-    // validation handler.
-    if (isset($element['#minlength'])) {
-      $element['#element_validate'][] = [get_class($this), 'validateMinlength'];
-    }
-    if (isset($element['#multiple']) && $element['#multiple'] > 1) {
-      $element['#element_validate'][] = [get_class($this), 'validateMultiple'];
-    }
-    if (isset($element['#unique']) && $webform_submission) {
-      $element['#element_validate'][] = [get_class($this), 'validateUnique'];
-    }
-  }
-
-  /**
-   * Prepare an element's pre render callbacks.
-   *
-   * @param array $element
-   *   An element.
-   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
-   *   A webform submission.
-   */
-  protected function prepareElementPreRenderCallbacks(array &$element, WebformSubmissionInterface $webform_submission = NULL) {
-    // Do nothing.
-  }
-
-  /**
-   * Replace Core's composite #pre_render with Webform's composite #pre_render.
-   *
-   * @param array $element
-   *   An element.
-   *
-   * @see \Drupal\Core\Render\Element\CompositeFormElementTrait
-   * @see \Drupal\webform\Element\WebformCompositeFormElementTrait
-   */
-  protected function prepareCompositeFormElement(array &$element) {
-    if (empty($element['#pre_render'])) {
-      return;
-    }
-
-    // Replace preRenderCompositeFormElement with
-    // preRenderWebformCompositeFormElement.
-    foreach ($element['#pre_render'] as $index => $pre_render) {
-      if (is_array($pre_render) && $pre_render[1] === 'preRenderCompositeFormElement') {
-        $element['#pre_render'][$index] = [get_called_class(), 'preRenderWebformCompositeFormElement'];
-      }
-    }
-  }
-
-  /**
-   * Set an elements #states and flexbox wrapper.
-   *
-   * @param array $element
-   *   An element.
-   */
-  protected function prepareWrapper(array &$element) {
-    $has_states_wrapper = $this->pluginDefinition['states_wrapper'];
-    $has_flexbox_wrapper = !empty($element['#webform_parent_flexbox']);
-    if (!$has_states_wrapper && !$has_flexbox_wrapper) {
-      return;
-    }
-
-    $class = get_class($this);
-
-    // Fix #states wrapper.
-    if ($has_states_wrapper) {
-      $element['#pre_render'][] = [$class, 'preRenderFixStatesWrapper'];
-    }
-
-    // Add flex(box) wrapper.
-    if ($has_flexbox_wrapper) {
-      $element['#pre_render'][] = [$class, 'preRenderFixFlexboxWrapper'];
-    }
-  }
-
-  /**
-   * Fix state wrapper.
-   *
-   * Notes:
-   * - Certain elements don't support #states so a workaround is to adds a
-   *   wrapper that renders the #states in a #prefix and #suffix div tag.
-   * - Composite elements tend not to properly handle #states.
-   * - Composite elements need propagate a visible/hidden #states to
-   *   sub-element required #state.
-   *
-   * @param array $element
-   *   An element.
-   *
-   * @return array
-   *   An element with #states added to the #prefix and #suffix.
-   */
-  public static function preRenderFixStatesWrapper(array $element) {
-    WebformElementHelper::fixStatesWrapper($element);
-    return $element;
-  }
-
-  /**
-   * Fix flexbox wrapper.
-   *
-   * @param array $element
-   *   An element.
-   *
-   * @return array
-   *   An element with flexbox wrapper added to the #prefix and #suffix.
-   */
-  public static function preRenderFixFlexboxWrapper(array $element) {
-    $flex = (isset($element['#flex'])) ? $element['#flex'] : 1;
-    $element += ['#prefix' => '', '#suffix' => ''];
-    $element['#prefix'] = '<div class="webform-flex webform-flex--' . $flex . '"><div class="webform-flex--container">' . $element['#prefix'];
-    $element['#suffix'] = $element['#suffix'] . '</div></div>';
-    return $element;
-  }
-
-  /**
-   * Set multiple element wrapper.
-   *
-   * @param array $element
-   *   An element.
-   */
-  protected function prepareMultipleWrapper(array &$element) {
-    if (!$this->hasMultipleValues($element) || !$this->hasMultipleWrapper() || empty($element['#multiple'])) {
-      return;
-    }
-
-    // Set the multiple element.
-    $element['#element'] = $element;
-
-    // Remove properties that should only be applied to the parent element.
-    $element['#element'] = array_diff_key($element['#element'], array_flip(['#access', '#default_value', '#description', '#description_display', '#required', '#required_error', '#states', '#wrapper_attributes', '#prefix', '#suffix', '#element', '#tags', '#multiple']));
-
-    // Propagate #states to sub element.
-    // @see \Drupal\webform\Element\WebformCompositeBase::processWebformComposite
-    if (!empty($element['#states'])) {
-      $element['#element']['#_webform_states'] = $element['#states'];
-    }
-
-    // Always make the title invisible.
-    $element['#element']['#title_display'] = 'invisible';
-
-    // Set hidden element #after_build handler.
-    $element['#element']['#after_build'][] = [get_class($this), 'hiddenElementAfterBuild'];
-
-    // Remove 'for' from the main element's label.
-    // This must be done after the $element['#element' is defined.
-    $element['#label_attributes']['webform-remove-for-attribute'] = TRUE;
-
-    // Change the element to a multiple element.
-    $element['#type'] = 'webform_multiple';
-    $element['#webform_multiple'] = TRUE;
-
-    // Set cardinality from #multiple.
-    if ($element['#multiple'] > 1) {
-      $element['#cardinality'] = $element['#multiple'];
-    }
-
-    // Apply multiple properties.
-    $multiple_properties = $this->defineDefaultMultipleProperties();
-    foreach ($multiple_properties as $multiple_property => $multiple_value) {
-      if (strpos($multiple_property, 'multiple__') === 0) {
-        $property_name = str_replace('multiple__', '', $multiple_property);
-        $element["#$property_name"] = (isset($element["#$multiple_property"])) ? $element["#$multiple_property"] : $multiple_value;
-      }
-    }
-
-    // If header label is defined use it for the #header.
-    if (!empty($element['#multiple__header_label'])) {
-      $element['#header'] = $element['#multiple__header_label'];
-    }
-
-    // Remove properties that should only be applied to the child element.
-    $element = array_diff_key($element, array_flip(['#attributes', '#field_prefix', '#field_suffix', '#pattern', '#placeholder', '#maxlength', '#element_validate', '#pre_render']));
-
-    // Apply #unique multiple validation.
-    if (isset($element['#unique'])) {
-      $element['#element_validate'][] = [get_class($this), 'validateUniqueMultiple'];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function displayDisabledWarning(array $element) {
-    $t_args = [
-      '%title' => $this->getLabel($element),
-      '%type' => $this->getPluginLabel(),
-      ':href' => Url::fromRoute('webform.config.elements')->toString(),
-    ];
-    if ($this->currentUser->hasPermission('administer webform')) {
-      $message = $this->t('%title is a %type element, which has been disabled and will not be rendered. Go to the <a href=":href">admin settings</a> page to enable this element.', $t_args);
-    }
-    else {
-      $message = $this->t('%title is a %type element, which has been disabled and will not be rendered. Please contact a site administrator.', $t_args);
-    }
-    $this->messenger()->addWarning($message);
-
-    $context = [
-      '@title' => $this->getLabel($element),
-      '@type' => $this->getPluginLabel(),
-      'link' => Link::fromTextAndUrl($this->t('Edit'), Url::fromRoute('<current>'))->toString(),
-    ];
-    $this->logger->notice("'@title' is a '@type' element, which has been disabled and will not be rendered.", $context);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setDefaultValue(array &$element) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getLabel(array $element) {
-    return (!empty($element['#title'])) ? $element['#title'] : $element['#webform_key'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAdminLabel(array $element) {
-    $element += ['#admin_title' => '', '#title' => '', '#webform_key' => ''];
-    return $element['#admin_title'] ?: $element['#title'] ?: $element['#webform_key'];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getKey(array $element) {
-    return $element['#webform_key'];
-  }
-
-  /****************************************************************************/
-  // Display submission value methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildHtml(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    return $this->build('html', $element, $webform_submission, $options);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildText(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    return $this->build('text', $element, $webform_submission, $options);
-  }
-
-  /**
-   * Build an element as text or HTML.
-   *
-   * @param string $format
-   *   Format of the element, text or html.
-   * @param array $element
-   *   An element.
-   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
-   *   A webform submission.
-   * @param array $options
-   *   An array of options.
-   *
-   * @return array
-   *   A render array representing an element as text or HTML.
-   */
-  protected function build($format, array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $options['multiline'] = $this->isMultiline($element);
-    $format_function = 'format' . ucfirst($format);
-    $value = $this->$format_function($element, $webform_submission, $options);
-
-    // Handle empty value.
-    if ($value === '') {
-      // Return NULL if empty is excluded.
-      if ($this->isEmptyExcluded($element, $options)) {
-        return NULL;
-      }
-      // Else set the formatted value to empty message/placeholder.
-      else {
-        $value = $this->configFactory->get('webform.settings')->get('element.empty_message');
-      }
-    }
-
-    // Convert string to renderable #markup.
-    if (is_string($value)) {
-      $value = ['#' . ($format === 'text' ? 'plain_text' : 'markup') => $value];
-    }
-
-    return [
-      '#theme' => 'webform_element_base_' . $format,
-      '#element' => $element,
-      '#value' => $value,
-      '#webform_submission' => $webform_submission,
-      '#options' => $options,
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formatHtml(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    return $this->format('Html', $element, $webform_submission, $options);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formatText(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    return $this->format('Text', $element, $webform_submission, $options);
-  }
-
-  /**
-   * Format an element's value as HTML or plain text.
-   *
-   * @param string $type
-   *   The format type, HTML or Text.
-   * @param array $element
-   *   An element.
-   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
-   *   A webform submission.
-   * @param array $options
-   *   An array of options.
-   *
-   * @return array|string
-   *   The element's value formatted as plain text or a render array.
-   */
-  protected function format($type, array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    if (!$this->hasValue($element, $webform_submission, $options) && !$this->isContainer($element)) {
-      return '';
-    }
-
-    $item_function = 'format' . $type . 'Item';
-    $items_function = 'format' . $type . 'Items';
-    if ($this->hasMultipleValues($element)) {
-      // Return $options['delta'] which is used by tokens.
-      // @see _webform_token_get_submission_value()
-      if (isset($options['delta'])) {
-        return $this->$item_function($element, $webform_submission, $options);
-      }
-      elseif ($this->getItemsFormat($element) === 'custom' && !empty($element['#format_items_' . strtolower($type)])) {
-        return $this->formatCustomItems($type, $element, $webform_submission, $options);
-      }
-      else {
-        return $this->$items_function($element, $webform_submission, $options);
-      }
-    }
-    else {
-      if ($this->getItemFormat($element) === 'custom' && !empty($element['#format_' . strtolower($type)])) {
-        return $this->formatCustomItem($type, $element, $webform_submission, $options);
-      }
-      else {
-        return $this->$item_function($element, $webform_submission, $options);
-      }
-    }
-  }
-
-  /**
-   * Format an element's items using custom HTML or plain text.
-   *
-   * @param string $type
-   *   The format type, HTML or Text.
-   * @param array $element
-   *   An element.
-   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
-   *   A webform submission.
-   * @param array $options
-   *   An array of options.
-   * @param array $context
-   *   (optional) Context to be passed to inline Twig template.
-   *
-   * @return array|string
-   *   The element's items formatted as plain text or a render array.
-   */
-  protected function formatCustomItems($type, array &$element, WebformSubmissionInterface $webform_submission, array $options = [], array $context = []) {
-    $name = strtolower($type);
-
-    // Get value.
-    $value = $this->getValue($element, $webform_submission, $options);
-
-    // Get items.
-    $items = [];
-    $item_function = 'format' . $type . 'Item';
-    foreach (array_keys($value) as $delta) {
-      $items[] = $this->$item_function($element, $webform_submission, ['delta' => $delta] + $options);
-    }
-
-    // Get template.
-    $template = trim($element['#format_items_' . $name]);
-
-    // Get context.
-    $options += ['context' => []];
-    $context += [
-      'value' => $value,
-      'items' => $items,
-    ];
-
-    return WebformTwigExtension::buildTwigTemplate($webform_submission, $template, $options, $context);
-  }
-
-  /**
-   * Format an element's items as HTML.
-   *
-   * @param array $element
-   *   An element.
-   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
-   *   A webform submission.
-   * @param array $options
-   *   An array of options.
-   *
-   * @return string|array
-   *   The element's items as HTML.
-   */
-  protected function formatHtmlItems(array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $value = $this->getValue($element, $webform_submission, $options);
-
-    // Get items.
-    $items = [];
-    foreach (array_keys($value) as $delta) {
-      $items[] = $this->formatHtmlItem($element, $webform_submission, ['delta' => $delta] + $options);
-    }
-
-    $format = $this->getItemsFormat($element);
-    switch ($format) {
-      case 'ol':
-      case 'ul':
-        return [
-          '#theme' => 'item_list',
-          '#items' => $items,
-          '#list_type' => $format,
-        ];
-
-      case 'and':
-        $total = count($items);
-        if ($total === 1) {
-          $item = current($items);
-          return is_array($item) ? $item : ['#markup' => $item];
-        }
-
-        $build = [];
-        foreach ($items as $index => &$item) {
-          $build[] = (is_array($item)) ? $item : ['#markup' => $item];
-          if ($total === 2 && $index === 0) {
-            $build[] = ['#markup' => ' ' . t('and') . ' '];
-          }
-          elseif ($index !== ($total - 1)) {
-            if ($index === ($total - 2)) {
-              $build[] = ['#markup' => ', ' . t('and') . ' '];
-            }
-            else {
-              $build[] = ['#markup' => ', '];
-            }
-          }
-        }
-        return $build;
-
-      default:
-      case 'br':
-      case 'semicolon':
-      case 'comma':
-      case 'space':
-      case 'hr':
-        $delimiters = [
-          'hr' => '<hr class="webform-horizontal-rule" />',
-          'br' => '<br />',
-          'semicolon' => '; ',
-          'comma' => ', ',
-          'space' => ' ',
-        ];
-        $delimiter = (isset($delimiters[$format])) ? $delimiters[$format] : $format;
-
-        $total = count($items);
-
-        $build = [];
-        foreach ($items as $index => &$item) {
-          $build[] = (is_array($item)) ? $item : ['#markup' => $item];
-          if ($index !== ($total - 1)) {
-            $build[] = ['#markup' => $delimiter];
-          }
-        }
-        return $build;
-    }
-  }
-
-  /**
-   * Format an element's items as text.
-   *
-   * @param array $element
-   *   An element.
-   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
-   *   A webform submission.
-   * @param array $options
-   *   An array of options.
-   *
-   * @return string
-   *   The element's items as text.
-   */
-  protected function formatTextItems(array &$element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $value = $this->getValue($element, $webform_submission, $options);
-
-    // Get items.
-    $items = [];
-    foreach (array_keys($value) as $delta) {
-      $items[] = $this->formatTextItem($element, $webform_submission, ['delta' => $delta] + $options);
-    }
-
-    $format = $this->getItemsFormat($element);
-    switch ($format) {
-      case 'ol':
-        $list = [];
-        $index = 1;
-        foreach ($items as $item) {
-          $prefix = ($index++) . '. ';
-          $list[] = $prefix . str_replace(PHP_EOL, PHP_EOL . str_repeat(' ', strlen($prefix)), $item);
-        }
-        return implode(PHP_EOL, $list);
-
-      case 'ul':
-        $list = [];
-        foreach ($items as $index => $item) {
-          $list[] = '- ' . str_replace(PHP_EOL, PHP_EOL . '  ', $item);
-        }
-        return implode(PHP_EOL, $list);
-
-      case 'and':
-        return WebformArrayHelper::toString($items);
-
-      default:
-      case 'br':
-      case 'semicolon':
-      case 'comma':
-      case 'space':
-      case 'hr':
-        $delimiters = [
-          'hr' => PHP_EOL . '---' . PHP_EOL,
-          'br' => PHP_EOL,
-          'semicolon' => '; ',
-          'comma' => ', ',
-          'space' => ' ',
-        ];
-        $delimiter = (isset($delimiters[$format])) ? $delimiters[$format] : $format;
-        return implode($delimiter, $items);
-    }
-  }
-
-  /**
-   * Format an element's item using custom HTML or plain text.
-   *
-   * @param string $type
-   *   The format type, HTML or Text.
-   * @param array $element
-   *   An element.
-   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
-   *   A webform submission.
-   * @param array $options
-   *   An array of options.
-   * @param array $context
-   *   (optional) Context to be passed to inline Twig template.
-   *
-   * @return array|string
-   *   The element's item formatted as plain text or a render array.
-   */
-  protected function formatCustomItem($type, array &$element, WebformSubmissionInterface $webform_submission, array $options = [], array $context = []) {
-    $name = strtolower($type);
-
-    // Get template.
-    $template = trim($element['#format_' . $name]);
-
-    // Get context.value.
-    $context['value'] = $this->getValue($element, $webform_submission, $options);
-
-    // Get content.item.
-    $context['item'] = [];
-    // Parse item.format from template and add to context.
-    if (preg_match_all("/item(?:\[['\"]|\.)([a-zA-Z0-9-_:]+)/", $template, $matches)) {
-      $formats = array_unique($matches[1]);
-      $item_function = 'format' . $type . 'Item';
-      foreach ($formats as $format) {
-        $context['item'][$format] = $this->$item_function(['#format' => $format] + $element, $webform_submission, $options);
-      }
-    }
-
-    // Return inline template.
-    if ($type === 'Text') {
-      return WebformTwigExtension::renderTwigTemplate($webform_submission, $template, $options, $context);
-    }
-    else {
-      return WebformTwigExtension::buildTwigTemplate($webform_submission, $template, $options, $context);
-    }
-  }
-
-  /**
-   * Format an element's value as HTML.
-   *
-   * @param array $element
-   *   An element.
-   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
-   *   A webform submission.
-   * @param array $options
-   *   An array of options.
-   *
-   * @return array|string
-   *   The element's value formatted as HTML or a render array.
-   */
-  protected function formatHtmlItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $format = $this->getItemFormat($element);
-    $value = $this->formatTextItem($element, $webform_submission, ['prefixing' => FALSE] + $options);
-
-    if ($format === 'raw') {
-      return Markup::create($value);
-    }
-
-    // Build a render that used #plain_text so that HTML characters are escaped.
-    // @see \Drupal\Core\Render\Renderer::ensureMarkupIsSafe
-    $build = ['#plain_text' => $value];
-
-    $options += ['prefixing' => TRUE];
-    if ($options['prefixing']) {
-      if (isset($element['#field_prefix'])) {
-        $build['#prefix'] = $element['#field_prefix'];
-      }
-      if (isset($element['#field_suffix'])) {
-        $build['#suffix'] = $element['#field_suffix'];
-      }
-    }
-
-    return $build;
-  }
-
-  /**
-   * Format an element's value as text.
-   *
-   * @param array $element
-   *   An element.
-   * @param \Drupal\webform\WebformSubmissionInterface $webform_submission
-   *   A webform submission.
-   * @param array $options
-   *   An array of options.
-   *
-   * @return string
-   *   The element's value formatted as text.
-   *
-   * @see _webform_token_get_submission_value()
-   */
-  protected function formatTextItem(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $value = $this->getValue($element, $webform_submission, $options);
-    $format = $this->getItemFormat($element);
-
-    if ($format === 'raw') {
-      return $value;
-    }
-
-    $options += ['prefixing' => TRUE];
-    if ($options['prefixing']) {
-      if (isset($element['#field_prefix'])) {
-        $value = strip_tags($element['#field_prefix']) . $value;
-      }
-      if (isset($element['#field_suffix'])) {
-        $value .= strip_tags($element['#field_suffix']);
-      }
-    }
-
-    return $value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function hasValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $value = $this->getValue($element, $webform_submission, $options);
-    return ($value === '' || $value === NULL || (is_array($value) && empty($value))) ? FALSE : TRUE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    if (!isset($element['#webform_key']) && isset($element['#value'])) {
-      return $element['#value'];
-    }
-
-    $webform_key = (isset($options['webform_key'])) ? $options['webform_key'] : $element['#webform_key'];
-    $value = $webform_submission->getElementData($webform_key);
-    // Is value is NULL and there is a #default_value, then use it.
-    if ($value === NULL && isset($element['#default_value'])) {
-      $value = $element['#default_value'];
-    }
-
-    // Return multiple (delta) value or composite (composite_key) value.
-    if (is_array($value)) {
-      // Return $options['delta'] which is used by tokens.
-      // @see _webform_token_get_submission_value()
-      if (isset($options['delta'])) {
-        $value = (isset($value[$options['delta']])) ? $value[$options['delta']] : NULL;
-      }
-
-      // Return $options['composite_key'] which is used by composite elements.
-      // @see \Drupal\webform\Plugin\WebformElement\WebformCompositeBase::formatTableColumn
-      if ($value && isset($options['composite_key'])) {
-        $value = (isset($value[$options['composite_key']])) ? $value[$options['composite_key']] : NULL;
-      }
-    }
-
-    return $value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRawValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    $element['#format'] = 'raw';
-    return $this->getValue($element, $webform_submission, $options);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getItemFormats() {
-    return [
-      'value' => $this->t('Value'),
-      'raw' => $this->t('Raw value'),
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getItemDefaultFormat() {
-    return 'value';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getItemFormat(array $element) {
-    if (isset($element['#format'])) {
-      return $element['#format'];
-    }
-    elseif ($default_format = $this->configFactory->get('webform.settings')->get('format.' . $this->getPluginId() . '.item')) {
-      return $default_format;
-    }
-    else {
-      return $this->getItemDefaultFormat();
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getItemsDefaultFormat() {
-    return 'ul';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getItemsFormats() {
-    return [
-      'comma' => $this->t('Comma'),
-      'semicolon' => $this->t('Semicolon'),
-      'and' => $this->t('And'),
-      'ol' => $this->t('Ordered list'),
-      'ul' => $this->t('Unordered list'),
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getItemsFormat(array $element) {
-    if (isset($element['#format_items'])) {
-      return $element['#format_items'];
-    }
-    elseif ($default_format = $this->configFactory->get('webform.settings')->get('format.' . $this->getPluginId() . '.items')) {
-      return $default_format;
-    }
-    else {
-      return $this->getItemsDefaultFormat();
-    }
-  }
-
-  /****************************************************************************/
-  // Preview method.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preview() {
-    return [
-      '#type' => $this->getTypeName(),
-      '#title' => $this->getPluginLabel(),
-    ];
-  }
-
-  /****************************************************************************/
-  // Test methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTestValues(array $element, WebformInterface $webform, array $options = []) {
-    return FALSE;
-  }
-
-  /****************************************************************************/
-  // Table methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTableColumn(array $element) {
-    $key = $element['#webform_key'];
-    return [
-      'element__' . $key => [
-        'title' => $this->getAdminLabel($element),
-        'sort' => TRUE,
-        'key' => $key,
-        'property_name' => NULL,
-        'element' => $element,
-        'plugin' => $this,
-      ],
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function formatTableColumn(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
-    return $this->formatHtml($element, $webform_submission);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isEmptyExcluded(array $element, array $options) {
-    $options += [
-      'exclude_empty' => TRUE,
-    ];
-    return !empty($options['exclude_empty']);
-  }
-
-  /****************************************************************************/
-  // Export methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getExportDefaultOptions() {
-    return [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildExportOptionsForm(array &$form, FormStateInterface $form_state, array $export_options) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildExportHeader(array $element, array $export_options) {
-    if ($export_options['header_format'] == 'label') {
-      return [$this->getAdminLabel($element)];
-    }
-    else {
-      return [$element['#webform_key']];
-    }
-  }
-
-  /**
-   * Prefix an element's export header.
-   *
-   * @param array $header
-   *   An element's export header.
-   * @param array $element
-   *   An element.
-   * @param array $export_options
-   *   An associative array of export options.
-   *
-   * @return array
-   *   An element's export header with prefix.
-   */
-  protected function prefixExportHeader(array $header, array $element, array $export_options) {
-    if (empty($export_options['header_prefix'])) {
-      return $header;
-    }
-
-    if ($export_options['header_format'] == 'label') {
-      $prefix = $this->getAdminLabel($element) . $export_options['header_prefix_label_delimiter'];
-    }
-    else {
-      $prefix = $this->getKey($element) . $export_options['header_prefix_key_delimiter'];
-    }
-
-    foreach ($header as $index => $column) {
-      $header[$index] = $prefix . $column;
-    }
-
-    return $header;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildExportRecord(array $element, WebformSubmissionInterface $webform_submission, array $export_options) {
-    $element['#format_items'] = $export_options['multiple_delimiter'];
-    return [$this->formatText($element, $webform_submission, $export_options)];
-  }
-
-  /****************************************************************************/
-  // Validation methods.
-  /****************************************************************************/
-
-  /**
-   * Form API callback. Validate element #minlength value.
-   */
-  public static function validateMinlength(&$element, FormStateInterface &$form_state) {
-    if (!isset($element['#minlength'])) {
-      return;
-    }
-
-    if (!empty($element['#value']) && mb_strlen($element['#value']) < $element['#minlength']) {
-      $t_args = [
-        '%name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'],
-        '%min' => $element['#minlength'],
-        '%length' => mb_strlen($element['#value']),
-      ];
-      $form_state->setError($element, t('%name cannot be less than %min characters but is currently %length characters long.', $t_args));
-    }
-  }
-
-  /**
-   * Form API callback. Validate element #unique value.
-   */
-  public static function validateUnique(array &$element, FormStateInterface $form_state) {
-    if (!isset($element['#unique'])) {
-      return;
-    }
-
-    /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
-    $element_manager = \Drupal::service('plugin.manager.webform.element');
-
-    $name = $element['#webform_key'];
-    $value = NestedArray::getValue($form_state->getValues(), $element['#parents']);
-
-    // Skip composite elements.
-    $element_plugin = $element_manager->getElementInstance($element);
-    if ($element_plugin->isComposite()) {
-      return;
-    }
-
-    // Skip empty values but allow for '0'.
-    if ($value === '' || $value === NULL || (is_array($value) && empty($value))) {
-      return;
-    }
-
-    /** @var \Drupal\webform\WebformSubmissionForm $form_object */
-    $form_object = $form_state->getFormObject();
-    /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
-    $webform_submission = $form_object->getEntity();
-    $webform = $webform_submission->getWebform();
-
-    // Build unique query which return a single duplicate value.
-    $query = \Drupal::database()->select('webform_submission', 'ws');
-    $query->leftJoin('webform_submission_data', 'wsd', 'ws.sid = wsd.sid');
-    $query->fields('wsd', ['value']);
-    $query->condition('wsd.webform_id', $webform->id());
-    $query->condition('wsd.name', $name);
-    $query->condition('wsd.value', (array) $value, 'IN');
-    // Unique user condition.
-    if (!empty($element['#unique_user'])) {
-      $query->condition('ws.uid', $webform_submission->getOwnerId());
-    }
-    // Unique (source) entity condition.
-    if (!empty($element['#unique_entity'])) {
-      if ($source_entity = $webform_submission->getSourceEntity()) {
-        $query->condition('ws.entity_type', $source_entity->getEntityTypeId());
-        $query->condition('ws.entity_id', $source_entity->id());
-      }
-      else {
-        $query->isNull('ws.entity_type');
-        $query->isNull('ws.entity_id');
-      }
-    }
-    // Exclude the current webform submission.
-    if ($sid = $webform_submission->id()) {
-      $query->condition('ws.sid', $sid, '<>');
-    }
-    // Get single duplicate value.
-    $query->range(0, 1);
-    $duplicate_value = $query->execute()->fetchField();
-
-    // Skip NULL or empty string value.
-    if ($duplicate_value === FALSE || $duplicate_value === '') {
-      return;
-    }
-
-    if (isset($element['#unique_error'])) {
-      $form_state->setError($element, WebformHtmlHelper::toHtmlMarkup($element['#unique_error']));
-    }
-    elseif (isset($element['#title'])) {
-      // Get #options display value.
-      if (isset($element['#options'])) {
-        $duplicate_value = WebformOptionsHelper::getOptionText($duplicate_value, $element['#options'], TRUE);
-      }
-      $t_args = [
-        '%name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'],
-        '%value' => $duplicate_value,
-      ];
-      $form_state->setError($element, t('The value %value has already been submitted once for the %name element. You may have already submitted this webform, or you need to use a different value.', $t_args));
-    }
-    else {
-      $form_state->setError($element);
-    }
-  }
-
-  /**
-   * Form API callback. Validate element #unique multiple values.
-   */
-  public static function validateUniqueMultiple(array &$element, FormStateInterface $form_state) {
-    if (!isset($element['#unique'])) {
-      return;
-    }
-
-    $name = $element['#name'];
-    $value = NestedArray::getValue($form_state->getValues(), $element['#parents']);
-
-    if (empty($value)) {
-      return;
-    }
-
-    // Compare number of values to unique number of values.
-    if (count($value) != count(array_unique($value))) {
-      $duplicates = WebformArrayHelper::getDuplicates($value);
-
-      if (isset($element['#unique_error'])) {
-        $form_state->setError($element, WebformHtmlHelper::toHtmlMarkup($element['#unique_error']));
-      }
-      elseif (isset($element['#title'])) {
-        $t_args = [
-          '%name' => empty($element['#title']) ? $name : $element['#title'],
-          '%value' => reset($duplicates),
-        ];
-        $form_state->setError($element, t('The value %value has already been submitted once for the %name element. You may have already submitted this webform, or you need to use a different value.', $t_args));
-      }
-      else {
-        $form_state->setError($element);
-      }
-    }
-  }
-
-  /**
-   * Form API callback. Validate element #multiple > 1 value.
-   */
-  public static function validateMultiple(array &$element, FormStateInterface $form_state) {
-    if (!isset($element['#multiple'])) {
-      return;
-    }
-
-    // IMPORTANT: Must get values from the $form_states since sub-elements
-    // may call $form_state->setValueForElement() via their validation hook.
-    // @see \Drupal\webform\Element\WebformEmailConfirm::validateWebformEmailConfirm
-    // @see \Drupal\webform\Element\WebformOtherBase::validateWebformOther
-    $values = NestedArray::getValue($form_state->getValues(), $element['#parents']);
-
-    // Skip empty values or values that are not an array.
-    if (empty($values) || !is_array($values)) {
-      return;
-    }
-
-    if (count($values) > $element['#multiple']) {
-      if (isset($element['#multiple_error'])) {
-        $form_state->setError($element, $element['#multiple_error']);
-      }
-      elseif (isset($element['#title'])) {
-        $t_args = [
-          '%name' => empty($element['#title']) ? $element['#parents'][0] : $element['#title'],
-          '@count' => $element['#multiple'],
-        ];
-        $form_state->setError($element, t('%name: this element cannot hold more than @count values.', $t_args));
-      }
-      else {
-        $form_state->setError($element);
-      }
-    }
-  }
-
-  /****************************************************************************/
-  // #states API methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementStateOptions() {
-    $visibility_optgroup = (string) $this->t('Visibility');
-    $state_optgroup = (string) $this->t('State');
-    $validation_optgroup = (string) $this->t('Validation');
-    $value_optgroup = (string) $this->t('Value');
-
-    $states = [];
-
-    // Set default states that apply to the element/container and sub elements.
-    $states += [
-      $visibility_optgroup => [
-        'visible' => $this->t('Visible'),
-        'invisible' => $this->t('Hidden'),
-        'visible-slide' => $this->t('Visible (Slide)'),
-        'invisible-slide' => $this->t('Hidden (Slide)'),
-      ],
-      $state_optgroup => [
-        'enabled' => $this->t('Enabled'),
-        'disabled' => $this->t('Disabled'),
-      ],
-      $validation_optgroup => [
-        'required' => $this->t('Required'),
-        'optional' => $this->t('Optional'),
-      ],
-    ];
-
-    // Set readwrite/readonly states for any element that supports it
-    // and containers.
-    if ($this->hasProperty('readonly') || $this->isContainer(['#type' => $this->getPluginId()])) {
-      $states[$state_optgroup] += [
-        'readwrite' => $this->t('Read/write'),
-        'readonly' => $this->t('Read-only'),
-      ];
-    }
-
-    // Set checked/unchecked states for any element that contains checkboxes.
-    if ($this instanceof Checkbox || $this instanceof Checkboxes) {
-      $states[$value_optgroup] = [
-        'checked' => $this->t('Checked'),
-        'unchecked' => $this->t('Unchecked'),
-      ];
-    }
-
-    // Set expanded/collapsed states for any details element.
-    if ($this instanceof Details) {
-      $states[$state_optgroup] += [
-        'expanded' => $this->t('Expanded'),
-        'collapsed' => $this->t('Collapsed'),
-      ];
-    }
-
-    return $states;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementSelectorOptions(array $element) {
-    if ($this->hasMultipleValues($element) && $this->hasMultipleWrapper()) {
-      return [];
-    }
-
-    $title = $this->getAdminLabel($element) . ' [' . $this->getPluginLabel() . ']';
-    $name = $element['#webform_key'];
-
-    if ($inputs = $this->getElementSelectorInputsOptions($element)) {
-      $selectors = [];
-      foreach ($inputs as $input_name => $input_title) {
-        $selectors[":input[name=\"{$name}[{$input_name}]\"]"] = $input_title;
-      }
-      return [$title => $selectors];
-    }
-    else {
-      return [":input[name=\"$name\"]" => $title];
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementSelectorSourceValues(array $element) {
-    return [];
-  }
-
-  /**
-   * Get an element's (sub)inputs selectors as options.
-   *
-   * @param array $element
-   *   An element.
-   *
-   * @return array
-   *   An array of element (sub)input selectors.
-   */
-  protected function getElementSelectorInputsOptions(array $element) {
-    return [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getElementSelectorInputValue($selector, $trigger, array $element, WebformSubmissionInterface $webform_submission) {
-    if ($this->isComposite()) {
-      $input_name = WebformSubmissionConditionsValidator::getSelectorInputName($selector);
-      $composite_key = WebformSubmissionConditionsValidator::getInputNameAsArray($input_name, 1);
-      if ($composite_key) {
-        return $this->getRawValue($element, $webform_submission, ['composite_key' => $composite_key]);
-      }
-      else {
-        return NULL;
-      }
-    }
-    else {
-      return $this->getRawValue($element, $webform_submission);
-    }
-  }
-
-  /****************************************************************************/
-  // Operation methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preCreate(array &$element, array &$values) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function postCreate(array &$element, WebformSubmissionInterface $webform_submission) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function postLoad(array &$element, WebformSubmissionInterface $webform_submission) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preDelete(array &$element, WebformSubmissionInterface $webform_submission) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function postDelete(array &$element, WebformSubmissionInterface $webform_submission) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preSave(array &$element, WebformSubmissionInterface $webform_submission) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function postSave(array &$element, WebformSubmissionInterface $webform_submission, $update = TRUE) {}
-
-  /****************************************************************************/
-  // Element configuration methods.
-  /****************************************************************************/
-
-  /**
-   * {@inheritdoc}
-   */
-  public function form(array $form, FormStateInterface $form_state) {
-    /** @var \Drupal\webform_ui\Form\WebformUiElementFormInterface $form_object */
-    $form_object = $form_state->getFormObject();
-    $webform = $form_object->getWebform();
-
-    $element_properties = $form_state->get('element_properties');
-
-    /**************************************************************************/
-    // General.
-    /**************************************************************************/
-
-    /* Element settings */
-
-    $form['element'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Element settings'),
-      '#access' => TRUE,
-      '#weight' => -50,
-    ];
-    $form['element']['title'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Title'),
-      '#maxlength' => NULL,
-      '#description' => $this->t('This is used as a descriptive label when displaying this webform element.'),
-      '#required' => TRUE,
-      '#attributes' => ['autofocus' => 'autofocus'],
-    ];
-    $form['element']['value'] = [
-      '#type' => 'textarea',
-      '#title' => $this->t('Value'),
-      '#description' => $this->t('The value of the webform element.'),
-    ];
-    $form['element']['multiple'] = [
-      '#title' => $this->t('Allowed number of values'),
-      '#type' => 'webform_element_multiple',
-    ];
-    $form['element']['multiple_error'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Custom allowed number of values error message'),
-      '#description' => $this->t('If set, this message will be used when an element\'s allowed number of values is exceeded, instead of the default "@message" message.', ['@message' => $this->t('%name: this element cannot hold more than @count values.')]),
-      '#states' => [
-        'visible' => [
-          ':input[name="properties[multiple][container][cardinality]"]' => ['value' => 'number'],
-          ':input[name="properties[multiple][container][cardinality_number]"]' => ['!value' => 1],
-        ],
-      ],
-    ];
-
-    /* Element description/help/more */
-
-    $form['element_description'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Element description/help/more'),
-    ];
-    $form['element_description']['description'] = [
-      '#type' => 'webform_html_editor',
-      '#title' => $this->t('Description'),
-      '#description' => $this->t('A short description of the element used as help for the user when he/she uses the webform.'),
-    ];
-    $form['element_description']['help'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Help'),
-      '#description' => $this->t("Displays a help tooltip after the element's title."),
-      '#states' => [
-        'invisible' => [
-          [':input[name="properties[title_display]"]' => ['value' => 'invisible']],
-        ],
-      ],
-    ];
-    $form['element_description']['help']['help_title'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Help title'),
-      '#description' => $this->t("The text displayed in help tooltip after the element's title.") . '<br /><br />' .
-        $this->t("Defaults to the element's title"),
-    ];
-    $form['element_description']['help']['help'] = [
-      '#type' => 'webform_html_editor',
-      '#title' => $this->t('Help text'),
-      '#description' => $this->t("The text displayed in help tooltip after the element's title."),
-    ];
-    $form['element_description']['more'] = [
-      '#type' => 'details',
-      '#title' => $this->t('More'),
-      '#description' => $this->t("Displays a read more hide/show widget below the element's description."),
-    ];
-    $form['element_description']['more']['more_title'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('More title'),
-      '#description' => $this->t('The click-able label used to open and close more text.') . '<br /><br />' .
-        $this->t('Defaults to: %value', ['%value' => $this->configFactory->get('webform.settings')->get('element.default_more_title')]),
-    ];
-    $form['element_description']['more']['more'] = [
-      '#type' => 'webform_html_editor',
-      '#title' => $this->t('More text'),
-      '#description' => $this->t('A long description of the element that provides form additional information which can opened and closed.'),
-    ];
-
-    /* Form display */
-    $form['form'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Form display'),
-    ];
-    $form['form']['display_container'] = $this->getFormInlineContainer();
-    $form['form']['display_container']['title_display'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Title display'),
-      '#empty_option' => $this->t('- Default -'),
-      '#options' => [
-        'before' => $this->t('Before'),
-        'after' => $this->t('After'),
-        'inline' => $this->t('Inline'),
-        'invisible' => $this->t('Invisible'),
-        'none' => $this->t('None'),
-      ],
-      '#description' => $this->t('Determines the placement of the title.'),
-    ];
-    // Displaying the title after the element is not supported by
-    // the composite (fieldset) wrapper.
-    if ($this->hasCompositeFormElementWrapper()) {
-      unset($form['form']['display_container']['title_display']['#options']['after']);
-    }
-    $form['form']['display_container']['description_display'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Description display'),
-      '#empty_option' => $this->t('- Default -'),
-      '#options' => [
-        'before' => $this->t('Before'),
-        'after' => $this->t('After'),
-        'invisible' => $this->t('Invisible'),
-        'tooltip' => $this->t('Tooltip'),
-      ],
-      '#description' => $this->t('Determines the placement of the description.'),
-    ];
-    $form['form']['display_container']['help_display'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Help display'),
-      '#empty_option' => $this->t('- Default -'),
-      '#options' => [
-        'title_before' => $this->t('Before title'),
-        'title_after' => $this->t('After title'),
-        'element_before' => $this->t('Before element'),
-        'element_after' => $this->t('After element'),
-      ],
-      '#description' => $this->t('Determines the placement of the help tooltip.'),
-    ];
-    if ($this->hasProperty('title_display')) {
-      $form['form']['title_display_message'] = [
-        '#type' => 'webform_message',
-        '#message_type' => 'warning',
-        '#message_message' => $this->t("Please note: Settings the element's title display to 'none' means the title will not be rendered or accessible to screenreaders"),
-        '#message_close' => TRUE,
-        '#message_storage' => WebformMessage::STORAGE_LOCAL,
-        '#access' => TRUE,
-        '#states' => [
-          'visible' => [
-            ':input[name="properties[title_display]"]' => ['value' => 'none'],
-          ],
-        ],
-      ];
-    }
-
-    // Remove unsupported title and description display from composite elements.
-    if ($this->isComposite()) {
-      unset($form['form']['display_container']['title_display']['#options']['inline']);
-      unset($form['form']['display_container']['description_display']['#options']['tooltip']);
-    }
-    // Remove unsupported title display from certain element types.
-    $element_types = [
-      'webform_codemirror',
-      'webform_email_confirm',
-      'webform_htmleditor',
-      'webform_mapping',
-      'webform_signature',
-    ];
-    if (in_array($this->getPluginId(), $element_types)) {
-      unset($form['form']['display_container']['title_display']['#options']['inline']);
-    }
-    // Remove unsupported title display from certain element types.
-    $element_types = [
-      'fieldset',
-      'details',
-      'webform_codemirror',
-      'webform_email_confirm',
-      'webform_htmleditor',
-      'webform_image_select',
-      'webform_likert',
-      'webform_mapping',
-      'webform_signature',
-    ];
-    if (in_array($this->getPluginId(), $element_types)) {
-      unset($form['form']['display_container']['title_display']['#options']['inline']);
-    }
-
-    $form['form']['field_container'] = $this->getFormInlineContainer();
-    $form['form']['field_container']['field_prefix'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Field prefix'),
-      '#description' => $this->t('Text or code that is placed directly in front of the input. This can be used to prefix an input with a constant string. Examples: $, #, -.'),
-      '#size' => 10,
-    ];
-    $form['form']['field_container']['field_suffix'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Field suffix'),
-      '#description' => $this->t('Text or code that is placed directly after the input. This can be used to add a unit to an input. Examples: lb, kg, %.'),
-      '#size' => 10,
-    ];
-    $form['form']['length_container'] = $this->getFormInlineContainer();
-    $form['form']['length_container']['minlength'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Minlength'),
-      '#description' => $this->t('The element may still be empty unless it is required.'),
-      '#min' => 1,
-      '#size' => 4,
-    ];    $form['form']['length_container']['maxlength'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Maxlength'),
-      '#description' => $this->t('Leaving blank will use the default maxlength.'),
-      '#min' => 1,
-      '#size' => 4,
-    ];
-    $form['form']['size_container'] = $this->getFormInlineContainer();
-    $form['form']['size_container']['size'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Size'),
-      '#description' => $this->t('Leaving blank will use the default size.'),
-      '#min' => 1,
-      '#size' => 4,
-    ];
-    $form['form']['size_container']['rows'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Rows'),
-      '#description' => $this->t('Leaving blank will use the default rows.'),
-      '#min' => 1,
-      '#size' => 4,
-    ];
-    $form['form']['placeholder'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Placeholder'),
-      '#description' => $this->t('The placeholder will be shown in the element until the user starts entering a value.'),
-    ];
-    $form['form']['autocomplete'] = [
-      '#type' => 'webform_select_other',
-      '#title' => $this->t('Autocomplete'),
-      '#description' => $this->t("Setting autocomplete to off will disable autocompletion for this element. Select 'Autofill' to use semantic attribute values for collecting certain types of user information."),
-      '#options' => [
-        'on' => $this->t('On'),
-        'off' => $this->t('Off'),
-      ],
-      '#other__type' => 'select',
-      '#other__option_label' => $this->t('Autofill…'),
-      '#other__title' => $this->t('Autocomplete autofill'),
-      '#other__description' => $this->t("Browsers sometimes have features for helping users fill forms in, for example prefilling the user's address based on earlier user input. The autocomplete (autofill) attribute can be used to hint to the user agent how to, or indeed whether to, provide such a feature."),
-      '#other__options' => [
-        (string) $this->t('Biographical attributes') => [
-          "name" => $this->t('Full name'),
-          "honorific-prefix" => $this->t('Honorific prefix'),
-          "given-name" => $this->t('Given name'),
-          "additional-name" => $this->t('Additional names'),
-          "family-name" => $this->t('Family name'),
-          "honorific-suffix" => $this->t('Honorific suffix'),
-          "nickname" => $this->t('Nickname'),
-          "username" => $this->t('Username'),
-          "new-password" => $this->t('New password'),
-          "current-password" => $this->t('Current password'),
-          "organization-title" => $this->t('Organization job title'),
-          "organization" => $this->t('Organization name'),
-          "language" => $this->t('Preferred language'),
-          "bday" => $this->t('Birthday'),
-          "bday-day" => $this->t('Birthday day'),
-          "bday-month" => $this->t('Birthday month'),
-          "bday-year" => $this->t('Birthday year'),
-          "sex" => $this->t('Gender'),
-          "url" => $this->t('Contact URL'),
-          "photo" => $this->t('Contact photo'),
-          "email" => $this->t('Email'),
-          "impp" => $this->t('Instant messaging URL'),
-        ],
-        (string) $this->t('Address attributes') => [
-          "street-address" => $this->t('Street address (multiline)'),
-          "address-line1" => $this->t('Address line 1'),
-          "address-line2" => $this->t('Address line 2'),
-          "address-line3" => $this->t('Address line 3'),
-          "address-level1" => $this->t('Address level 1'),
-          "address-level2" => $this->t('Address level 2'),
-          "address-level3" => $this->t('Address level 3'),
-          "address-level4" => $this->t('Address level 4'),
-          "country" => $this->t('Country code'),
-          "country-name" => $this->t('Country name'),
-          "postal-code" => $this->t('Postal code / Zip code'),
-        ],
-        (string) $this->t('Telephone attributes') => [
-          "tel" => $this->t('Telephone'),
-          "home tel" => $this->t('Telephone - home'),
-          "work tel" => $this->t('Telephone - work'),
-          "work tel-extension" => $this->t('Telephone - work extension'),
-          "mobile tel" => $this->t('Telephone - mobile'),
-          "fax tel" => $this->t('Telephone - fax'),
-          "pager tel" => $this->t('Telephone - pager'),
-          "tel-country-code" => $this->t('Telephone country code'),
-          "tel-national" => $this->t('Telephone national code'),
-          "tel-area-code" => $this->t('Telephone area code'),
-          "tel-local" => $this->t('Telephone local number'),
-          "tel-local-prefix" => $this->t('Telephone local prefix'),
-          "tel-local-suffix" => $this->t('Telephone local suffix'),
-          "tel-extension" => $this->t('Telephone extension'),
-        ],
-        (string) $this->t('Commerce attributes') => [
-          "cc-name" => $this->t('Name on card'),
-          "cc-given-name" => $this->t('Given name on card'),
-          "cc-additional-name" => $this->t('Additional names on card'),
-          "cc-family-name" => $this->t('Family name on card'),
-          "cc-number" => $this->t('Card number'),
-          "cc-exp" => $this->t('Card expiry date'),
-          "cc-exp-month" => $this->t('Card expiry month'),
-          "cc-exp-year" => $this->t('Card expiry year'),
-          "cc-csc" => $this->t('Card Security Code'),
-          "cc-type" => $this->t('Card type'),
-          "transaction-currency" => $this->t('Transaction currency'),
-          "transaction-amount" => $this->t('Transaction amount'),
-        ],
-      ],
-    ];
-    $form['form']['disabled'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Disabled'),
-      '#description' => $this->t('Make this element non-editable with the user entered (e.g. via developer tools) value <strong>ignored</strong>. Useful for displaying default value. Changeable via JavaScript.'),
-      '#return_value' => TRUE,
-      '#weight' => 50,
-    ];
-    $form['form']['readonly'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Readonly'),
-      '#description' => $this->t('Make this element non-editable with the user entered (e.g. via developer tools) value <strong>submitted</strong>. Useful for displaying default value. Changeable via JavaScript.'),
-      '#return_value' => TRUE,
-      '#weight' => 50,
-    ];
-    $form['form']['prepopulate'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Prepopulate'),
-      '#description' => $this->t('Allow element to be populated using query string parameters.'),
-      '#return_value' => TRUE,
-      '#weight' => 50,
-    ];
-    // Disabled check element when prepopulate is enabled for all elements.
-    if ($webform->getSetting('form_prepopulate') && $this->hasProperty('prepopulate')) {
-      $form['form']['prepopulate_disabled'] = [
-        '#description' => $this->t('Prepopulation is enabled for all form elements.'),
-        '#value' => TRUE,
-        '#disabled' => TRUE,
-        '#access' => TRUE,
-      ] + $form['form']['prepopulate'];
-      $form['form']['prepopulate']['#value'] = FALSE;
-      $form['form']['prepopulate']['#access'] = FALSE;
-    }
-    $form['form']['open'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Open'),
-      '#description' => $this->t('Contents should be visible (open) to the user.'),
-      '#return_value' => TRUE,
-      '#weight' => 50,
-    ];
-
-    /* Validation */
-
-    // Placeholder webform elements with #options.
-    // @see \Drupal\webform\Plugin\WebformElement\OptionsBase::form
-    $form['options'] = [];
-    $form['options_other'] = [];
-
-    $form['validation'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Form validation'),
-    ];
-    $error_messages = ['required_error', 'unique_error', 'pattern_error'];
-    $validation_html_message_states = [];
-    foreach ($error_messages as $error_message) {
-      if ($this->hasProperty($error_message)) {
-        if ($validation_html_message_states) {
-          $validation_html_message_states[] = 'or';
-        }
-        $validation_html_message_states[] = [':input[name="properties[' . $error_message . ']"]' => ['value' => ['pattern' => '(<[a-z][^>]*>|&(?:[a-z]+|#\d+);)']]];
-      }
-    }
-    if ($validation_html_message_states) {
-      $form['validation']['html_message'] = [
-        '#type' => 'webform_message',
-        '#message_message' => $this->t('Validation error message contains HTML markup. HTML markup can not be display via HTML5 clientside validation and will be removed.'),
-        '#message_type' => 'warning',
-        '#states' => ['visible' => $validation_html_message_states],
-        '#access' => TRUE,
-      ];
-    }
-    $form['validation']['required_container'] = [
-      '#type' => 'container',
-    ];
-    $form['validation']['required_container']['required'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Required'),
-      '#description' => $this->t('Check this option if the user must enter a value.'),
-      '#return_value' => TRUE,
-    ];
-    $form['validation']['required_container']['required_error'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Required message'),
-      '#description' => $this->t('If set, this message will be used when a required webform element is empty, instead of the default "Field x is required." message.'),
-      '#states' => [
-        'visible' => [
-          ':input[name="properties[required]"]' => ['checked' => TRUE],
-        ],
-      ],
-    ];
-    $form['validation']['unique_container'] = $this->getFormInlineContainer();
-    $form['validation']['unique_container']['unique'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Unique'),
-      '#description' => $this->t('Check that all entered values for this element are unique.'),
-      '#return_value' => TRUE,
-    ];
-    $form['validation']['unique_container']['unique_entity'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Unique per entity'),
-      '#description' => $this->t('Check that entered values for this element is unique for the current source entity.'),
-      '#return_value' => TRUE,
-      '#states' => [
-        'visible' => [
-          ['input[name="properties[unique]"]' => ['checked' => TRUE]],
-        ],
-      ],
-    ];
-    $form['validation']['unique_container']['unique_user'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Unique per user'),
-      '#description' => $this->t('Check that entered values for this element are unique for the current user.'),
-      '#return_value' => TRUE,
-      '#states' => [
-        'visible' => [
-          ['input[name="properties[unique]"]' => ['checked' => TRUE]],
-        ],
-      ],
-    ];
-    $form['validation']['unique_error'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Unique message'),
-      '#description' => $this->t('If set, this message will be used when an element\'s value are not unique, instead of the default "@message" message.', ['@message' => $this->t('The value %value has already been submitted once for the %name element. You may have already submitted this webform, or you need to use a different value.')]),
-      '#states' => [
-        'visible' => [
-          [':input[name="properties[unique]"]' => ['checked' => TRUE]],
-        ],
-      ],
-    ];
-
-    /* Flexbox item */
-
-    $form['flex'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Flexbox item'),
-      '#description' => $this->t('Learn more about using <a href=":href">flexbox layouts</a>.', [':href' => 'http://www.w3schools.com/css/css3_flexbox.asp']),
-    ];
-    $flex_range = range(0, 12);
-    $form['flex']['flex'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Flex'),
-      '#description' => $this->t('The flex property specifies the length of the item, relative to the rest of the flexible items inside the same container.') . '<br /><br />' .
-      $this->t('Defaults to: %value', ['%value' => 1]),
-      '#options' => [0 => $this->t('0 (none)')] + array_combine($flex_range, $flex_range),
-    ];
-
-    /**************************************************************************/
-    // Conditions.
-    /**************************************************************************/
-
-    /* Conditional logic */
-
-    $form['conditional_logic'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Conditional logic'),
-    ];
-    $form['conditional_logic']['states'] = [
-      '#type' => 'webform_element_states',
-      '#state_options' => $this->getElementStateOptions(),
-      '#selector_options' => $webform->getElementsSelectorOptions(),
-      '#selector_sources' => $webform->getElementsSelectorSourceValues(),
-      '#disabled_message' => TRUE,
-    ];
-    $form['conditional_logic']['states_clear'] = [
-      '#type' => 'checkbox',
-      '#title' => 'Clear value(s) when hidden',
-      '#return_value' => TRUE,
-      '#description' => ($this instanceof ContainerBase) ?
-        $this->t("When this container is hidden all this container's subelement values will be cleared.")
-        :
-        $this->t("When this element is hidden, this element's value will be cleared."),
-    ];
-    if ($this->hasProperty('states') && $this->hasProperty('required')) {
-      $form['conditional_logic']['states_required_message'] = [
-        '#type' => 'webform_message',
-        '#message_type' => 'warning',
-        '#message_message' => $this->t('Please note when an element is hidden it will not be required.'),
-        '#access' => TRUE,
-        '#states' => [
-          'visible' => [
-            ':input[name="properties[required]"]' => ['checked' => TRUE],
-          ],
-        ],
-      ];
-    }
-
-    /**************************************************************************/
-    // Advanced.
-    /**************************************************************************/
-
-    /* Default value */
-
-    $form['default'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Default value'),
-    ];
-    if ($this->isComposite()) {
-      $form['default']['default_value'] = [
-        '#type' => 'webform_codemirror',
-        '#mode' => 'yaml',
-        '#title' => $this->t('Default value'),
-      ];
-    }
-    else {
-      $form['default']['default_value'] = [
-        '#type' => 'textfield',
-        '#title' => $this->t('Default value'),
-        '#maxlength' => NULL,
-      ];
-    }
-    $form['default']['default_value']['#description'] = $this->t('The default value of the webform element.');
-    if ($this->hasProperty('multiple')) {
-      $form['default']['default_value']['#description'] .= ' ' . $this->t('For multiple options, use commas to separate multiple defaults.');
-    }
-
-    // Multiple.
-    $form['multiple'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Multiple settings'),
-      '#states' => [
-        'invisible' => [
-          ':input[name="properties[multiple][container][cardinality]"]' => ['!value' => -1],
-          ':input[name="properties[multiple][container][cardinality_number]"]' => ['value' => 1],
-        ],
-      ],
-      '#attributes' => ['data-webform-states-no-clear' => TRUE],
-    ];
-    $form['multiple']['multiple__header'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Display elements in table columns'),
-      '#description' => $this->t("If checked, the composite sub-element titles will be displayed as the table header labels."),
-      '#return_value' => TRUE,
-    ];
-    $form['multiple']['multiple__header_label'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Table header label'),
-      '#description' => $this->t('This is used as the table header for this webform element when displaying multiple values.'),
-    ];
-    $form['multiple']['multiple__no_items_message'] = [
-      '#type' => 'webform_html_editor',
-      '#title' => $this->t('No items message'),
-      '#description' => $this->t('This is used when there are no items entered.'),
-    ];
-    $form['multiple']['multiple__min_items'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Minimum amount of items'),
-      '#description' => $this->t('Minimum items defaults to 0 for optional elements and 1 for required elements.'),
-      '#min' => 0,
-      '#max' => 20,
-    ];
-    $form['multiple']['multiple__empty_items'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Number of empty items'),
-      '#required' => TRUE,
-      '#min' => 0,
-      '#max' => 20,
-    ];
-    $form['multiple']['multiple__sorting'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Allow users to sort elements'),
-      '#description' => $this->t('If unchecked, the elements will no longer be sortable.'),
-      '#return_value' => TRUE,
-    ];
-    $form['multiple']['multiple__operations'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Allow users to add/remove elements'),
-      '#description' => $this->t('If unchecked, the add/remove (+/x) buttons will be removed from each table row.'),
-      '#return_value' => TRUE,
-    ];
-    $form['multiple']['multiple__add_more'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Allow users to add more items'),
-      '#description' => $this->t('If checked, an add more input will be added below the multiple values.'),
-      '#return_value' => TRUE,
-    ];
-    $form['multiple']['multiple__add_more_container'] = [
-      '#type' => 'container',
-      '#states' => [
-        'visible' => [
-          ':input[name="properties[multiple__add_more]"]' => ['checked' => TRUE],
-        ],
-      ],
-    ];
-    $form['multiple']['multiple__add_more_container']['multiple__add_more_input'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Allow users to input the number of items to be added'),
-      '#description' => $this->t('If checked, users will be able to input the number of items to be added.'),
-      '#return_value' => TRUE,
-    ];
-    $form['multiple']['multiple__add_more_container']['multiple__add_more_button_label'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Add more button label'),
-      '#description' => $this->t('This is used as the add more items button label for this webform element when displaying multiple values.'),
-    ];
-    $form['multiple']['multiple__add_more_container']['multiple__add_more_input_label'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Add more input label'),
-      '#description' => $this->t('This is used as the add more items input label for this webform element when displaying multiple values.'),
-      '#states' => [
-        'visible' => [
-          ':input[name="properties[multiple__add_more_input]"]' => ['checked' => TRUE],
-        ],
-      ],
-    ];
-    $form['multiple']['multiple__add_more_container']['multiple__add_more_items'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Number of add more items'),
-      '#required' => TRUE,
-      '#min' => 1,
-      '#max' => 20,
-    ];
-
-    /* Wrapper attributes */
-
-    $form['wrapper_attributes'] = [
-      '#type' => 'details',
-      '#title' => ($this->hasProperty('wrapper_type')) ?
-        $this->t('Wrapper type and attributes') :
-        $this->t('Wrapper attributes'),
-    ];
-    $form['wrapper_attributes']['wrapper_type'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Wrapper type'),
-      '#options' => [
-        'fieldset' => $this->t('Fieldset'),
-        'form_element' => $this->t('Form element'),
-        'container' => $this->t('Container'),
-      ],
-      '#description' => '<b>' . t('Fieldset') . ':</b> ' . t('Wraps inputs in a fieldset.') . ' <strong>' . t('Recommended') . '</strong>' .
-        '<br/><br/><b>' . t('Form element') . ':</b> ' . t('Wraps inputs in a basic form element with title and description.') .
-        '<br/><br/><b>' . t('Container') . ':</b> ' . t('Wraps inputs in a basic div with no title or description.'),
-    ];
-    // Hide element description and display when using a container wrapper.
-    if ($this->hasProperty('wrapper_type')) {
-      $form['element_description']['#states'] = [
-        '!visible' => [
-          ':input[name="properties[wrapper_type]"]' => ['value' => 'container'],
-        ],
-      ];
-      $form['form']['display_container']['#states'] = [
-        '!visible' => [
-          ':input[name="properties[wrapper_type]"]' => ['value' => 'container'],
-        ],
-      ];
-      $form['form']['field_container']['#states'] = [
-        '!visible' => [
-          ':input[name="properties[wrapper_type]"]' => ['value' => 'container'],
-        ],
-      ];
-    }
-
-    $form['wrapper_attributes']['wrapper_attributes'] = [
-      '#type' => 'webform_element_attributes',
-      '#title' => $this->t('Wrapper'),
-      '#class__description' => $this->t("Apply classes to the element's wrapper around both the field and its label. Select 'custom…' to enter custom classes."),
-      '#style__description' => $this->t("Apply custom styles to the element's wrapper around both the field and its label."),
-      '#attributes__description' => $this->t("Enter additional attributes to be added to the element's wrapper."),
-      '#classes' => $this->configFactory->get('webform.settings')->get('element.wrapper_classes'),
-    ];
-
-    /* Element attributes */
-
-    $form['element_attributes'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Element attributes'),
-    ];
-    $form['element_attributes']['attributes'] = [
-      '#type' => 'webform_element_attributes',
-      '#title' => $this->t('Element'),
-      '#classes' => $this->configFactory->get('webform.settings')->get('element.classes'),
-    ];
-
-    /* Label attributes */
-
-    $form['label_attributes'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Label attributes'),
-    ];
-    $form['label_attributes']['label_attributes'] = [
-      '#type' => 'webform_element_attributes',
-      '#title' => $this->t('Label'),
-      '#class__description' => $this->t("Apply classes to the element's label."),
-      '#style__description' => $this->t("Apply custom styles to the element's label."),
-      '#attributes__description' => $this->t("Enter additional attributes to be added to the element's label."),
-    ];
-    // Only display label attribute when the wrapper type is a form element.
-    if ($this->hasProperty('wrapper_type')) {
-      $form['label_attributes']['#states'] = [
-        'visible' => [
-          ':input[name="properties[wrapper_type]"]' => ['value' => 'form_element'],
-        ],
-      ];
-    }
-
-    /* Summary attributes */
-
-    $form['summary_attributes'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Summary attributes'),
-    ];
-    $form['summary_attributes']['summary_attributes'] = [
-      '#type' => 'webform_element_attributes',
-      '#title' => $this->t('Summary'),
-      '#class__description' => $this->t("Apply classes to the details' summary around both the field and its label."),
-      '#style__description' => $this->t("Apply custom styles to the details' summary."),
-      '#attributes__description' => $this->t("Enter additional attributes to be added to the details' summary."),
-    ];
-
-    /* Submission display */
-    $has_edit_twig_access = WebformTwigExtension::hasEditTwigAccess();
-
-    $form['display'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Submission display'),
-    ];
-    // Item.
-    $form['display']['item'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Single item'),
-    ];
-    $form['display']['item']['format'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Item format'),
-      '#description' => $this->t('Select how a single value is displayed.'),
-      '#options' => WebformOptionsHelper::appendValueToText($this->getItemFormats()),
-    ];
-    $format = isset($element_properties['format']) ? $element_properties['format'] : NULL;
-    $format_custom = ($has_edit_twig_access || $format === 'custom');
-    if ($format_custom) {
-      $form['display']['item']['format']['#options'] += ['custom' => $this->t('Custom…')];
-    }
-    $format_custom_states = [
-      'visible' => [':input[name="properties[format]"]' => ['value' => 'custom']],
-      'required' => [':input[name="properties[format]"]' => ['value' => 'custom']],
-    ];
-    $form['display']['item']['format_html'] = [
-      '#type' => 'webform_codemirror',
-      '#mode' => 'twig',
-      '#title' => $this->t('Item format custom HTML'),
-      '#description' => $this->t('The HTML to display for a single element value. You may include HTML or <a href=":href">Twig</a>. You may enter data from the submission as per the "variables" below.', [':href' => 'http://twig.sensiolabs.org/documentation']),
-      '#states' => $format_custom_states,
-      '#access' => $format_custom,
-    ];
-    $form['display']['item']['format_text'] = [
-      '#type' => 'webform_codemirror',
-      '#mode' => 'twig',
-      '#title' => $this->t('Item format custom Text'),
-      '#description' => $this->t('The text to display for a single element value. You may include <a href=":href">Twig</a>. You may enter data from the submission as per the "variables" below.', [':href' => 'http://twig.sensiolabs.org/documentation']),
-      '#states' => $format_custom_states,
-      '#access' => $format_custom,
-    ];
-    if ($has_edit_twig_access) {
-      // Containers use the 'children' variable and inputs use the
-      // 'value' variable.
-      $twig_variables = ($this instanceof ContainerBase) ? ['children' => '{{ children }}'] : ['value' => '{{ value }}'];
-
-      // Composite Twig variables.
-      if ($this instanceof WebformCompositeBase) {
-        // Add composite elements to items.
-        $composite_elements = $this->getCompositeElements();
-        foreach ($composite_elements as $composite_key => $composite_element) {
-          $twig_variables["element.$composite_key"] = "{{ element.$composite_key }}";
-        }
-      }
-
-      $formats = $this->getItemFormats();
-      foreach ($formats as $format_name => $format) {
-        if (is_array($format)) {
-          foreach ($format as $sub_format_name => $sub_format) {
-            $twig_variables["item['$sub_format_name']"] = "{{ item['$sub_format_name'] }}";
-          }
-        }
-        else {
-          $twig_variables["item.$format_name"] = "{{ item.$format_name }}";
-        }
-      }
-      $form['display']['item']['twig'] = WebformTwigExtension::buildTwigHelp($twig_variables);
-      $form['display']['item']['twig']['#states'] = $format_custom_states;
-      WebformElementHelper::setPropertyRecursive($form['display']['item']['twig'], '#access', TRUE);
-    }
-
-    // Items.
-    $form['display']['items'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Multiple items'),
-      '#states' => [
-        'visible' => [
-          [':input[name="properties[multiple][container][cardinality]"]' => ['value' => '-1']],
-          'or',
-          [':input[name="properties[multiple][container][cardinality_number]"]' => ['!value' => 1]],
-        ],
-      ],
-    ];
-    $form['display']['items']['format_items'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Items format'),
-      '#description' => $this->t('Select how multiple values are displayed.'),
-      '#options' => WebformOptionsHelper::appendValueToText($this->getItemsFormats()),
-    ];
-    $format_items = isset($element_properties['format_items']) ? $element_properties['format_items'] : NULL;
-    $format_items_custom = ($has_edit_twig_access || $format_items === 'custom');
-    if ($format_items_custom) {
-      $form['display']['items']['format_items']['#options'] += ['custom' => $this->t('Custom…')];
-    }
-    $format_items_custom_states = [
-      'visible' => [':input[name="properties[format_items]"]' => ['value' => 'custom']],
-      'required' => [':input[name="properties[format_items]"]' => ['value' => 'custom']],
-    ];
-    $form['display']['items']['format_items_html'] = [
-      '#type' => 'webform_codemirror',
-      '#mode' => 'twig',
-      '#title' => $this->t('Items format custom HTML'),
-      '#description' => $this->t('The HTML to display for multiple element values. You may include HTML or <a href=":href">Twig</a>. You may enter data from the submission as per the "variables" below.', [':href' => 'http://twig.sensiolabs.org/documentation']),
-      '#states' => $format_items_custom_states,
-      '#access' => $format_items_custom,
-    ];
-    $form['display']['items']['format_items_text'] = [
-      '#type' => 'webform_codemirror',
-      '#mode' => 'twig',
-      '#title' => $this->t('Items format custom Text'),
-      '#description' => $this->t('The text to display for multiple element values. You may include <a href=":href">Twig</a>. You may enter data from the submission as per the "variables" below.', [':href' => 'http://twig.sensiolabs.org/documentation']),
-      '#states' => $format_items_custom_states,
-      '#access' => $format_items_custom,
-    ];
-    if ($format_items_custom) {
-      $twig_variables = [
-        '{{ value }}',
-        '{{ items }}',
-      ];
-      $form['display']['items']['twig'] = WebformTwigExtension::buildTwigHelp($twig_variables);
-      $form['display']['items']['twig']['#states'] = $format_items_custom_states;
-      WebformElementHelper::setPropertyRecursive($form['display']['items']['twig'], '#access', TRUE);
-    }
-
-    $form['display']['format_attributes'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Display wrapper attributes'),
-    ];
-    $form['display']['format_attributes']['format_attributes'] = [
-      '#type' => 'webform_element_attributes',
-      '#title' => $this->t('Display'),
-      '#class__description' => $this->t("Apply classes to the element's display wrapper. Select 'custom…' to enter custom classes."),
-      '#style__description' => $this->t("Apply custom styles to the element's display wrapper."),
-      '#attributes__description' => $this->t("Enter additional attributes to be added to the element's display wrapper."),
-      '#classes' => $this->configFactory->get('webform.settings')->get('element.wrapper_classes'),
-    ];
-
-    /* Administration */
-
-    $form['admin'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Administration'),
-    ];
-    $form['admin']['private'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('Private'),
-      '#description' => $this->t('Private elements are shown only to users with results access.'),
-      '#weight' => 50,
-      '#return_value' => TRUE,
-    ];
-    $form['admin']['admin_title'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Admin title'),
-      '#description' => $this->t('The admin title will always be displayed when managing elements and viewing & downloading submissions.') .
-        '<br/>' .
-        $this->t("If an element's title is hidden, the element's admin title will be displayed when viewing a submission."),
-    ];
-
-    /**************************************************************************/
-    // Access.
-    /**************************************************************************/
-
-    /* Access */
-
-    $operations = [
-      'create' => [
-        '#title' => $this->t('Create submission'),
-        '#description' => $this->t('Select roles and users that should be able to populate this element when creating a new submission.'),
-        '#open' => TRUE,
-      ],
-      'update' => [
-        '#title' => $this->t('Update submission'),
-        '#description' => $this->t('Select roles and users that should be able to update this element when updating an existing submission.'),
-        '#open' => FALSE,
-      ],
-      'view' => [
-        '#title' => $this->t('View submission'),
-        '#description' => $this->t('Select roles and users that should be able to view this element when viewing a submission.'),
-        '#open' => FALSE,
-      ],
-    ];
-
-    $form['access'] = [
-      '#type' => 'container',
-    ];
-    if (!$this->currentUser->hasPermission('administer webform') && !$this->currentUser->hasPermission('administer webform element access')) {
-      $form['access']['#access'] = FALSE;
-    }
-    foreach ($operations as $operation => $operation_element) {
-      $form['access']['access_' . $operation] = $operation_element + [
-        '#type' => 'details',
-      ];
-      $form['access']['access_' . $operation]['access_' . $operation . '_roles'] = [
-        '#type' => 'webform_roles',
-        '#title' => $this->t('Roles'),
-      ];
-      $form['access']['access_' . $operation]['access_' . $operation . '_users'] = [
-        '#type' => 'webform_users',
-        '#title' => $this->t('Users'),
-      ];
-      $form['access']['access_' . $operation]['access_' . $operation . '_permissions'] = [
-        '#type' => 'webform_permissions',
-        '#title' => $this->t('Permissions'),
-        '#multiple' => TRUE,
-        '#select2' => TRUE,
-      ];
-    }
-
-    /**************************************************************************/
-
-    // Disable #multiple if the element has submission data.
-    if (!$form_object->isNew() && $this->hasProperty('multiple')) {
-      $element_key = $form_object->getKey();
-      if ($this->submissionStorage->hasSubmissionValue($webform, $element_key)) {
-        $form['element']['multiple']['#disabled'] = TRUE;
-        $form['element']['multiple']['#description'] = '<em>' . $this->t('There is data for this element in the database. This setting can no longer be changed.') . '</em>';
-      }
-    }
-
-    // Add warning to all password elements that are stored in the database.
-    if (strpos($this->pluginId, 'password') !== FALSE && !$webform->getSetting('results_disabled')) {
-      $form['element']['password_message'] = [
-        '#type' => 'webform_message',
-        '#message_type' => 'warning',
-        '#message_message' => $this->t('Webform submissions store passwords as plain text.') . ' ' .
-          $this->t('<a href=":href">Encryption</a> should be enabled for this element.', [':href' => 'https://www.drupal.org/project/webform_encrypt']),
-        '#access' => TRUE,
-        '#weight' => -100,
-        '#message_close' => TRUE,
-        '#message_storage' => WebformMessage::STORAGE_SESSION,
-      ];
-    }
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
-    $default_properties = $this->getDefaultProperties();
-    $element_properties = WebformArrayHelper::removePrefix($this->configuration)
-      + $default_properties;
-
-    // Make sure 'format_items' is removed if the element does not
-    // support multiple values.
-    // @todo Webform 8.x-6.x: Remove and assume custom element are fixed.
-    if (!$this->supportsMultipleValues()) {
-      unset(
-        $default_properties['format_items'],
-        $default_properties['format_items_html'],
-        $default_properties['format_items_text']
-      );
-    }
-
-    // Set default and element properties.
-    // Note: Storing this information in the webform's state allows modules to view
-    // and alter this information using webform alteration hooks.
-    $form_state->set('default_properties', $default_properties);
-    $form_state->set('element_properties', $element_properties);
-
-    $form = $this->form($form, $form_state);
-    \Drupal::moduleHandler()->alter('webform_element_configuration_form', $form, $form_state);
-
-    // Get default and element properties which can be altered by WebformElementHandlers.
-    // @see \Drupal\webform\Plugin\WebformElement\WebformEntityReferenceTrait::form
-    $element_properties = $form_state->get('element_properties');
-
-    // Copy element properties to custom properties which will be determined
-    // as the default values are set.
-    $custom_properties = $element_properties;
-
-    // Populate the webform.
-    $this->setConfigurationFormDefaultValueRecursive($form, $custom_properties);
-
-    // Set fieldset weights so that they appear first.
-    foreach ($form as &$element) {
-      if (is_array($element) && !isset($element['#weight']) && isset($element['#type']) && $element['#type'] == 'fieldset') {
-        $element['#weight'] = -20;
-      }
-    }
-
-    // Store 'type' as a hardcoded value and make sure it is always first.
-    // Also always remove the 'webform_*' prefix from the type name.
-    if (isset($custom_properties['type'])) {
-      $form['type'] = [
-        '#type' => 'value',
-        '#value' => $custom_properties['type'],
-        '#parents' => ['properties', 'type'],
-      ];
-      unset($custom_properties['type']);
-    }
-
-    // Allow custom properties (i.e. #attributes) to be added to the element.
-    $form['custom'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Custom settings'),
-      '#open' => $custom_properties ? TRUE : FALSE,
-      '#access' => $this->currentUser->hasPermission('edit webform source'),
-    ];
-    if ($api_url = $this->getPluginApiUrl()) {
-      $t_args = [
-        ':href' => $api_url->toString(),
-        '%label' => $this->getPluginLabel(),
-      ];
-      $form['custom']['#description'] = $this->t('Read the %label element\'s <a href=":href">API documentation</a>.', $t_args);
-    }
-
-    $form['custom']['properties'] = [
-      '#type' => 'webform_codemirror',
-      '#mode' => 'yaml',
-      '#title' => $this->t('Custom properties'),
-      '#description' => $this->t('Properties do not have to be prepended with a hash (#) character, the hash character will be automatically added to the custom properties.') .
-        '<br /><br />' .
-        $this->t('These properties and callbacks are not allowed: @properties', ['@properties' => WebformArrayHelper::toString(WebformArrayHelper::addPrefix(WebformElementHelper::$ignoredProperties))]),
-      '#default_value' => $custom_properties ,
-      '#parents' => ['properties', 'custom'],
-    ];
-
-    $this->tokenManager->elementValidate($form);
-
-    // Set custom properties.
-    // Note: Storing this information in the webform's state allows modules to
-    // view and alter this information using webform alteration hooks.
-    $form_state->set('custom_properties', $custom_properties);
-
-    return $this->buildConfigurationFormTabs($form, $form_state);
-  }
-
-  /**
-   * Get form--inline container which is used for side-by-side element layout.
-   *
-   * @return array
-   *   A container element with .form--inline class if inline help text is
-   *   enabled.
-   */
-  protected function getFormInlineContainer() {
-    $help_enabled = $this->configFactory->get('webform.settings')->get('ui.description_help');
-    return [
-      '#type' => 'container',
-      '#attributes' => ($help_enabled) ? ['class' => ['form--inline', 'clearfix', 'webform-ui-element-form-inline--input']] : [],
-    ];
-  }
-
-  /**
-   * Build configuration form tabs.
-   *
-   * @param array $form
-   *   An associative array containing the initial structure of the plugin form.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The current state of the form.
-   *
-   * @return array
-   *   The plugin form with tabs.
-   */
-  protected function buildConfigurationFormTabs(array $form, FormStateInterface $form_state) {
-    $tabs = [
-      'conditions' => [
-        'title' => $this->t('Conditions'),
-        'elements' => [
-          'conditional_logic',
-        ],
-        'weight' => 10,
-      ],
-      'advanced' => [
-        'title' => $this->t('Advanced'),
-        'elements' => [
-          'default',
-          'multiple',
-          'wrapper_attributes',
-          'element_attributes',
-          'label_attributes',
-          'summary_attributes',
-          'display',
-          'admin',
-          'options_properties',
-          'custom',
-        ],
-        'weight' => 20,
-      ],
-      'access' => [
-        'title' => $this->t('Access'),
-        'elements' => [
-          'access',
-        ],
-        'weight' => 30,
-      ],
-    ];
-    return WebformFormHelper::buildTabs($form, $tabs, $form_state->get('active_tab'));
-  }
-
-  /**
-   * Set configuration webform default values recursively.
-   *
-   * @param array $form
-   *   A webform render array.
-   * @param array $element_properties
-   *   The element's properties without hash prefix. Any property that is found
-   *   in the webform will be populated and unset from
-   *   $element_properties array.
-   *
-   * @return bool
-   *   TRUE is the webform has any inputs.
-   */
-  protected function setConfigurationFormDefaultValueRecursive(array &$form, array &$element_properties) {
-    $has_input = FALSE;
-
-    foreach ($form as $property_name => &$property_element) {
-      // Skip all properties.
-      if (is_string($property_name) && Element::property($property_name)) {
-        continue;
-      }
-
-      // Skip Entity reference element 'selection_settings'.
-      // @see \Drupal\webform\Plugin\WebformElement\WebformEntityReferenceTrait::form
-      // @todo Fix entity reference Ajax and move code WebformEntityReferenceTrait.
-      if (!empty($property_element['#tree']) && $property_name == 'selection_settings') {
-        unset($element_properties[$property_name]);
-        $property_element['#parents'] = ['properties', $property_name];
-        $has_input = TRUE;
-        continue;
-      }
-
-      // Determine if the property element is an input using the webform element
-      // manager.
-      // Note: #access is used to protect inputs and containers that should
-      // always be visible.
-      $is_input = $this->elementManager->getElementInstance($property_element)->isInput($property_element);
-      if ($is_input) {
-        if (array_key_exists($property_name, $element_properties)) {
-          // If this property exists, then set its default value.
-          $this->setConfigurationFormDefaultValue($form, $element_properties, $property_element, $property_name);
-          $has_input = TRUE;
-        }
-        elseif (empty($form[$property_name]['#access'])) {
-          // Else completely remove the property element from the webform.
-          unset($form[$property_name]);
-        }
-      }
-      else {
-        // Recurse down this container and see if it's children have inputs.
-        $container_has_input = $this->setConfigurationFormDefaultValueRecursive($property_element, $element_properties);
-        if ($container_has_input) {
-          $has_input = TRUE;
-        }
-        elseif (empty($form[$property_name]['#access'])) {
-          unset($form[$property_name]);
-        }
-      }
-    }
-
-    return $has_input;
-  }
-
-  /**
-   * Set an element's configuration webform element default value.
-   *
-   * @param array $form
-   *   An element's configuration webform.
-   * @param array $element_properties
-   *   The element's properties without hash prefix.
-   * @param array $property_element
-   *   The webform input used to set an element's property.
-   * @param string $property_name
-   *   THe property's name.
-   */
-  protected function setConfigurationFormDefaultValue(array &$form, array &$element_properties, array &$property_element, $property_name) {
-    $default_value = $element_properties[$property_name];
-    $type = (isset($property_element['#type'])) ? $property_element['#type'] : NULL;
-
-    switch ($type) {
-      case 'entity_autocomplete':
-        $target_type = $property_element['#target_type'];
-        $target_storage = $this->entityTypeManager->getStorage($target_type);
-        if (!empty($property_element['#tags'])) {
-          $property_element['#default_value'] = ($default_value) ? $target_storage->loadMultiple($default_value) : [];
-        }
-        else {
-          $property_element['#default_value'] = ($default_value) ? $target_storage->load($default_value) : NULL;
-        }
-        break;
-
-      case 'radios':
-      case 'select':
-        // Handle invalid default_value throwing
-        // "An illegal choice has been detected…" error.
-        if (!is_array($default_value) && isset($property_element['#options'])) {
-          $flattened_options = OptGroup::flattenOptions($property_element['#options']);
-          if (!isset($flattened_options[$default_value])) {
-            $default_value = NULL;
-          }
-        }
-        $property_element['#default_value'] = $default_value;
-        break;
-
-      default:
-        // Convert default_value array into a comma delimited list.
-        // This is applicable to elements that support #multiple #options.
-        if (is_array($default_value) && $property_name == 'default_value' && !$this->isComposite()) {
-          $property_element['#default_value'] = implode(', ', $default_value);
-        }
-        elseif (is_bool($default_value) && $property_name == 'default_value') {
-          $property_element['#default_value'] = $default_value ? 1 : 0;
-        }
-        elseif (is_null($default_value) && $property_name == 'default_value') {
-          $property_element['#default_value'] = (string) $default_value;
-        }
-        else {
-          $property_element['#default_value'] = $default_value;
-        }
-        break;
-
-    }
-
-    $property_element['#parents'] = ['properties', $property_name];
-    unset($element_properties[$property_name]);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
-    $properties = $this->getConfigurationFormProperties($form, $form_state);
-
-    $ignored_properties = WebformElementHelper::getIgnoredProperties($properties);
-    foreach ($ignored_properties as $ignored_property => $ignored_message) {
-      // Display custom messages.
-      if ($ignored_property != $ignored_message) {
-        unset($ignored_properties[$ignored_property]);
-        $form_state->setErrorByName('custom', $ignored_message);
-      }
-    }
-
-    // Display ignored properties message.
-    if ($ignored_properties) {
-      $t_args = [
-        '@properties' => WebformArrayHelper::toString($ignored_properties),
-      ];
-      $form_state->setErrorByName('custom', $this->t('Element contains ignored/unsupported properties: @properties', $t_args));
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
-    // Generally, elements will not be processing any submitted properties.
-    // It is possible that a custom element might need to call a third-party API
-    // to 'register' the element.
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getConfigurationFormProperties(array &$form, FormStateInterface $form_state) {
-    $element_properties = $form_state->getValues();
-
-    // Get default properties so that they can be unset below.
-    $default_properties = $form_state->get('default_properties');
-
-    // Get custom properties.
-    if (isset($element_properties['custom'])) {
-      if (is_array($element_properties['custom'])) {
-        $element_properties += $element_properties['custom'];
-      }
-      unset($element_properties['custom']);
-    }
-
-    // Remove all hash prefixes so that we can filter out any default
-    // properties.
-    WebformArrayHelper::removePrefix($element_properties);
-
-    // Build a temp element used to see if multiple value and/or composite
-    // elements need to be supported.
-    $element = WebformArrayHelper::addPrefix($element_properties);
-    foreach ($element_properties as $property_name => $property_value) {
-      if (!array_key_exists($property_name, $default_properties)) {
-        continue;
-      }
-
-      $this->getConfigurationFormProperty($element_properties, $property_name, $property_value, $element);
-
-      // Unset element property that matched the default property.
-      switch ($property_name) {
-        case 'multiple':
-          // The #multiple property element is converted to the correct datatype
-          // so we are looking for 'strict equality' (===).
-          // This prevents #multiple: 2 from being interpeted as TRUE.
-          // @see \Drupal\webform\Element\WebformElementMultiple::validateWebformElementMultiple
-          // @see \Drupal\webform\Plugin\WebformElement\Checkboxes::defaultProperties
-          if ($default_properties[$property_name] === $element_properties[$property_name]) {
-            unset($element_properties[$property_name]);
-          }
-          break;
-
-        default:
-          // Most elements properties are strings or numbers and we need to use
-          // 'type-converting equality' (==) because all numbers are posted
-          // back to the server as strings.
-          if ($default_properties[$property_name] == $element_properties[$property_name]) {
-            unset($element_properties[$property_name]);
-          }
-
-          // Cast data types (except #multiple).
-          if (isset($element_properties[$property_name])) {
-            if (is_bool($default_properties[$property_name])) {
-              $element_properties[$property_name] = (bool) $element_properties[$property_name];
-            }
-            elseif (is_null($default_properties[$property_name]) || is_numeric($default_properties[$property_name])) {
-              $value = $element_properties[$property_name];
-              $cast_value = ($value == (int) $value) ? (int) $value : (float) $value;
-              if ($value == $cast_value) {
-                $element_properties[$property_name] = $cast_value;
-              }
-            }
-          }
-          break;
-      }
-    }
-
-    // Make sure #type is always first.
-    if (isset($element_properties['type'])) {
-      $element_properties = ['type' => $element_properties['type']] + $element_properties;
-    }
-
-    return WebformArrayHelper::addPrefix($element_properties);
-  }
-
-  /**
-   * Get configuration property value.
-   *
-   * @param array $properties
-   *   An associative array of submitted properties.
-   * @param string $property_name
-   *   The property's name.
-   * @param mixed $property_value
-   *   The property's value.
-   * @param array $element
-   *   The element whose properties are being updated.
-   */
-  protected function getConfigurationFormProperty(array &$properties, $property_name, $property_value, array $element) {
-    if ($property_name == 'default_value' && is_string($property_value) && $property_value && $this->hasMultipleValues($element)) {
-      $properties[$property_name] = preg_split('/\s*,\s*/', $property_value);
-    }
-  }
-
-  /**
-   * Determine if the element has a composite field wrapper.
-   *
-   * @return bool
-   *   TRUE if the element has a composite field wrapper.
-   */
-  protected function hasCompositeFormElementWrapper() {
-    $callbacks = $this->elementInfo->getInfoProperty($this->getPluginId(), '#pre_render') ?: [];
-    foreach ($callbacks as $callback) {
-      if (is_array($callback)
-        && in_array($callback[1], ['preRenderCompositeFormElement', 'preRenderWebformCompositeFormElement'])) {
-        return TRUE;
-      }
-    }
-    return FALSE;
-  }
-
-}
diff --git a/web/modules/webform/src/Plugin/WebformExporter/DelimitedWebformExporter.php b/web/modules/webform/src/Plugin/WebformExporter/DelimitedWebformExporter.php
index 2b6cb913f5..748799b125 100644
--- a/web/modules/webform/src/Plugin/WebformExporter/DelimitedWebformExporter.php
+++ b/web/modules/webform/src/Plugin/WebformExporter/DelimitedWebformExporter.php
@@ -31,7 +31,7 @@ public function defaultConfiguration() {
    */
   public function setConfiguration(array $configuration) {
     parent::setConfiguration($configuration);
-    if ($this->configuration['delimiter'] == '\t') {
+    if ($this->configuration['delimiter'] === '\t') {
       $this->configuration['delimiter'] = "\t";
     }
     return $this;
diff --git a/web/modules/webform/src/Plugin/WebformExporter/TabularBaseWebformExporter.php b/web/modules/webform/src/Plugin/WebformExporter/TabularBaseWebformExporter.php
index aae2a6df0e..2ee5e576d8 100644
--- a/web/modules/webform/src/Plugin/WebformExporter/TabularBaseWebformExporter.php
+++ b/web/modules/webform/src/Plugin/WebformExporter/TabularBaseWebformExporter.php
@@ -46,7 +46,7 @@ protected function buildHeader() {
       // Build a webform element for each field definition so that we can
       // use WebformElement::buildExportHeader(array $element, $export_options).
       $element = [
-        '#type' => ($field_definition['type'] == 'entity_reference') ? 'entity_autocomplete' : 'element',
+        '#type' => ($field_definition['type'] === 'entity_reference') ? 'entity_autocomplete' : 'element',
         '#admin_title' => '',
         '#title' => (string) $field_definition['title'],
         '#webform_key' => (string) $field_definition['name'],
@@ -142,7 +142,7 @@ protected function formatRecordFieldDefinitionValue(array &$record, WebformSubmi
         $entity_id = $webform_submission->entity_id->value;
         $entity = $this->entityTypeManager->getStorage($entity_type)->load($entity_id);
         if ($entity) {
-          $record[] = ($field_type == 'entity_url' && $entity->hasLinkTemplate('canonical')) ? $entity->toUrl()->setOption('absolute', TRUE)->toString() : $entity->label();
+          $record[] = ($field_type === 'entity_url' && $entity->hasLinkTemplate('canonical')) ? $entity->toUrl()->setOption('absolute', TRUE)->toString() : $entity->label();
         }
         else {
           $record[] = '';
diff --git a/web/modules/webform/src/Plugin/WebformExporterBase.php b/web/modules/webform/src/Plugin/WebformExporterBase.php
index 04a737893b..837c47c8c0 100644
--- a/web/modules/webform/src/Plugin/WebformExporterBase.php
+++ b/web/modules/webform/src/Plugin/WebformExporterBase.php
@@ -43,7 +43,7 @@ abstract class WebformExporterBase extends PluginBase implements WebformExporter
   protected $entityTypeManager;
 
   /**
-   * Webform submission storage.
+   * The webform submission storage.
    *
    * @var \Drupal\webform\WebformSubmissionStorageInterface
    */
@@ -263,7 +263,7 @@ public function writeFooter() {}
    * {@inheritdoc}
    */
   public function getFileTempDirectory() {
-    return $this->configFactory->get('webform.settings')->get('export.temp_directory') ?: file_directory_temp();
+    return $this->configFactory->get('webform.settings')->get('export.temp_directory') ?: \Drupal::service('file_system')->getTempDirectory();
   }
 
   /**
@@ -334,17 +334,17 @@ public function getArchiveFileName() {
    * {@inheritdoc}
    */
   public function getArchiveType() {
-    return ($this->configuration['archive_type'] === static::ARCHIVE_ZIP
+    return ($this->configuration['archive_type'] === WebformExporterInterface::ARCHIVE_ZIP
       && class_exists('\ZipArchive'))
-      ? static::ARCHIVE_ZIP
-      : static::ARCHIVE_TAR;
+      ? WebformExporterInterface::ARCHIVE_ZIP
+      : WebformExporterInterface::ARCHIVE_TAR;
   }
 
   /**
    * {@inheritdoc}
    */
   public function getArchiveFileExtension() {
-    return ($this->getArchiveType() === static::ARCHIVE_ZIP)
+    return ($this->getArchiveType() === WebformExporterInterface::ARCHIVE_ZIP)
       ? 'zip'
       : 'tar.gz';
   }
@@ -358,7 +358,7 @@ public function addToArchive($path, $name, array $options = []) {
       'close' => FALSE,
     ];
 
-    if ($this->getArchiveType() === static::ARCHIVE_ZIP) {
+    if ($this->getArchiveType() === WebformExporterInterface::ARCHIVE_ZIP) {
       $this->addToZipFile($path, $name, $options);
     }
     else {
@@ -439,7 +439,7 @@ protected function addToZipFile($path, $name, array $options = []) {
       }
       else {
         // Add file to ZIP file.
-        // Get file name from the path and remove path option..
+        // Get file name from the path and remove path option.
         $file_name = $path;
         if ($options['remove_path']) {
           $file_name = preg_replace('#^' . $options['remove_path'] . '#', '', $file_name);
diff --git a/web/modules/webform/src/Plugin/WebformExporterInterface.php b/web/modules/webform/src/Plugin/WebformExporterInterface.php
index 7124de7a9f..56f9056d07 100644
--- a/web/modules/webform/src/Plugin/WebformExporterInterface.php
+++ b/web/modules/webform/src/Plugin/WebformExporterInterface.php
@@ -122,7 +122,7 @@ public function writeFooter();
    * Get export file temp directory.
    *
    * @return string
-   *   The export file temp directory..
+   *   The export file temp directory.
    */
   public function getFileTempDirectory();
 
diff --git a/web/modules/webform/src/Plugin/WebformExporterManager.php b/web/modules/webform/src/Plugin/WebformExporterManager.php
index 1506f730b3..fbe680e34e 100644
--- a/web/modules/webform/src/Plugin/WebformExporterManager.php
+++ b/web/modules/webform/src/Plugin/WebformExporterManager.php
@@ -54,9 +54,9 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
   /**
    * {@inheritdoc}
    */
-  public function getSortedDefinitions(array $definitions = NULL) {
+  public function getSortedDefinitions(array $definitions = NULL, $sort_by = 'label') {
     // Sort the plugins first by category, then by label.
-    $definitions = $this->traitGetSortedDefinitions($definitions);
+    $definitions = $this->traitGetSortedDefinitions($definitions, $sort_by);
     return $definitions;
   }
 
diff --git a/web/modules/webform/src/Plugin/WebformHandler/EmailWebformHandler.php b/web/modules/webform/src/Plugin/WebformHandler/EmailWebformHandler.php
index 59fec6dbe4..59e2af8436 100644
--- a/web/modules/webform/src/Plugin/WebformHandler/EmailWebformHandler.php
+++ b/web/modules/webform/src/Plugin/WebformHandler/EmailWebformHandler.php
@@ -121,7 +121,7 @@ class EmailWebformHandler extends WebformHandlerBase implements WebformHandlerMe
   protected $themeManager;
 
   /**
-   * A webform element plugin manager.
+   * The webform element plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
@@ -573,7 +573,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
       '#default_value' => $body_select_default_value,
     ];
     foreach ($body_default_values as $format => $default_value) {
-      if ($format == 'html') {
+      if ($format === 'html') {
         $form['message']['body_custom_' . $format] = [
           '#type' => 'webform_html_editor',
           '#format' => $this->configFactory->get('webform.settings')->get('html_editor.mail_format'),
@@ -592,11 +592,11 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
         '#states' => [
           'visible' => [
             ':input[name="settings[body]"]' => ['value' => WebformSelectOther::OTHER_OPTION],
-            ':input[name="settings[html]"]' => ['checked' => ($format == 'html') ? TRUE : FALSE],
+            ':input[name="settings[html]"]' => ['checked' => ($format === 'html') ? TRUE : FALSE],
           ],
           'required' => [
             ':input[name="settings[body]"]' => ['value' => WebformSelectOther::OTHER_OPTION],
-            ':input[name="settings[html]"]' => ['checked' => ($format == 'html') ? TRUE : FALSE],
+            ':input[name="settings[html]"]' => ['checked' => ($format === 'html') ? TRUE : FALSE],
           ],
         ],
       ];
@@ -615,7 +615,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
         '#states' => [
           'visible' => [
             ':input[name="settings[body]"]' => ['value' => static::DEFAULT_VALUE],
-            ':input[name="settings[html]"]' => ['checked' => ($format == 'html') ? TRUE : FALSE],
+            ':input[name="settings[html]"]' => ['checked' => ($format === 'html') ? TRUE : FALSE],
           ],
         ],
       ];
@@ -935,7 +935,7 @@ public function getMessage(WebformSubmissionInterface $webform_submission) {
       list($configuration_name, $configuration_type) = (strpos($configuration_key, '_') !== FALSE) ? explode('_', $configuration_key) : [$configuration_key, 'text'];
 
       // Set options and continue.
-      if ($configuration_type == 'options') {
+      if ($configuration_type === 'options') {
         $message[$configuration_key] = $configuration_value;
         continue;
       }
@@ -949,13 +949,13 @@ public function getMessage(WebformSubmissionInterface $webform_submission) {
       }
 
       // Set email addresses.
-      if ($configuration_type == 'mail') {
+      if ($configuration_type === 'mail') {
         $emails = $this->getMessageEmails($webform_submission, $configuration_name, $configuration_value);
         $configuration_value = implode(',', array_unique($emails));
       }
 
       // If Twig enabled render and body, render the Twig template.
-      if ($configuration_key == 'body' && $this->configuration['twig']) {
+      if ($configuration_key === 'body' && $this->configuration['twig']) {
         $message[$configuration_key] = WebformTwigExtension::renderTwigTemplate($webform_submission, $configuration_value, $token_options);
       }
       else {
@@ -1036,8 +1036,8 @@ protected function getMessageEmails(WebformSubmissionInterface $webform_submissi
       $email_options = WebformOptionsHelper::decodeConfig($this->configuration[$configuration_name . '_options']);
 
       // Set default email address.
-      if (!empty($email_options[self::DEFAULT_OPTION])) {
-        $emails[] = $email_options[self::DEFAULT_OPTION];
+      if (!empty($email_options[static::DEFAULT_OPTION])) {
+        $emails[] = $email_options[static::DEFAULT_OPTION];
       }
 
       // Get submission email addresses as an array.
@@ -1051,8 +1051,8 @@ protected function getMessageEmails(WebformSubmissionInterface $webform_submissi
 
       // Set empty email address.
       if (empty($options_values)) {
-        if (!empty($email_options[self::EMPTY_OPTION])) {
-          $emails[] = $email_options[self::EMPTY_OPTION];
+        if (!empty($email_options[static::EMPTY_OPTION])) {
+          $emails[] = $email_options[static::EMPTY_OPTION];
         }
       }
       // Loop through options values and collect email addresses.
@@ -1062,8 +1062,8 @@ protected function getMessageEmails(WebformSubmissionInterface $webform_submissi
             $emails[] = $email_options[$option_value];
           }
           // Set other email address.
-          elseif (!empty($email_options[self::OTHER_OPTION])) {
-            $emails[] = $email_options[self::OTHER_OPTION];
+          elseif (!empty($email_options[static::OTHER_OPTION])) {
+            $emails[] = $email_options[static::OTHER_OPTION];
           }
         }
       }
@@ -1144,8 +1144,6 @@ public function sendMessage(WebformSubmissionInterface $webform_submission, arra
     $from = $message['from_mail'];
 
     // Remove less than (<) and greater (>) than from name.
-    // @todo Figure out the proper way to encode special characters.
-    // Note: PhpMail call.
     $message['from_name'] = preg_replace('/[<>]/', '', $message['from_name']);
 
     if (!empty($message['from_name'])) {
@@ -1178,13 +1176,11 @@ public function sendMessage(WebformSubmissionInterface $webform_submission, arra
     $theme_name = $this->configuration['theme_name'];
     $message['body'] = trim((string) $this->themeManager->renderPlain($build, $theme_name));
 
+    // Html body needs to be Markup so that relative URLs are converted
+    // to absolute.
+    // @see \Drupal\Core\Mail\MailManager::doMail
     if ($this->configuration['html']) {
-      switch ($this->getMailSystemFormatter()) {
-        case 'swiftmailer':
-          // SwiftMailer requires that the body be valid Markup.
-          $message['body'] = Markup::create($message['body']);
-          break;
-      }
+      $message['body'] = Markup::create($message['body']);
     }
 
     // Send message.
@@ -1361,7 +1357,7 @@ protected function supportsHtml() {
   protected function supportsAttachments() {
     // If 'system.mail.interface.default' is 'test_mail_collector'
     // allow email attachments during testing.
-    if ($this->configFactory->get('system.mail')->get('interface.default') == 'test_mail_collector') {
+    if ($this->configFactory->get('system.mail')->get('interface.default') === 'test_mail_collector') {
       return TRUE;
     }
 
@@ -1411,7 +1407,7 @@ protected function buildDebugMessage(WebformSubmissionInterface $webform_submiss
       'subject' => $this->t('Subject'),
     ];
     foreach ($values as $name => $title) {
-      if ($title == '---') {
+      if ($title === '---') {
         $build[$name] = ['#markup' => '<hr />'];
       }
       elseif (!empty($message[$name])) {
@@ -1538,7 +1534,7 @@ protected function buildElement($name, $title, $label, $required = FALSE, array
       '#other__title' => $title,
       '#other__title_display' => 'invisible',
       '#other__placeholder' => $this->t('Enter @label…', ['@label' => $label]),
-      '#other__type' => ($element_type == 'mail') ? 'webform_email_multiple' : 'textfield',
+      '#other__type' => ($element_type === 'mail') ? 'webform_email_multiple' : 'textfield',
       '#other__allow_tokens' => TRUE,
       '#required' => $required,
       '#default_value' => $this->configuration[$name],
@@ -1605,12 +1601,12 @@ protected function buildElement($name, $title, $label, $required = FALSE, array
         $value = '<b>' . $value . '</b>';
       });
       if (preg_match('/_other$/', $options_element['#type'])) {
-        $mapping_options[self::OTHER_OPTION] = $this->t("Other (Used when 'other' value is entered)");
+        $mapping_options[static::OTHER_OPTION] = $this->t("Other (Used when 'other' value is entered)");
       }
       if (empty($options_element['#required'])) {
-        $mapping_options[self::EMPTY_OPTION] = $this->t('Empty (Used when no option is selected)');
+        $mapping_options[static::EMPTY_OPTION] = $this->t('Empty (Used when no option is selected)');
       }
-      $mapping_options[self::DEFAULT_OPTION] = $this->t('Default (This email address will always be included)');
+      $mapping_options[static::DEFAULT_OPTION] = $this->t('Default (This email address will always be included)');
 
       // Set placeholder emails.
       $destination_placeholder_emails = ['example@example.com', '[site:mail]'];
diff --git a/web/modules/webform/src/Plugin/WebformHandler/RemotePostWebformHandler.php b/web/modules/webform/src/Plugin/WebformHandler/RemotePostWebformHandler.php
index d583f219c1..4c175b4e36 100644
--- a/web/modules/webform/src/Plugin/WebformHandler/RemotePostWebformHandler.php
+++ b/web/modules/webform/src/Plugin/WebformHandler/RemotePostWebformHandler.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Logger\LoggerChannelFactoryInterface;
+use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\Routing\TrustedRedirectResponse;
 use Drupal\Core\Serialization\Yaml;
 use Drupal\Core\Extension\ModuleHandlerInterface;
@@ -74,7 +75,7 @@ class RemotePostWebformHandler extends WebformHandlerBase {
   protected $messageManager;
 
   /**
-   * A webform element plugin manager.
+   * The webform element plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
@@ -193,10 +194,10 @@ public function defaultConfiguration() {
       'draft_updated_custom_data' => '',
       'converted_url' => '',
       'converted_custom_data' => '',
-      // Custom error response messages.
+      // Custom response messages.
       'message' => '',
       'messages' => [],
-      // Custom error response redirect URL.
+      // Custom response redirect URL.
       'error_url' => '',
     ];
   }
@@ -318,8 +319,16 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
     ];
     $form['additional']['cast'] = [
       '#type' => 'checkbox',
-      '#title' => $this->t('Cast posted data'),
-      '#description' => $this->t('If checked, posted data will be casted to booleans and floats as needed.'),
+      '#title' => $this->t('Cast posted element value and custom data'),
+      '#description' => $this->t('If checked, posted element values will be cast to integers, floats, and booleans as needed. Custom data can be cast by placing the desired type in parentheses before the value or token. (i.e. "(int) [webform_submission:value:total]" or "(int) 100")') .
+        '<br/>' .
+        '<br/>' .
+        $this->t('For custom data, the casts allowed are:') .
+        '<ul>' .
+        '<li>' . $this->t('@cast - cast to @type', ['@cast' => '(int), (integer)', '@type' => 'integer']) . '</li>' .
+        '<li>' . $this->t('@cast - cast to @type', ['@cast' => '(float), (double), (real)', '@type' => 'float']) . '</li>' .
+        '<li>' . $this->t('@cast - cast to @type', ['@cast' => '(bool), (boolean)', '@type' => 'boolean']) . '</li>' .
+        '</ul>',
       '#return_value' => TRUE,
       '#default_value' => $this->configuration['cast'],
     ];
@@ -340,7 +349,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
     $form['additional']['message'] = [
       '#type' => 'webform_html_editor',
       '#title' => $this->t('Custom error response message'),
-      '#description' => $this->t('This message is displayed when the response status code is not 2xx'),
+      '#description' => $this->t('This message is displayed when the response status code is not 2xx.') . '<br/><br/>' . $this->t('Defaults to: %value', ['%value' => $this->messageManager->render(WebformMessageManagerInterface::SUBMISSION_EXCEPTION_MESSAGE)]),
       '#default_value' => $this->configuration['message'],
     ];
     $form['additional']['messages_token'] = [
@@ -350,8 +359,8 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
     ];
     $form['additional']['messages'] = [
       '#type' => 'webform_multiple',
-      '#title' => $this->t('Custom error response messages'),
-      '#description' => $this->t('Enter custom response messages for specific status codes.') . '<br/>' . $this->t('Defaults to: %value', ['%value' => $this->messageManager->render(WebformMessageManagerInterface::SUBMISSION_EXCEPTION_MESSAGE)]),
+      '#title' => $this->t('Custom response messages'),
+      '#description' => $this->t('Enter custom response messages for specific status codes.'),
       '#empty_items' => 0,
       '#no_items_message' => $this->t('No error response messages entered. Please add messages below.'),
       '#add' => FALSE,
@@ -360,6 +369,9 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
           '#type' => 'webform_select_other',
           '#title' => $this->t('Response status code'),
           '#options' => [
+            '200' => $this->t('200 OK'),
+            '201' => $this->t('201 Created'),
+            '204' => $this->t('204 No Content'),
             '400' => $this->t('400 Bad Request'),
             '401' => $this->t('401 Unauthorized'),
             '403' => $this->t('403 Forbidden'),
@@ -493,7 +505,7 @@ protected function remotePost($state, WebformSubmissionInterface $webform_submis
       }
       else {
         $method = strtolower($request_method);
-        $request_options[($request_type == 'json' ? 'json' : 'form_params')] = $this->getRequestData($state, $webform_submission);
+        $request_options[($request_type === 'json' ? 'json' : 'form_params')] = $this->getRequestData($state, $webform_submission);
         $response = $this->httpClient->$method($request_url, $request_options);
       }
     }
@@ -509,12 +521,14 @@ protected function remotePost($state, WebformSubmissionInterface $webform_submis
     }
 
     // Display submission exception if response code is not 2xx.
-    $status_code = $response->getStatusCode();
-    if ($status_code < 200 || $status_code >= 300) {
-      $message = $this->t('Remote post request return @status_code status code.', ['@status_code' => $status_code]);
+    if ($this->responseHasError($response)) {
+      $message = $this->t('Remote post request return @status_code status code.', ['@status_code' => $response->getStatusCode()]);
       $this->handleError($state, $message, $request_url, $request_method, $request_type, $request_options, $response);
       return;
     }
+    else {
+      $this->displayCustomResponseMessage($response, FALSE);
+    }
 
     // If debugging is enabled, display the request and response.
     $this->debug(t('Remote post successful!'), $state, $request_url, $request_method, $request_type, $request_options, $response, 'warning');
@@ -596,23 +610,34 @@ protected function getRequestData($state, WebformSubmissionInterface $webform_su
         }
       }
       elseif (!empty($this->configuration['cast'])) {
+        // Cast value.
         $data[$element_key] = $this->castRequestValues($element, $element_plugin, $element_value);
       }
     }
 
+    // Replace tokens.
+    $data = $this->replaceTokens($data, $webform_submission);
+
     // Append custom data.
     if (!empty($this->configuration['custom_data'])) {
-      $data = Yaml::decode($this->configuration['custom_data']) + $data;
+      $custom_data = Yaml::decode($this->configuration['custom_data']);
+      // Replace tokens.
+      $custom_data = $this->replaceTokens($custom_data, $webform_submission);
+      // Cast custom data.
+      $custom_data = $this->castCustomData($custom_data);
+      $data = $custom_data + $data;
     }
 
     // Append state custom data.
     if (!empty($this->configuration[$state . '_custom_data'])) {
-      $data = Yaml::decode($this->configuration[$state . '_custom_data']) + $data;
+      $state_custom_data = Yaml::decode($this->configuration[$state . '_custom_data']);
+      // Replace tokens.
+      $state_custom_data = $this->replaceTokens($state_custom_data, $webform_submission);
+      // Cast custom data.
+      $state_custom_data = $this->castCustomData($state_custom_data);
+      $data = $state_custom_data + $data;
     }
 
-    // Replace tokens.
-    $data = $this->replaceTokens($data, $webform_submission);
-
     return $data;
   }
 
@@ -679,6 +704,49 @@ protected function castRequestValue(array $element, WebformElementInterface $ele
     }
   }
 
+  /**
+   * Cast custom data.
+   *
+   * @param array $data
+   *   Custom data.
+   *
+   * @return array
+   *   The custom data with value casted
+   */
+  protected function castCustomData(array $data) {
+    if (empty($this->configuration['cast'])) {
+      return $data;
+    }
+
+    foreach ($data as $key => $value) {
+      if (is_array($value)) {
+        $data[$key] = $this->castCustomData($value);
+      }
+      elseif (is_string($value) && preg_match('/^\((int|integer|bool|boolean|float|double|real)\)\s*(.+)$/', $value, $match)) {
+        $type_cast = $match[1];
+        $type_value = $match[2];
+        switch ($type_cast) {
+          case 'int':
+          case 'integer':
+            $data[$key] = (int) $type_value;
+            break;
+
+          case 'bool':
+          case 'boolean';
+            $data[$key] = (bool) $type_value;
+            break;
+
+          case 'float':
+          case 'double':
+          case 'real':
+            $data[$key] = (float) $type_value;
+            break;
+        }
+      }
+    }
+    return $data;
+  }
+
   /**
    * Get request file data.
    *
@@ -763,7 +831,7 @@ protected function isResultsEnabled() {
    *   TRUE if saving of draft is enabled.
    */
   protected function isDraftEnabled() {
-    return $this->isResultsEnabled() && ($this->getWebform()->getSetting('draft') != WebformInterface::DRAFT_NONE);
+    return $this->isResultsEnabled() && ($this->getWebform()->getSetting('draft') !== WebformInterface::DRAFT_NONE);
   }
 
   /**
@@ -975,18 +1043,7 @@ protected function handleError($state, $message, $request_url, $request_method,
       ->error('@form webform remote @type post (@state) to @url failed. @message', $context);
 
     // Display custom or default exception message.
-    if ($custom_response_message = $this->getCustomResponseMessage($response)) {
-      $token_data = [
-        'webform_handler' => [
-          $this->getHandlerId() => $this->getResponseData($response),
-        ],
-      ];
-      $build_message = [
-        '#markup' => $this->replaceTokens($custom_response_message, $this->getWebform(), $token_data),
-      ];
-      $this->messenger()->addError(\Drupal::service('renderer')->renderPlain($build_message));
-    }
-    else {
+    if (!$this->displayCustomResponseMessage($response, TRUE)) {
       $this->messageManager->display(WebformMessageManagerInterface::SUBMISSION_EXCEPTION_MESSAGE, 'error');
     }
 
@@ -1008,24 +1065,71 @@ protected function handleError($state, $message, $request_url, $request_method,
   }
 
   /**
-   * Get custom custom response message.
+   * Get custom response message.
    *
    * @param \Psr\Http\Message\ResponseInterface|null $response
    *   The response returned by the remote server.
+   * @param bool $default
+   *   Display the default message. Defaults to TRUE.
    *
    * @return string
-   *   A custom custom response message.
+   *   A custom response message.
    */
-  protected function getCustomResponseMessage($response) {
-    if ($response instanceof ResponseInterface) {
+  protected function getCustomResponseMessage($response, $default = TRUE) {
+    if (!empty($this->configuration['messages']) && $response instanceof ResponseInterface) {
       $status_code = $response->getStatusCode();
       foreach ($this->configuration['messages'] as $message_item) {
-        if ($message_item['code'] == $status_code) {
+        if ((int) $message_item['code'] === (int) $status_code) {
           return $message_item['message'];
         }
       }
     }
-    return (!empty($this->configuration['message'])) ? $this->configuration['message'] : '';
+    return (!empty($this->configuration['message']) && $default) ? $this->configuration['message'] : '';
+  }
+
+  /**
+   * Display custom response message.
+   *
+   * @param \Psr\Http\Message\ResponseInterface|null $response
+   *   The response returned by the remote server.
+   * @param bool $default
+   *   Display the default message. Defaults to TRUE.
+   *
+   * @return bool
+   *   TRUE if custom response message is displayed.
+   */
+  protected function displayCustomResponseMessage($response, $default = TRUE) {
+    $custom_response_message = $this->getCustomResponseMessage($response, $default);
+    if (!$custom_response_message) {
+      return FALSE;
+    }
+
+    $token_data = [
+      'webform_handler' => [
+        $this->getHandlerId() => $this->getResponseData($response),
+      ],
+    ];
+    $build_message = [
+      '#markup' => $this->replaceTokens($custom_response_message, $this->getWebform(), $token_data),
+    ];
+    $message = \Drupal::service('renderer')->renderPlain($build_message);
+    $type = ($this->responseHasError($response)) ? MessengerInterface::TYPE_ERROR : MessengerInterface::TYPE_STATUS;
+    $this->messenger()->addMessage($message, $type);
+    return TRUE;
+  }
+
+  /**
+   * Determine if response has an error status code.
+   *
+   * @param \Psr\Http\Message\ResponseInterface|null $response
+   *   The response returned by the remote server.
+   *
+   * @return bool
+   *   TRUE if response status code reflects an unsuccessful value.
+   */
+  protected function responseHasError($response) {
+    $status_code = $response->getStatusCode();
+    return $status_code < 200 || $status_code >= 300;
   }
 
   /**
diff --git a/web/modules/webform/src/Plugin/WebformHandlerBase.php b/web/modules/webform/src/Plugin/WebformHandlerBase.php
index fbae6a179c..825db8d8bf 100644
--- a/web/modules/webform/src/Plugin/WebformHandlerBase.php
+++ b/web/modules/webform/src/Plugin/WebformHandlerBase.php
@@ -90,7 +90,7 @@ abstract class WebformHandlerBase extends PluginBase implements WebformHandlerIn
   protected $loggerFactory;
 
   /**
-   * Webform submission storage.
+   * The webform submission storage.
    *
    * @var \Drupal\webform\WebformSubmissionStorageInterface
    */
@@ -365,14 +365,14 @@ public function isApplicable(WebformInterface $webform) {
    * {@inheritdoc}
    */
   public function isSubmissionOptional() {
-    return ($this->pluginDefinition['submission'] === self::SUBMISSION_OPTIONAL);
+    return ($this->pluginDefinition['submission'] === WebformHandlerInterface::SUBMISSION_OPTIONAL);
   }
 
   /**
    * {@inheritdoc}
    */
   public function isSubmissionRequired() {
-    return ($this->pluginDefinition['submission'] === self::SUBMISSION_REQUIRED);
+    return ($this->pluginDefinition['submission'] === WebformHandlerInterface::SUBMISSION_REQUIRED);
   }
 
   /**
diff --git a/web/modules/webform/src/Plugin/WebformHandlerManager.php b/web/modules/webform/src/Plugin/WebformHandlerManager.php
index e901eff253..41f60ab1e8 100644
--- a/web/modules/webform/src/Plugin/WebformHandlerManager.php
+++ b/web/modules/webform/src/Plugin/WebformHandlerManager.php
@@ -55,9 +55,9 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
   /**
    * {@inheritdoc}
    */
-  public function getSortedDefinitions(array $definitions = NULL) {
+  public function getSortedDefinitions(array $definitions = NULL, $sort_by = 'label') {
     // Sort the plugins first by category, then by label.
-    $definitions = $this->traitGetSortedDefinitions($definitions);
+    $definitions = $this->traitGetSortedDefinitions($definitions, $sort_by);
     return $definitions;
   }
 
diff --git a/web/modules/webform/src/Plugin/WebformHandlerPluginCollection.php b/web/modules/webform/src/Plugin/WebformHandlerPluginCollection.php
index c2571d1174..8a69eb724e 100644
--- a/web/modules/webform/src/Plugin/WebformHandlerPluginCollection.php
+++ b/web/modules/webform/src/Plugin/WebformHandlerPluginCollection.php
@@ -21,7 +21,7 @@ public function sortHelper($a_id, $b_id) {
 
     $a_weight = $a->getWeight();
     $b_weight = $b->getWeight();
-    if ($a_weight == $b_weight) {
+    if ($a_weight === $b_weight) {
       return 0;
     }
 
diff --git a/web/modules/webform/src/Plugin/WebformSourceEntity/QueryStringWebformSourceEntity.php b/web/modules/webform/src/Plugin/WebformSourceEntity/QueryStringWebformSourceEntity.php
index 633e471e60..d23e88f514 100644
--- a/web/modules/webform/src/Plugin/WebformSourceEntity/QueryStringWebformSourceEntity.php
+++ b/web/modules/webform/src/Plugin/WebformSourceEntity/QueryStringWebformSourceEntity.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\webform\Plugin\WebformSourceEntity;
 
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Language\LanguageManagerInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
@@ -164,4 +165,28 @@ public function getSourceEntity(array $ignored_types) {
     return $source_entity;
   }
 
+  /**
+   * Get source entity route options query string parameters.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface|null $entity
+   *   An entity.
+   *
+   * @return array
+   *   An associative array contains a source entity's route options
+   *   query string parameters.
+   */
+  public static function getRouteOptionsQuery(EntityInterface $entity = NULL) {
+    if (!$entity) {
+      return [];
+    }
+    else {
+      return [
+        'query' => [
+          'source_entity_type' => $entity->getEntityTypeId(),
+          'source_entity_id' => $entity->id(),
+        ],
+      ];
+    }
+  }
+
 }
diff --git a/web/modules/webform/src/Plugin/WebformVariant/OverrideWebformVariant.php b/web/modules/webform/src/Plugin/WebformVariant/OverrideWebformVariant.php
index f38274bb08..c9d7591fb5 100644
--- a/web/modules/webform/src/Plugin/WebformVariant/OverrideWebformVariant.php
+++ b/web/modules/webform/src/Plugin/WebformVariant/OverrideWebformVariant.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Render\Element;
 use Drupal\Core\Serialization\Yaml;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\webform\Element\WebformHtmlEditor;
@@ -174,6 +175,11 @@ public function validateConfigurationForm(array &$form, FormStateInterface $form
     $elements = Yaml::decode($values['elements']) ?: [];
     if ($elements) {
       foreach ($elements as $element_key => $element_properties) {
+        // Skip custom form property.
+        if (Element::property($element_key)) {
+          continue;
+        }
+
         $element = $webform->getElement($element_key);
         if (!$element) {
           $form_state->setErrorByName('elements', $this->t('Element %key is not a valid element key.', ['%key' => $element_key]));
@@ -218,11 +224,18 @@ public function applyVariant() {
     $elements = Yaml::decode($this->configuration['elements']) ?: [];
     if ($elements) {
       foreach ($elements as $element_key => $element_properties) {
-        $element = $webform->getElement($element_key);
-        if (!$element) {
-          continue;
+        if (Element::property($element_key)) {
+          // Set custom form property.
+          $webform->setElements([$element_key => $element_properties] + $webform->getElementsDecoded());
         }
-        $webform->setElementProperties($element_key, $element_properties + $element);
+        else {
+          $element = $webform->getElement($element_key);
+          if (!$element) {
+            continue;
+          }
+          $webform->setElementProperties($element_key, $element_properties + $element);
+        }
+
       }
     }
 
diff --git a/web/modules/webform/src/Plugin/WebformVariantManager.php b/web/modules/webform/src/Plugin/WebformVariantManager.php
index eb1c2df699..284c4620b2 100644
--- a/web/modules/webform/src/Plugin/WebformVariantManager.php
+++ b/web/modules/webform/src/Plugin/WebformVariantManager.php
@@ -55,9 +55,9 @@ public function __construct(\Traversable $namespaces, CacheBackendInterface $cac
   /**
    * {@inheritdoc}
    */
-  public function getSortedDefinitions(array $definitions = NULL) {
+  public function getSortedDefinitions(array $definitions = NULL, $sort_by = 'label') {
     // Sort the plugins first by category, then by label.
-    $definitions = $this->traitGetSortedDefinitions($definitions);
+    $definitions = $this->traitGetSortedDefinitions($definitions, $sort_by);
     return $definitions;
   }
 
diff --git a/web/modules/webform/src/Plugin/WebformVariantPluginCollection.php b/web/modules/webform/src/Plugin/WebformVariantPluginCollection.php
index fad0e20672..5bbbeccfff 100644
--- a/web/modules/webform/src/Plugin/WebformVariantPluginCollection.php
+++ b/web/modules/webform/src/Plugin/WebformVariantPluginCollection.php
@@ -21,7 +21,7 @@ public function sortHelper($a_id, $b_id) {
 
     $a_weight = $a->getWeight();
     $b_weight = $b->getWeight();
-    if ($a_weight == $b_weight) {
+    if ($a_weight === $b_weight) {
       return strnatcasecmp($a->getVariantId(), $b->getVariantId());
     }
 
diff --git a/web/modules/webform/src/Routing/WebformRouteSubscriber.php b/web/modules/webform/src/Routing/WebformRouteSubscriber.php
index d31647984f..60fefecbfa 100644
--- a/web/modules/webform/src/Routing/WebformRouteSubscriber.php
+++ b/web/modules/webform/src/Routing/WebformRouteSubscriber.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\webform\Routing;
 
+use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Routing\RouteSubscriberBase;
 use Symfony\Component\Routing\RouteCollection;
 
@@ -10,6 +11,23 @@
  */
 class WebformRouteSubscriber extends RouteSubscriberBase {
 
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Extension\ModuleHandlerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * Constructs a WebformShareRouteSubscriber object.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   */
+  public function __construct(ModuleHandlerInterface $module_handler) {
+    $this->moduleHandler = $module_handler;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -23,6 +41,11 @@ protected function alterRoutes(RouteCollection $collection) {
         $route->setOption('_admin_route', TRUE);
       }
     }
+
+    // If the webform_share.module is not enabled, remove variant share route.
+    if (!$this->moduleHandler->moduleExists('webform_share')) {
+      $collection->remove('entity.webform.variant.share_form');
+    }
   }
 
 }
diff --git a/web/modules/webform/src/Theme/WebformThemeNegotiator.php b/web/modules/webform/src/Theme/WebformThemeNegotiator.php
index 88b4fc4fc1..394a669e00 100644
--- a/web/modules/webform/src/Theme/WebformThemeNegotiator.php
+++ b/web/modules/webform/src/Theme/WebformThemeNegotiator.php
@@ -28,14 +28,14 @@ class WebformThemeNegotiator implements ThemeNegotiatorInterface {
   protected $configFactory;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
   protected $requestHandler;
 
   /**
-   * Creates a new AdminNegotiator instance.
+   * Creates a new WebformThemeNegotiator instance.
    *
    * @param \Drupal\Core\Session\AccountInterface $user
    *   The current user.
@@ -56,14 +56,34 @@ public function __construct(AccountInterface $user, ConfigFactoryInterface $conf
    * {@inheritdoc}
    */
   public function applies(RouteMatchInterface $route_match) {
+    return $this->getActiveTheme($route_match) ? TRUE : FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function determineActiveTheme(RouteMatchInterface $route_match) {
+    return $this->getActiveTheme($route_match);
+  }
+
+  /**
+   * Determine the active theme for the current route.
+   *
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The current route match.
+   *
+   * @return string
+   *   The active theme or an empty string.
+   */
+  protected function getActiveTheme(RouteMatchInterface $route_match) {
     $route_name = $route_match->getRouteName();
     if (strpos($route_name, 'webform') === FALSE) {
-      return FALSE;
+      return '';
     }
 
     $webform = $this->requestHandler->getCurrentWebform();
     if (empty($webform)) {
-      return FALSE;
+      return '';
     }
 
     $is_webform_route = in_array($route_name, [
@@ -74,25 +94,22 @@ public function applies(RouteMatchInterface $route_match) {
     ]);
     $is_user_submission_route = (strpos($route_name, 'entity.webform.user.') === 0);
 
-    // If page is disabled, apply admin theme to the webform routes.
-    if (!$webform->getSetting('page') && $is_webform_route) {
-      return ($this->user->hasPermission('view the administration theme'));
+    // If webform route and page is disabled, apply admin theme to
+    // the webform routes.
+    if ($is_webform_route && !$webform->getSetting('page')) {
+      return ($this->user->hasPermission('view the administration theme'))
+        ? $this->configFactory->get('system.theme')->get('admin')
+        : '';
     }
 
-    // If admin theme is enabled, apply it to webform and user submission routes.
-    if ($webform->getSetting('page_admin_theme')
-      && ($is_webform_route || $is_user_submission_route)) {
-      return ($this->user->hasPermission('view the administration theme'));
+    // If webform and user submission routes apply custom page theme to
+    // the webform routes.
+    if (($is_webform_route || $is_user_submission_route)
+      && $webform->getSetting('page_theme_name')) {
+      return $webform->getSetting('page_theme_name');
     }
 
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function determineActiveTheme(RouteMatchInterface $route_match) {
-    return $this->configFactory->get('system.theme')->get('admin');
+    return '';
   }
 
 }
diff --git a/web/modules/webform/src/Twig/WebformTwigExtension.php b/web/modules/webform/src/Twig/WebformTwigExtension.php
index 89bfb91c02..73812ef2dc 100644
--- a/web/modules/webform/src/Twig/WebformTwigExtension.php
+++ b/web/modules/webform/src/Twig/WebformTwigExtension.php
@@ -228,7 +228,7 @@ public static function buildTwigHelp(array $variables = []) {
    */
   public static function renderTwigTemplate(WebformSubmissionInterface $webform_submission, $template, array $options = [], array $context = []) {
     try {
-      $build = self::buildTwigTemplate($webform_submission, $template, $options, $context);
+      $build = static::buildTwigTemplate($webform_submission, $template, $options, $context);
       return \Drupal::service('renderer')->renderPlain($build);
     }
     catch (\Exception $exception) {
diff --git a/web/modules/webform/src/Utility/WebformArrayHelper.php b/web/modules/webform/src/Utility/WebformArrayHelper.php
index b20528b22d..c592cce099 100644
--- a/web/modules/webform/src/Utility/WebformArrayHelper.php
+++ b/web/modules/webform/src/Utility/WebformArrayHelper.php
@@ -162,7 +162,7 @@ protected static function getKey(array $array, $key, $direction) {
     $array_keys = array_keys($array);
     $array_key = reset($array_keys);
     do {
-      if ($array_key == $key) {
+      if ($array_key === $key) {
         return $direction($array_keys);
       }
     } while ($array_key = next($array_keys));
@@ -183,7 +183,7 @@ protected static function getKey(array $array, $key, $direction) {
   public static function addPrefix(array $array, $prefix = '#') {
     $prefixed_array = [];
     foreach ($array as $key => $value) {
-      if ($key[0] != $prefix) {
+      if ($key[0] !== $prefix) {
         $key = $prefix . $key;
       }
       $prefixed_array[$key] = $value;
@@ -205,7 +205,7 @@ public static function addPrefix(array $array, $prefix = '#') {
   public static function removePrefix(array $array, $prefix = '#') {
     $unprefixed_array = [];
     foreach ($array as $key => $value) {
-      if ($key[0] == $prefix) {
+      if ($key[0] === $prefix) {
         $key = preg_replace('/^' . $prefix . '/', '', $key);
       }
       $unprefixed_array[$key] = $value;
diff --git a/web/modules/webform/src/Utility/WebformElementHelper.php b/web/modules/webform/src/Utility/WebformElementHelper.php
index 382843af17..c7730793eb 100644
--- a/web/modules/webform/src/Utility/WebformElementHelper.php
+++ b/web/modules/webform/src/Utility/WebformElementHelper.php
@@ -49,6 +49,16 @@ class WebformElementHelper {
     '#captcha_validate' => '#captcha_validate',
   ];
 
+  /**
+   * Allowed (whitelist) element properties.
+   *
+   * @var array
+   */
+  public static $allowedProperties = [
+    // webform_validation.module.
+    '#equal_stepwise_validate' => '#equal_stepwise_validate',
+  ];
+
   /**
    * Regular expression used to determine if sub-element property should be ignored.
    *
@@ -56,6 +66,13 @@ class WebformElementHelper {
    */
   protected static $ignoredSubPropertiesRegExp;
 
+  /**
+   * Regular expression used to determine if sub-element property should be allowed.
+   *
+   * @var string
+   */
+  protected static $allowedSubPropertiesRegExp;
+
   /**
    * Determine if an element and its key is a renderable array.
    *
@@ -363,7 +380,7 @@ public static function getIgnoredProperties(array $element) {
             $ignored_properties[$key] = $key;
           }
         }
-        elseif ($key == '#element' && is_array($value) && isset($element['#type']) && $element['#type'] === 'webform_composite') {
+        elseif ($key === '#element' && is_array($value) && isset($element['#type']) && $element['#type'] === 'webform_composite') {
           foreach ($value as $composite_value) {
 
             // Multiple sub composite elements are not supported.
@@ -399,7 +416,7 @@ public static function getIgnoredProperties(array $element) {
    */
   public static function removeIgnoredProperties(array $element) {
     foreach ($element as $key => $value) {
-      if (Element::property($key) && self::isIgnoredProperty($key)) {
+      if ($key && is_string($key) && Element::property($key) && self::isIgnoredProperty($key)) {
         // Computed elements use #ajax as boolean and should not be ignored.
         // @see \Drupal\webform\Element\WebformComputedBase
         $is_ajax_computed = ($key === '#ajax' && is_bool($value));
@@ -432,10 +449,22 @@ public static function removeIgnoredProperties(array $element) {
   protected static function isIgnoredProperty($property) {
     // Build cached ignored sub properties regular expression.
     if (!isset(self::$ignoredSubPropertiesRegExp)) {
-      self::$ignoredSubPropertiesRegExp = '/__(' . implode('|', array_keys(WebformArrayHelper::removePrefix(self::$ignoredProperties))) . ')$/';
+      $allowedSubProperties = self::$allowedProperties;
+      $ignoredSubProperties = self::$ignoredProperties;
+      // Allow #weight as sub property. This makes it easier for developer to
+      // sort composite sub-elements.
+      unset($ignoredSubProperties['#weight']);
+      self::$ignoredSubPropertiesRegExp = '/__(' . implode('|', array_keys(WebformArrayHelper::removePrefix($ignoredSubProperties))) . ')$/';
+      self::$allowedSubPropertiesRegExp = '/__(' . implode('|', array_keys(WebformArrayHelper::removePrefix($allowedSubProperties))) . ')$/';
     }
 
-    if (isset(self::$ignoredProperties[$property])) {
+    if (isset(self::$allowedProperties[$property])) {
+      return FALSE;
+    }
+    elseif (strpos($property, '__') !== FALSE && preg_match(self::$allowedSubPropertiesRegExp, $property)) {
+      return FALSE;
+    }
+    elseif (isset(self::$ignoredProperties[$property])) {
       return TRUE;
     }
     elseif (strpos($property, '__') !== FALSE && preg_match(self::$ignoredSubPropertiesRegExp, $property)) {
@@ -549,7 +578,7 @@ public static function getFlattened(array $elements) {
    */
   public static function &getElement(array &$elements, $name) {
     foreach (Element::children($elements) as $element_name) {
-      if ($element_name == $name) {
+      if ($element_name === $name) {
         return $elements[$element_name];
       }
       elseif (is_array($elements[$element_name])) {
diff --git a/web/modules/webform/src/Utility/WebformFormHelper.php b/web/modules/webform/src/Utility/WebformFormHelper.php
index ea2bdefc57..4c73d1efb0 100644
--- a/web/modules/webform/src/Utility/WebformFormHelper.php
+++ b/web/modules/webform/src/Utility/WebformFormHelper.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\webform\Utility;
 
+use Drupal\Component\Serialization\Json;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Url;
 
@@ -10,6 +11,29 @@
  */
 class WebformFormHelper {
 
+  /**
+   * Adds JavaScript to change the state of an element based on another element.
+   *
+   * @param array $elements
+   *   A renderable array element having a #states property as described above.
+   * @param string $key
+   *   The element property to add the states attribute to.
+   *
+   * @see \Drupal\Core\Form\FormHelper::processStates
+   */
+  public static function processStates(array &$elements, $key = '#attributes') {
+    if (empty($elements['#states'])) {
+      return;
+    }
+
+    $elements['#attached']['library'][] = 'core/drupal.states';
+    $elements[$key]['data-drupal-states'] = Json::encode($elements['#states']);
+    // Make sure to include target class for this container.
+    if (empty($elements[$key]['class']) || !WebformArrayHelper::inArray(['js-form-item', 'js-form-submit', 'js-form-wrapper'], $elements[$key]['class'])) {
+      $elements[$key]['class'][] = 'js-form-item';
+    }
+  }
+
   /**
    * Build form jQuery UI tabs.
    *
diff --git a/web/modules/webform/src/Utility/WebformOptionsHelper.php b/web/modules/webform/src/Utility/WebformOptionsHelper.php
index ca54b10e50..3518698959 100644
--- a/web/modules/webform/src/Utility/WebformOptionsHelper.php
+++ b/web/modules/webform/src/Utility/WebformOptionsHelper.php
@@ -56,7 +56,7 @@ public static function hasOption($value, array $options) {
           return $has_value;
         }
       }
-      elseif ($value == $option_value) {
+      elseif ($value === $option_value) {
         return TRUE;
       }
     }
diff --git a/web/modules/webform/src/Utility/WebformReflectionHelper.php b/web/modules/webform/src/Utility/WebformReflectionHelper.php
index 1af5dfdf78..1fe6022626 100644
--- a/web/modules/webform/src/Utility/WebformReflectionHelper.php
+++ b/web/modules/webform/src/Utility/WebformReflectionHelper.php
@@ -26,7 +26,7 @@ public static function getSubModules() {
     }
 
     self::$modules = [];
-    $files = file_scan_directory(drupal_get_path('module', 'webform') . '/modules', '/.*\.info\.yml/');
+    $files = \Drupal::service('file_system')->scanDirectory(drupal_get_path('module', 'webform') . '/modules', '/.*\.info\.yml/');
     foreach ($files as $file) {
       $module_name = str_replace('.info.yml', '', $file->filename);
       self::$modules[$module_name] = $module_name;
@@ -52,7 +52,7 @@ public static function getParentClasses($object, $base_class_name = '') {
     while ($class_name = self::getClassName($class)) {
       $parent_classes[] = $class_name;
       $class = get_parent_class($class);
-      if ($class_name == $base_class_name || !$class) {
+      if ($class_name === $base_class_name || !$class) {
         break;
       }
     }
diff --git a/web/modules/webform/src/Utility/WebformYaml.php b/web/modules/webform/src/Utility/WebformYaml.php
index b0af0ad408..d76769bcfb 100644
--- a/web/modules/webform/src/Utility/WebformYaml.php
+++ b/web/modules/webform/src/Utility/WebformYaml.php
@@ -33,7 +33,7 @@ public static function encode($data) {
    * {@inheritdoc}
    */
   public static function decode($raw) {
-    return Yaml::decode($raw);
+    return $raw ? Yaml::decode($raw) : [];
   }
 
   /**
diff --git a/web/modules/webform/src/WebformAddonsManager.php b/web/modules/webform/src/WebformAddonsManager.php
index 92c0a60aed..6a1d8a67f7 100644
--- a/web/modules/webform/src/WebformAddonsManager.php
+++ b/web/modules/webform/src/WebformAddonsManager.php
@@ -35,7 +35,7 @@ public function getProjects($category = NULL) {
     $projects = $this->projects;
     if ($category) {
       foreach ($projects as $project_name => $project) {
-        if ($project['category'] != $category) {
+        if ($project['category'] !== $category) {
           unset($projects[$project_name]);
         }
       }
@@ -526,7 +526,7 @@ protected function initProjects() {
     // Integrations: GitLab API with Library.
     $projects['gitlab_api'] = [
       'title' => $this->t('GitLab API with Library'),
-      'description' => $this->t(' Integrates your Drupal site into GitLab using the GitLab API.'),
+      'description' => $this->t('Integrates your Drupal site into GitLab using the GitLab API.'),
       'url' => Url::fromUri('https://www.drupal.org/project/gitlab_api'),
       'category' => 'integration',
     ];
@@ -860,6 +860,14 @@ protected function initProjects() {
       'category' => 'mail',
     ];
 
+    // Mail: Mailboxlayer.
+    $projects['mailboxlayer'] = [
+      'title' => $this->t('Mailboxlayer'),
+      'description' => $this->t('Integrates the <a href=":href">Mailboxlayer API</a> with the Webforms.', [':href' => 'https://mailboxlayer.com']),
+      'url' => Url::fromUri('https://www.drupal.org/project/mailboxlayer'),
+      'category' => 'mail',
+    ];
+
     // Mail: Mail System: SendGrid Integration.
     $projects['sendgrid_integration'] = [
       'title' => $this->t('SendGrid Integration <em>(requires Mail System)</em>'),
@@ -1047,6 +1055,15 @@ protected function initProjects() {
       'recommended' => TRUE,
     ];
 
+    // Submissions: Webform Submission Views Token Field.
+    $projects['ws_views_field'] = [
+      'title' => $this->t('Webform Submission Views Token Field'),
+      'description' => $this->t('Provides a token approach to list WebformSubmission fields in views.'),
+      'url' => Url::fromUri('https://www.drupal.org/project/ws_views_field'),
+      'category' => 'submission',
+      'recommended' => TRUE,
+    ];
+
     /**************************************************************************/
 
     // Submissions: Protected Submissions.
diff --git a/web/modules/webform/src/WebformEntityAccessControlHandler.php b/web/modules/webform/src/WebformEntityAccessControlHandler.php
index 2d9af3da79..00eb11ee42 100644
--- a/web/modules/webform/src/WebformEntityAccessControlHandler.php
+++ b/web/modules/webform/src/WebformEntityAccessControlHandler.php
@@ -36,14 +36,14 @@ class WebformEntityAccessControlHandler extends EntityAccessControlHandler imple
   protected $entityTypeManager;
 
   /**
-   * Webform source entity plugin manager.
+   * The webform source entity plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformSourceEntityManagerInterface
    */
   protected $webformSourceEntityManager;
 
   /**
-   * Webform access rules manager service.
+   * The webform access rules manager service.
    *
    * @var \Drupal\webform\WebformAccessRulesManagerInterface
    */
@@ -120,7 +120,7 @@ public function checkAccess(EntityInterface $entity, $operation, AccountInterfac
       }
     }
 
-    $is_owner = ($account->id() == $entity->getOwnerId());
+    $is_owner = ((int) $account->id() === (int) $entity->getOwnerId());
 
     // Check 'view' operation use 'submission_create' when viewing rendered
     // HTML webform or use access 'configuration' when requesting a
diff --git a/web/modules/webform/src/WebformEntityAddForm.php b/web/modules/webform/src/WebformEntityAddForm.php
index 71f90fa099..3a1a106e95 100644
--- a/web/modules/webform/src/WebformEntityAddForm.php
+++ b/web/modules/webform/src/WebformEntityAddForm.php
@@ -18,7 +18,7 @@ class WebformEntityAddForm extends BundleEntityFormBase {
    * {@inheritdoc}
    */
   protected function prepareEntity() {
-    if ($this->operation == 'duplicate') {
+    if ($this->operation === 'duplicate') {
       $this->setEntity($this->getEntity()->createDuplicate());
     }
     parent::prepareEntity();
@@ -32,7 +32,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $webform = $this->getEntity();
 
     // Customize title for duplicate webform.
-    if ($this->operation == 'duplicate') {
+    if ($this->operation === 'duplicate') {
       // Display custom title.
       $form['#title'] = $this->t("Duplicate '@label' form", ['@label' => $webform->label()]);
     }
diff --git a/web/modules/webform/src/WebformEntityElementsForm.php b/web/modules/webform/src/WebformEntityElementsForm.php
index 6b6e327067..f00200d64a 100644
--- a/web/modules/webform/src/WebformEntityElementsForm.php
+++ b/web/modules/webform/src/WebformEntityElementsForm.php
@@ -6,7 +6,6 @@
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Render\ElementInfoManagerInterface;
-use Drupal\Core\Serialization\Yaml;
 use Drupal\webform\Form\WebformDialogFormTrait;
 use Drupal\webform\Plugin\WebformElementManagerInterface;
 use Drupal\webform\Utility\WebformYaml;
@@ -20,21 +19,21 @@ class WebformEntityElementsForm extends BundleEntityFormBase {
   use WebformDialogFormTrait;
 
   /**
-   * Element info manager.
+   * The element info manager.
    *
    * @var \Drupal\Core\Render\ElementInfoManagerInterface
    */
   protected $elementInfo;
 
   /**
-   * Webform element manager.
+   * The webform element manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
   protected $elementManager;
 
   /**
-   * Webform element validator.
+   * The webform element validator.
    *
    * @var \Drupal\webform\WebformEntityElementsValidatorInterface
    */
@@ -194,7 +193,7 @@ public function save(array $form, FormStateInterface $form_state) {
    *   Elements (YAML) without 'webform_' #type prefix.
    */
   protected function getElementsWithoutWebformTypePrefix($value) {
-    $elements = Yaml::decode($value);
+    $elements = WebformYaml::decode($value);
     if (!is_array($elements)) {
       return $value;
     }
@@ -231,7 +230,7 @@ protected function removeWebformTypePrefixRecursive(array &$element) {
    *   Elements (YAML) with 'webform_' #type prefix.
    */
   protected function getElementsWithWebformTypePrefix($value) {
-    $elements = Yaml::decode($value);
+    $elements = WebformYaml::decode($value);
     if (!is_array($elements)) {
       return $value;
     }
diff --git a/web/modules/webform/src/WebformEntityElementsValidator.php b/web/modules/webform/src/WebformEntityElementsValidator.php
index 8ac9030231..f74836101d 100644
--- a/web/modules/webform/src/WebformEntityElementsValidator.php
+++ b/web/modules/webform/src/WebformEntityElementsValidator.php
@@ -6,13 +6,13 @@
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Form\FormBuilderInterface;
 use Drupal\Core\Render\RendererInterface;
-use Drupal\Core\Serialization\Yaml;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Form\FormState;
 use Drupal\Core\Url;
 use Drupal\webform\Plugin\WebformElementManagerInterface;
 use Drupal\webform\Utility\WebformArrayHelper;
 use Drupal\webform\Utility\WebformElementHelper;
+use Drupal\webform\Utility\WebformYaml;
 
 /**
  * Webform elements validator.
@@ -148,6 +148,7 @@ public function validate(WebformInterface $webform, array $options = []) {
       'submissions' => TRUE,
       'variants' => TRUE,
       'hierarchy' => TRUE,
+      'pages' => TRUE,
       'rendering' => TRUE,
     ];
 
@@ -166,8 +167,8 @@ public function validate(WebformInterface $webform, array $options = []) {
       return [$message];
     }
 
-    $this->elements = Yaml::decode($this->elementsRaw);
-    $this->originalElements = Yaml::decode($this->originalElementsRaw);
+    $this->elements = WebformYaml::decode($this->elementsRaw);
+    $this->originalElements = WebformYaml::decode($this->originalElementsRaw);
 
     $this->elementKeys = [];
     if (is_array($this->elements)) {
@@ -209,6 +210,11 @@ public function validate(WebformInterface $webform, array $options = []) {
       return $messages;
     }
 
+    // Validate pages.
+    if ($options['pages'] && ($messages = $this->validatePages())) {
+      return $messages;
+    }
+
     // Validate rendering.
     if ($options['rendering'] && ($message = $this->validateRendering())) {
       return [$message];
@@ -235,7 +241,7 @@ protected function validateRequired() {
    */
   protected function validateYaml() {
     try {
-      Yaml::decode($this->elementsRaw);
+      WebformYaml::decode($this->elementsRaw);
       return NULL;
     }
     catch (\Exception $exception) {
@@ -371,7 +377,7 @@ protected function validateProperties() {
     if ($ignored_properties) {
       $messages = [];
       foreach ($ignored_properties as $ignored_property => $ignored_message) {
-        if ($ignored_property != $ignored_message) {
+        if ($ignored_property !== $ignored_message) {
           $messages[] = $ignored_message;
         }
         else {
@@ -518,6 +524,25 @@ protected function validateHierarchy() {
     return $messages;
   }
 
+  /**
+   * Validate wizard/card pages.
+   *
+   * @return \Drupal\Core\StringTranslation\TranslatableMarkup|string|null
+   *   If not valid an error message.
+   *
+   * @see \Drupal\Core\Entity\EntityFormBuilder
+   * @see \Drupal\webform\Entity\Webform::getSubmissionForm()
+   */
+  protected function validatePages() {
+    if (strpos($this->elementsRaw, "'#type': webform_card") !== FALSE
+      && strpos($this->elementsRaw, "'#type': webform_wizard_page") !== FALSE) {
+        return [$this->t('Pages and cards cannot be used in the same webform. Please remove or convert the pages/cards to the same element type.')];
+    }
+    else {
+      return NULL;
+    }
+  }
+
   /**
    * Validate that elements are a valid render array.
    *
diff --git a/web/modules/webform/src/WebformEntityHandlersForm.php b/web/modules/webform/src/WebformEntityHandlersForm.php
index b838b5268f..ca362bbd4b 100644
--- a/web/modules/webform/src/WebformEntityHandlersForm.php
+++ b/web/modules/webform/src/WebformEntityHandlersForm.php
@@ -30,7 +30,7 @@ class WebformEntityHandlersForm extends EntityForm {
   protected $entity;
 
   /**
-   * Webform handler manager.
+   * The webform handler manager.
    *
    * @var \Drupal\webform\Plugin\WebformHandlerManagerInterface
    */
diff --git a/web/modules/webform/src/WebformEntityListBuilder.php b/web/modules/webform/src/WebformEntityListBuilder.php
index 866fd3f3e1..b73299b6b2 100644
--- a/web/modules/webform/src/WebformEntityListBuilder.php
+++ b/web/modules/webform/src/WebformEntityListBuilder.php
@@ -59,21 +59,21 @@ class WebformEntityListBuilder extends ConfigEntityListBuilder {
   protected $state;
 
   /**
-   * Webform submission storage.
+   * The webform submission storage.
    *
    * @var \Drupal\webform\WebformSubmissionStorageInterface
    */
   protected $submissionStorage;
 
   /**
-   * User storage.
+   * The user storage.
    *
    * @var \Drupal\user\UserStorageInterface
    */
   protected $userStorage;
 
   /**
-   * Role storage.
+   * The role storage.
    *
    * @var \Drupal\user\RoleStorageInterface
    */
@@ -291,7 +291,7 @@ public function buildRow(EntityInterface $entity) {
       $row['status']['data'] = [
         '#type' => 'html_tag',
         '#tag' => 'span',
-        '#markup' => $this->t('Archived'),
+        '#value' => $this->t('Archived'),
         '#attributes' => ['aria-label' => $this->t('@label is archived', $t_args)],
       ];
       $row['status'] = $this->t('Archived');
@@ -326,7 +326,7 @@ public function buildRow(EntityInterface $entity) {
         $row['status']['data'] = [
           '#type' => 'html_tag',
           '#tag' => 'span',
-          '#markup' => $status,
+          '#value' => $status,
           '#attributes' => ['aria-label' => $aria_label],
         ];
       }
@@ -381,24 +381,35 @@ public function getDefaultOperations(EntityInterface $entity, $type = 'edit') {
       $operations['edit'] = [
         'title' => $this->t('Build'),
         'url' => $this->ensureDestination($entity->toUrl('edit-form')),
+        'weight' => 0,
       ];
     }
     if ($entity->access('submission_page')) {
       $operations['view'] = [
         'title' => $this->t('View'),
         'url' => $entity->toUrl('canonical'),
+        'weight' => 10,
+      ];
+    }
+    if ($entity->access('test')) {
+      $operations['test'] = [
+        'title' => $this->t('Test'),
+        'url' => $entity->toUrl('canonical'),
+        'weight' => 20,
       ];
     }
     if ($entity->access('submission_view_any') && !$entity->isResultsDisabled()) {
       $operations['results'] = [
         'title' => $this->t('Results'),
         'url' => $entity->toUrl('results-submissions'),
+        'weight' => 30,
       ];
     }
     if ($entity->access('update')) {
       $operations['settings'] = [
         'title' => $this->t('Settings'),
         'url' => $entity->toUrl('settings'),
+        'weight' => 40,
       ];
     }
     if ($entity->access('duplicate')) {
@@ -406,6 +417,7 @@ public function getDefaultOperations(EntityInterface $entity, $type = 'edit') {
         'title' => $this->t('Duplicate'),
         'url' => $entity->toUrl('duplicate-form'),
         'attributes' => WebformDialogHelper::getModalDialogAttributes(WebformDialogHelper::DIALOG_NARROW),
+        'weight' => 90,
       ];
     }
     if ($entity->access('delete') && $entity->hasLinkTemplate('delete-form')) {
@@ -413,6 +425,7 @@ public function getDefaultOperations(EntityInterface $entity, $type = 'edit') {
         'title' => $this->t('Delete'),
         'url' => $this->ensureDestination($entity->toUrl('delete-form')),
         'attributes' => WebformDialogHelper::getModalDialogAttributes(WebformDialogHelper::DIALOG_NARROW),
+        'weight' => 100,
       ];
     }
     return $operations;
@@ -446,7 +459,7 @@ protected function getEntityIds() {
       $total = count($entity_ids);
       $limit = $this->getLimit();
       $start = ($page * $limit);
-      pager_default_initialize($total, $limit);
+      \Drupal::service('pager.manager')->createPager($total, $limit);
       return array_slice($entity_ids, $start, $limit, TRUE);
     }
     else {
@@ -530,7 +543,7 @@ protected function getQuery($keys = '', $category = '', $state = '') {
           $or->condition('id', $webform_ids, 'IN');
         }
         // Also check the webform's owner.
-        if ($access_type == 'users') {
+        if ($access_type === 'users') {
           $or->condition('uid', $access_value);
         }
       }
diff --git a/web/modules/webform/src/WebformEntityReferenceManager.php b/web/modules/webform/src/WebformEntityReferenceManager.php
index 1abef57818..5ff83aa437 100644
--- a/web/modules/webform/src/WebformEntityReferenceManager.php
+++ b/web/modules/webform/src/WebformEntityReferenceManager.php
@@ -87,7 +87,8 @@ public function isUserWebformRoute(EntityInterface $entity) {
       "entity.$entity_type.webform.api_form",
     ];
     return in_array($this->routeMatch->getRouteName(), $user_routes)
-      || (strpos($route_name, "entity.$entity_type.webform.results_") === 0);
+      || (strpos($route_name, "entity.$entity_type.webform.results_") === 0)
+      || (strpos($route_name, "entity.$entity_type.webform.share_") === 0);
   }
 
   /**
@@ -172,7 +173,7 @@ public function getFieldNames(EntityInterface $entity = NULL) {
     if ($entity instanceof ContentEntityInterface) {
       $fields = $entity->getFieldDefinitions();
       foreach ($fields as $field_name => $field_definition) {
-        if ($field_definition->getType() == 'webform') {
+        if ($field_definition->getType() === 'webform') {
           $field_names[$field_name] = $field_name;
         }
       }
@@ -245,7 +246,7 @@ public function getTableNames() {
     $field_storage_configs = FieldStorageConfig::loadMultiple();
     $tables = [];
     foreach ($field_storage_configs as $field_storage_config) {
-      if ($field_storage_config->getType() == 'webform') {
+      if ($field_storage_config->getType() === 'webform') {
         $webform_field_table = $field_storage_config->getTargetEntityTypeId();
         $webform_field_name = $field_storage_config->getName();
         $tables[$webform_field_table . '__' . $webform_field_name] = $webform_field_name;
diff --git a/web/modules/webform/src/WebformEntityStorage.php b/web/modules/webform/src/WebformEntityStorage.php
index ef803b32e8..35e6f7571f 100644
--- a/web/modules/webform/src/WebformEntityStorage.php
+++ b/web/modules/webform/src/WebformEntityStorage.php
@@ -115,7 +115,7 @@ protected function doCreate(array $values) {
    * {@inheritdoc}
    */
   protected function doPostSave(EntityInterface $entity, $update) {
-    if ($update && $entity->getAccessRules() != $entity->original->getAccessRules()) {
+    if ($update && $entity->getAccessRules() !== $entity->original->getAccessRules()) {
       // Invalidate webform_submission listing cache tags because due to the
       // change in access rules of this webform, some listings might have
       // changed for users.
@@ -173,16 +173,18 @@ public function delete(array $entities) {
       foreach ($stream_wrappers as $stream_wrapper) {
         $file_directory = $stream_wrapper . '://webform/' . $entity->id();
 
-        // Clear all signature files.
-        // @see \Drupal\webform\Plugin\WebformElement\WebformSignature::getImageUrl
-        $files = file_scan_directory($file_directory, '/^signature-.*/');
-        foreach (array_keys($files) as $uri) {
-          $this->fileSystem->delete($uri);
-        }
-
-        // Clear empty webform directory.
-        if (file_exists($file_directory) && empty(file_scan_directory($file_directory, '/.*/'))) {
-          $this->fileSystem->deleteRecursive($file_directory);
+        if (file_exists($file_directory)) {
+          // Clear all signature files.
+          // @see \Drupal\webform\Plugin\WebformElement\WebformSignature::getImageUrl
+          $files = $this->fileSystem->scanDirectory($file_directory, '/^signature-.*/');
+          foreach (array_keys($files) as $uri) {
+            $this->fileSystem->delete($uri);
+          }
+
+          // Clear empty webform directory.
+          if (empty($this->fileSystem->scanDirectory($file_directory, '/.*/'))) {
+            $this->fileSystem->deleteRecursive($file_directory);
+          }
         }
       }
     }
@@ -195,7 +197,7 @@ public function getCategories($template = NULL) {
     $webforms = $this->loadMultiple();
     $categories = [];
     foreach ($webforms as $webform) {
-      if ($template !== NULL && $webform->get('template') != $template) {
+      if ($template !== NULL && $webform->get('template') !== $template) {
         continue;
       }
       if ($category = $webform->get('category')) {
@@ -218,7 +220,7 @@ public function getOptions($template = NULL) {
     $categorized_options = [];
     foreach ($webforms as $id => $webform) {
       // Skip templates.
-      if ($template !== NULL && $webform->get('template') != $template) {
+      if ($template !== NULL && $webform->get('template') !== $template) {
         continue;
       }
       // Skip archived.
diff --git a/web/modules/webform/src/WebformEntityVariantsForm.php b/web/modules/webform/src/WebformEntityVariantsForm.php
index 34c98ab8ab..474e40b984 100644
--- a/web/modules/webform/src/WebformEntityVariantsForm.php
+++ b/web/modules/webform/src/WebformEntityVariantsForm.php
@@ -30,14 +30,14 @@ class WebformEntityVariantsForm extends EntityForm {
   protected $entity;
 
   /**
-   * Webform element manager.
+   * The webform element manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
   protected $elementManager;
 
   /**
-   * Webform variant manager.
+   * The webform variant manager.
    *
    * @var \Drupal\webform\Plugin\WebformVariantManagerInterface
    */
@@ -204,6 +204,19 @@ public function form(array $form, FormStateInterface $form_state) {
             ),
           ];
         }
+        // Share.
+        if ($this->moduleHandler->moduleExists('webform_share')
+          && $webform->access('update')
+          && $webform->getSetting('share', TRUE)) {
+          $operations['share'] = [
+            'title' => t('Share'),
+            'url' => Url::fromRoute(
+              'entity.webform.share_embed',
+              ['webform' => $webform->id()],
+              ['query' => $query]
+            ),
+          ];
+        }
       }
       // Apply.
       $operations['apply'] = [
@@ -272,6 +285,19 @@ public function form(array $form, FormStateInterface $form_state) {
           'attributes' => WebformDialogHelper::getModalDialogAttributes(WebformDialogHelper::DIALOG_NARROW),
         ];
       }
+      // Share variants.
+      if ($this->moduleHandler->moduleExists('webform_share')
+        && $webform->access('update')
+        && $webform->getSetting('share', TRUE)) {
+        $operations['share'] = [
+          'title' => $this->t('Share variants'),
+          'url' => Url::fromRoute(
+            'entity.webform.variant.share_form',
+            ['webform' => $webform->id()]
+          ),
+          'attributes' => WebformDialogHelper::getModalDialogAttributes(WebformDialogHelper::DIALOG_NARROW),
+        ];
+      }
       // Apply variants.
       $operations['apply'] = [
         'title' => $this->t('Apply variants'),
diff --git a/web/modules/webform/src/WebformHelpManager.php b/web/modules/webform/src/WebformHelpManager.php
index 8bb6583be1..6c9e3157c8 100644
--- a/web/modules/webform/src/WebformHelpManager.php
+++ b/web/modules/webform/src/WebformHelpManager.php
@@ -89,21 +89,21 @@ class WebformHelpManager implements WebformHelpManagerInterface {
   protected $pathMatcher;
 
   /**
-   * The Webform add-ons manager.
+   * The webform add-ons manager.
    *
    * @var \Drupal\webform\WebformAddonsManagerInterface
    */
   protected $addOnsManager;
 
   /**
-   * The Webform libraries manager.
+   * The webform libraries manager.
    *
    * @var \Drupal\webform\WebformLibrariesManagerInterface
    */
   protected $librariesManager;
 
   /**
-   * Webform element manager.
+   * The webform element manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
@@ -1296,7 +1296,18 @@ protected function initVideos() {
         'youtube_id' => '7cVIqySy5fs',
         'presentation_id' => '1R13ZGkNgTkxjlN-BT05zrwW2JKhOcvGiByNYl7qtywg',
       ],
-
+      'sharing' => [
+        'title' => $this->t('Sharing Webforms'),
+        'content' => $this->t('This screencast walks through how to share a webform with any website, webpage, or application.'),
+        'youtube_id' => 'oMgOprfJTWA',
+        'presentation_id' => '1ZYPW5BWh9gm7APrYKAuMdQKksFN2yWqaeN0C4iK127M',
+      ],
+      'cards' => [
+        'title' => $this->t('Webform Cards'),
+        'content' => $this->t('This screencast walks through how to create faster and better multistep form user experiences using the Webform Cards module.'),
+        'youtube_id' => 'bDugc2gWQnw',
+        'presentation_id' => '1N7gaq8jDyrGQUawBr8hvegQUfqESaBUEI3WYNpVfTKw',
+      ],
       'webform' => [
         'title' => $this->t('Webform: There is this for that'),
         'content' => $this->t('One of the key mantras in the Drupal is “there is a module for that, “ and Webform is the module for building forms for Drupal 8.'),
@@ -1371,7 +1382,7 @@ protected function initVideos() {
             'title' => $this->t('Moving Forward with Webform in Drupal 8: Part II | WebWash'),
             'url' => 'https://www.webwash.net/moving-forward-webform-drupal-8/ ',
           ],
-        ]
+        ],
       ],
       'webwash_install' => [
         'title' => $this->t('Using Webform in Drupal 8, 1.1: Install Webform'),
@@ -1624,7 +1635,6 @@ protected function initHelp() {
       ],
     ];
 
-
     /**************************************************************************/
     // Help.
     /**************************************************************************/
@@ -2216,7 +2226,6 @@ protected function initHelp() {
     // Modules.
     /**************************************************************************/
 
-
     // Webform Entity Print (PDF).
     $help['webform_entity_print'] = [
       'group' => 'webform_entity_print',
diff --git a/web/modules/webform/src/WebformInterface.php b/web/modules/webform/src/WebformInterface.php
index 859f429998..45b887e695 100644
--- a/web/modules/webform/src/WebformInterface.php
+++ b/web/modules/webform/src/WebformInterface.php
@@ -134,6 +134,21 @@ interface WebformInterface extends ConfigEntityInterface, EntityWithPluginCollec
    */
   const ACCESS_DENIED_LOGIN = 'login';
 
+  /**
+   * Wizard start page.
+   */
+  const PAGE_START = 'webform_start';
+
+  /**
+   * Wizard preview page.
+   */
+  const PAGE_PREVIEW = 'webform_preview';
+
+  /**
+   * Wizard confirmation page.
+   */
+  const PAGE_CONFIRMATION = 'webform_confirmation';
+
   /**
    * Returns the webform's (original) langcode.
    *
@@ -993,7 +1008,7 @@ public function invokeElements($method, &$data, &$context1 = NULL, &$context2 =
    * @param string $variant_id
    *   The webform variant ID.
    *
-   * @return boolean
+   * @return bool
    *   TRUE if a specific webform variant exists.
    */
   public function hasVariant($variant_id);
@@ -1071,7 +1086,7 @@ public function deleteWebformVariant(WebformVariantInterface $variant);
    * @throws \Exception
    *   Throws exception if submission was not created using this webform.
    */
-  public function applyVariants(WebformSubmissionInterface $webform_submission = NULL, $variants = [], $force = FALSE);
+  public function applyVariants(WebformSubmissionInterface $webform_submission = NULL, array $variants = [], $force = FALSE);
 
   /**
    * Get variants data from a webform submission.
diff --git a/web/modules/webform/src/WebformLibrariesManager.php b/web/modules/webform/src/WebformLibrariesManager.php
index 64d743576f..da94477835 100644
--- a/web/modules/webform/src/WebformLibrariesManager.php
+++ b/web/modules/webform/src/WebformLibrariesManager.php
@@ -175,7 +175,7 @@ public function requirements($cli = FALSE) {
     $description = [
       'info' => $info,
     ];
-    if (!$cli && $severity == REQUIREMENT_WARNING) {
+    if (!$cli && $severity === REQUIREMENT_WARNING) {
       $description['cdn'] = ['#markup' => $this->t('<a href=":href">Disable CDN warning</a>', [':href' => Url::fromRoute('webform.config.advanced')->toString()])];
     }
 
@@ -329,9 +329,9 @@ protected function initLibraries() {
       'description' => $this->t('Code Mirror is a versatile text editor implemented in JavaScript for the browser.'),
       'notes' => $this->t('Code Mirror is used to provide a text editor for YAML, HTML, CSS, and JavaScript configuration settings and messages.'),
       'homepage_url' => Url::fromUri('http://codemirror.net/'),
-      'download_url' => Url::fromUri('https://github.com/components/codemirror/archive/5.51.0.zip'),
+      'download_url' => Url::fromUri('https://github.com/components/codemirror/archive/5.53.2.zip'),
       'issues_url' => Url::fromUri('https://github.com/codemirror/codemirror/issues'),
-      'version' => '5.51.0',
+      'version' => '5.53.2',
     ];
     $libraries['algolia.places'] = [
       'title' => $this->t('Algolia Places'),
@@ -342,8 +342,8 @@ protected function initLibraries() {
       // NOTE: Using NPM/JsDelivr because it contains the '/dist/cdn/' directory.
       // @see https://asset-packagist.org/package/detail?fullname=npm-asset/places.js
       // @see https://www.jsdelivr.com/package/npm/places.js
-      'download_url' => Url::fromUri('https://registry.npmjs.org/places.js/-/places.js-1.17.1.tgz'),
-      'version' => '1.17.1',
+      'download_url' => Url::fromUri('https://registry.npmjs.org/places.js/-/places.js-1.18.2.tgz'),
+      'version' => '1.18.2',
       'elements' => ['webform_location_places'],
     ];
     $libraries['jquery.inputmask'] = [
@@ -376,16 +376,16 @@ protected function initLibraries() {
       'description' => $this->t('A jQuery plugin for counting and limiting characters/words on text input, or textarea, elements.'),
       'notes' => $this->t('Word or character counting, with server-side validation, is available for text fields and text areas.'),
       'homepage_url' => Url::fromUri('https://github.com/ractoon/jQuery-Text-Counter'),
-      'download_url' => Url::fromUri('https://github.com/ractoon/jQuery-Text-Counter/archive/0.8.0.zip'),
-      'version' => '0.8.0',
+      'download_url' => Url::fromUri('https://github.com/ractoon/jQuery-Text-Counter/archive/0.9.0.zip'),
+      'version' => '0.9.0',
     ];
     $libraries['jquery.timepicker'] = [
-      'title' => $this->t('jQuery: Timepicker'),
+      'title' => $this->t('jQuery: Timepicker 1.13.10'),
       'description' => $this->t('A lightweight, customizable javascript timepicker plugin for jQuery, inspired by Google Calendar.'),
       'notes' => $this->t('Timepicker is used to provide a polyfill for HTML 5 time elements.'),
       'homepage_url' => Url::fromUri('https://github.com/jonthornton/jquery-timepicker'),
-      'download_url' => Url::fromUri('https://github.com/jonthornton/jquery-timepicker/archive/1.13.0.zip'),
-      'version' => '1.13.0',
+      'download_url' => Url::fromUri('https://github.com/jonthornton/jquery-timepicker/archive/1.13.10.zip'),
+      'version' => '1.13.10',
     ];
     $libraries['progress-tracker'] = [
       'title' => $this->t('Progress Tracker'),
@@ -409,8 +409,8 @@ protected function initLibraries() {
       'description' => $this->t('Select2 gives you a customizable select box with support for searching and tagging.'),
       'notes' => $this->t('Select2 is used to improve the user experience for select menus. Select2 is the recommended select menu enhancement library.'),
       'homepage_url' => Url::fromUri('https://select2.github.io/'),
-      'download_url' => Url::fromUri('https://github.com/select2/select2/archive/4.0.12.zip'),
-      'version' => '4.0.12',
+      'download_url' => Url::fromUri('https://github.com/select2/select2/archive/4.0.13.zip'),
+      'version' => '4.0.13',
       'module' => $this->moduleHandler->moduleExists('select2') ? 'select2' : '',
     ];
     $libraries['choices'] = [
diff --git a/web/modules/webform/src/WebformMessageManager.php b/web/modules/webform/src/WebformMessageManager.php
index fd60b95a47..774cbb8f5a 100644
--- a/web/modules/webform/src/WebformMessageManager.php
+++ b/web/modules/webform/src/WebformMessageManager.php
@@ -36,7 +36,7 @@ class WebformMessageManager implements WebformMessageManagerInterface {
   protected $configFactory;
 
   /**
-   * Webform submission storage.
+   * The webform submission storage.
    *
    * @var \Drupal\webform\WebformSubmissionStorageInterface
    */
@@ -50,7 +50,7 @@ class WebformMessageManager implements WebformMessageManagerInterface {
   protected $token;
 
   /**
-   * Logger service.
+   * The logger service.
    *
    * @var \Drupal\Core\Logger\LoggerChannelInterface
    */
@@ -64,7 +64,7 @@ class WebformMessageManager implements WebformMessageManagerInterface {
   protected $renderer;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/src/WebformOptionsDeleteForm.php b/web/modules/webform/src/WebformOptionsDeleteForm.php
index e9ce67db7f..01d90a8f88 100644
--- a/web/modules/webform/src/WebformOptionsDeleteForm.php
+++ b/web/modules/webform/src/WebformOptionsDeleteForm.php
@@ -39,7 +39,7 @@ public function getDetails() {
 
     $t_args = [
       '%label' => $this->getEntity()->label(),
-      '@entity-type' => $this->getEntity()->getEntityType()->getLowercaseLabel(),
+      '@entity-type' => $this->getEntity()->getEntityType()->getSingularLabel(),
     ];
 
     $details = [];
diff --git a/web/modules/webform/src/WebformOptionsForm.php b/web/modules/webform/src/WebformOptionsForm.php
index 0c468f9edf..b0112a6677 100644
--- a/web/modules/webform/src/WebformOptionsForm.php
+++ b/web/modules/webform/src/WebformOptionsForm.php
@@ -37,7 +37,7 @@ public static function create(ContainerInterface $container) {
    * {@inheritdoc}
    */
   protected function prepareEntity() {
-    if ($this->operation == 'duplicate') {
+    if ($this->operation === 'duplicate') {
       $this->setEntity($this->getEntity()->createDuplicate());
     }
 
diff --git a/web/modules/webform/src/WebformOptionsListBuilder.php b/web/modules/webform/src/WebformOptionsListBuilder.php
index 22a39ec21b..769effb90c 100644
--- a/web/modules/webform/src/WebformOptionsListBuilder.php
+++ b/web/modules/webform/src/WebformOptionsListBuilder.php
@@ -225,7 +225,7 @@ protected function buildOptions(WebformOptionsInterface $webform_options) {
     $options = WebformOptions::getElementOptions($element);
     $options = OptGroup::flattenOptions($options);
     foreach ($options as $key => &$value) {
-      if ($key != $value) {
+      if ($key !== $value) {
         $value .= ' (' . $key . ')';
       }
     }
diff --git a/web/modules/webform/src/WebformRequest.php b/web/modules/webform/src/WebformRequest.php
index 1ec30eeaf1..79d5b05623 100644
--- a/web/modules/webform/src/WebformRequest.php
+++ b/web/modules/webform/src/WebformRequest.php
@@ -68,7 +68,7 @@ class WebformRequest implements WebformRequestInterface {
   protected $webformEntityReferenceManager;
 
   /**
-   * Webform source entity plugin manager.
+   * The webform source entity plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformSourceEntityManagerInterface
    */
@@ -133,6 +133,7 @@ public function isWebformAdminRoute() {
     else {
       $this->isAdminRoute = (preg_match('/^(webform\.|^entity\.([^.]+\.)?webform)/', $route_name)) ? TRUE : FALSE;
     }
+
     return $this->isAdminRoute;
   }
 
@@ -332,7 +333,7 @@ public function isValidSourceEntity(EntityInterface $webform_entity, EntityInter
 
     // Validate that source entity's field target id is the correct webform.
     $webform_target = $this->webformEntityReferenceManager->getWebform($source_entity);
-    if ($webform_target && $webform_target->id() == $webform->id()) {
+    if ($webform_target && $webform_target->id() === $webform->id()) {
       return TRUE;
     }
     else {
diff --git a/web/modules/webform/src/WebformServiceProvider.php b/web/modules/webform/src/WebformServiceProvider.php
index bfd445bc97..a7553878bb 100644
--- a/web/modules/webform/src/WebformServiceProvider.php
+++ b/web/modules/webform/src/WebformServiceProvider.php
@@ -32,6 +32,17 @@ public function alter(ContainerBuilder $container) {
       $service_definition->addTag('normalizer', ['priority' => 20]);
       $container->setDefinition('serializer.normalizer.webform_entity_reference_item', $service_definition);
     }
+
+    // Overrides webform.exception_html_subscriber to support ExceptionEvent in
+    // Drupal 9/Symfony 4.4.
+    //
+    // Issue #3113876: The "GetResponseForExceptionEvent::getException()"
+    // method is deprecated since Symfony 4.4, use "getThrowable()" instead.
+    // @see https://www.drupal.org/node/3113876
+    if (floatval(\Drupal::VERSION) >= 9) {
+      $definition = $container->getDefinition('webform.exception_html_subscriber');
+      $definition->setClass('Drupal\webform\EventSubscriber\WebformDefaultExceptionHtmlSubscriber');
+    }
   }
 
 }
diff --git a/web/modules/webform/src/WebformSubmissionConditionsValidator.php b/web/modules/webform/src/WebformSubmissionConditionsValidator.php
index 95f314538a..87947fd368 100644
--- a/web/modules/webform/src/WebformSubmissionConditionsValidator.php
+++ b/web/modules/webform/src/WebformSubmissionConditionsValidator.php
@@ -16,7 +16,7 @@
  * Webform submission conditions (#states) validator.
  *
  * @see \Drupal\webform\Element\WebformElementStates
- * @see drupal_process_states()
+ * @see \Drupal\Core\Form\FormHelper::processStates
  */
 class WebformSubmissionConditionsValidator implements WebformSubmissionConditionsValidatorInterface {
 
@@ -345,7 +345,7 @@ protected function validateFormElement(array $element, FormStateInterface $form_
 
       // Determine if the element is required.
       $is_required = $this->validateConditions($conditions, $webform_submission);
-      $is_required = ($state == 'optional') ? !$is_required : $is_required;
+      $is_required = ($state === 'optional') ? !$is_required : $is_required;
       if (!$is_required) {
         continue;
       }
@@ -721,7 +721,7 @@ protected function checkCondition(array $element, $selector, array $condition, W
     // Process trigger sub state used for custom #states API validation.
     // @see Drupal.behaviors.webformStatesComparisions
     // @see http://drupalsun.com/julia-evans/2012/03/09/extending-form-api-states-regular-expressions
-    if ($trigger_state == 'value' && is_array($trigger_value)) {
+    if ($trigger_state === 'value' && is_array($trigger_value)) {
       $trigger_substate = key($trigger_value);
       if (in_array($trigger_substate, ['pattern', '!pattern', 'less', 'greater', 'between'])) {
         $trigger_state = $trigger_substate;
diff --git a/web/modules/webform/src/WebformSubmissionConditionsValidatorInterface.php b/web/modules/webform/src/WebformSubmissionConditionsValidatorInterface.php
index 1764716274..fdfec76489 100644
--- a/web/modules/webform/src/WebformSubmissionConditionsValidatorInterface.php
+++ b/web/modules/webform/src/WebformSubmissionConditionsValidatorInterface.php
@@ -86,7 +86,7 @@ public function validateState($state, array $conditions, WebformSubmissionInterf
    *   processed. NULL is returned when there is an invalid selector or a
    *   missing element in the conditions.
    *
-   * @see drupal_process_states()
+   * @see \Drupal\Core\Form\FormHelper::processStates
    */
   public function validateConditions(array $conditions, WebformSubmissionInterface $webform_submission);
 
diff --git a/web/modules/webform/src/WebformSubmissionExporter.php b/web/modules/webform/src/WebformSubmissionExporter.php
index 8abade0ecb..949be78d11 100644
--- a/web/modules/webform/src/WebformSubmissionExporter.php
+++ b/web/modules/webform/src/WebformSubmissionExporter.php
@@ -34,14 +34,14 @@ class WebformSubmissionExporter implements WebformSubmissionExporterInterface {
   protected $configFactory;
 
   /**
-   * File system service.
+   * The file system service.
    *
    * @var \Drupal\Core\File\FileSystemInterface
    */
   protected $fileSystem;
 
   /**
-   * Webform submission storage.
+   * The webform submission storage.
    *
    * @var \Drupal\webform\WebformSubmissionStorageInterface
    */
@@ -62,14 +62,14 @@ class WebformSubmissionExporter implements WebformSubmissionExporterInterface {
   protected $archiverManager;
 
   /**
-   * Webform element manager.
+   * The webform element manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
   protected $elementManager;
 
   /**
-   * Results exporter manager.
+   * The results exporter manager.
    *
    * @var \Drupal\webform\Plugin\WebformExporterManagerInterface
    */
@@ -521,10 +521,12 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
             '#input' => FALSE,
             '#title' => $this->t('Submitted to'),
             '#description' => $this->t('Select the entity type and then enter the entity id.'),
-            '#field_prefix' => '<div class="container-inline">',
-            '#field_suffix' => '</div>',
           ];
-          $form['export']['download']['submitted']['entity_type'] = [
+          $form['export']['download']['submitted']['container'] = [
+            '#prefix' => '<div class="container-inline">',
+            '#suffix' => '</div>',
+          ];
+          $form['export']['download']['submitted']['container']['entity_type'] = [
             '#type' => 'select',
             '#title' => $this->t('Entity type'),
             '#title_display' => 'invisible',
@@ -534,7 +536,7 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
           if ($export_options['entity_type']) {
             $source_entity_options = $this->entityStorage->getSourceEntityAsOptions($webform, $export_options['entity_type']);
             if ($source_entity_options) {
-              $form['export']['download']['submitted']['entity_id'] = [
+              $form['export']['download']['submitted']['container']['entity_id'] = [
                 '#type' => 'select',
                 '#title' => $this->t('Entity id'),
                 '#title_display' => 'invisible',
@@ -543,7 +545,7 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
               ];
             }
             else {
-              $form['export']['download']['submitted']['entity_id'] = [
+              $form['export']['download']['submitted']['container']['entity_id'] = [
                 '#type' => 'number',
                 '#title' => $this->t('Entity id'),
                 '#title_display' => 'invisible',
@@ -554,7 +556,7 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
             }
           }
           else {
-            $form['export']['download']['submitted']['entity_id'] = [
+            $form['export']['download']['submitted']['container']['entity_id'] = [
               '#type' => 'value',
               '#value' => '',
             ];
@@ -562,7 +564,7 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
           $this->buildAjaxElement(
             'webform-submission-export-download-submitted',
             $form['export']['download']['submitted'],
-            $form['export']['download']['submitted']['entity_type']
+            $form['export']['download']['submitted']['container']['entity_type']
           );
         }
       }
@@ -575,7 +577,9 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
           'latest' => $this->t('Latest'),
           'serial' => $this->t('Submission number'),
           'sid' => $this->t('Submission ID'),
-          'date' => $this->t('Date'),
+          'date' => $this->t('Created date'),
+          'date_completed' => $this->t('Completed date'),
+          'date_changed' => $this->t('Changed date'),
         ],
         '#default_value' => $export_options['range_type'],
       ];
@@ -598,6 +602,8 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
         'serial' => ['#type' => 'number'],
         'sid' => ['#type' => 'number'],
         'date' => ['#type' => 'date'],
+        'date_completed' => ['#type' => 'date'],
+        'date_changed' => ['#type' => 'date'],
       ];
       foreach ($ranges as $key => $range_element) {
         $form['export']['download'][$key] = [
@@ -655,7 +661,7 @@ public function buildExportOptionsForm(array &$form, FormStateInterface $form_st
           'completed' => $this->t('Completed submissions only'),
           'draft' => $this->t('Drafts only'),
         ],
-        '#access' => ($webform->getSetting('draft') != WebformInterface::DRAFT_NONE),
+        '#access' => ($webform->getSetting('draft') !== WebformInterface::DRAFT_NONE),
       ];
     }
 
@@ -864,11 +870,16 @@ public function getQuery() {
         break;
 
       case 'date':
+      case 'date_completed':
+      case 'date_changed':
+        $date_field = preg_match('/date_(completed|changed)/', $export_options['range_type'], $match)
+          ? $match[1]
+          : 'created';
         if ($export_options['range_start']) {
-          $query->condition('created', strtotime($export_options['range_start']), '>=');
+          $query->condition($date_field, strtotime($export_options['range_start']), '>=');
         }
         if ($export_options['range_end']) {
-          $query->condition('created', strtotime('+1 day', strtotime($export_options['range_end'])), '<');
+          $query->condition($date_field, strtotime('+1 day', strtotime($export_options['range_end'])), '<');
         }
         break;
     }
@@ -891,7 +902,7 @@ public function getQuery() {
     }
 
     // Filter by latest.
-    if ($export_options['range_type'] == 'latest' && $export_options['range_latest']) {
+    if ($export_options['range_type'] === 'latest' && $export_options['range_latest']) {
       // Clone the query and use it to get latest sid starting sid.
       $latest_query = clone $query;
       $latest_query->sort('created', 'DESC');
@@ -980,7 +991,7 @@ public function requiresBatch() {
    * {@inheritdoc}
    */
   public function getFileTempDirectory() {
-    return $this->configFactory->get('webform.settings')->get('export.temp_directory') ?: file_directory_temp();
+    return $this->configFactory->get('webform.settings')->get('export.temp_directory') ?: $this->fileSystem->getTempDirectory();
   }
 
   /**
diff --git a/web/modules/webform/src/WebformSubmissionForm.php b/web/modules/webform/src/WebformSubmissionForm.php
index c9848666ff..b84b474a23 100644
--- a/web/modules/webform/src/WebformSubmissionForm.php
+++ b/web/modules/webform/src/WebformSubmissionForm.php
@@ -77,14 +77,14 @@ class WebformSubmissionForm extends ContentEntityForm {
   protected $pathValidator;
 
   /**
-   * The webform element (plugin) manager.
+   * The webform element plugin manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
   protected $elementManager;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
@@ -181,8 +181,6 @@ class WebformSubmissionForm extends ContentEntityForm {
    *
    * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
    *   The entity repository.
-   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
-   *   The entity manager.
    * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
    *   The factory for configuration objects.
    * @param \Drupal\Core\Render\RendererInterface $renderer
@@ -288,7 +286,7 @@ public function getFormId() {
     if ($source_entity = $this->entity->getSourceEntity()) {
       $form_id .= '_' . $source_entity->getEntityTypeId() . '_' . $source_entity->id();
     }
-    if ($this->operation != 'default') {
+    if ($this->operation !== 'default') {
       $form_id .= '_' . $this->operation;
     }
     return $form_id . '_form';
@@ -380,7 +378,7 @@ public function setEntity(EntityInterface $entity) {
         $data = $entity->getRawData();
         $this->operation = 'edit';
       }
-      elseif ($webform->getSetting('draft') != WebformInterface::DRAFT_NONE) {
+      elseif ($webform->getSetting('draft') !== WebformInterface::DRAFT_NONE) {
         if ($webform->getSetting('draft_multiple')) {
           // Allow multiple drafts to be restored using token.
           // This allows the webform's public facing URL to be used instead of
@@ -497,7 +495,13 @@ protected function overrideSettings(WebformSubmissionInterface $webform_submissi
     // Must be called after WebformHandler::overrideSettings which resets all
     // overridden settings.
     // @see \Drupal\webform\Entity\Webform::invokeHandlers
-    if ($this->getRequest()->query->get('_webform_dialog') && !$webform->getSetting('ajax')) {
+    if ($this->getRequest()->query->get('_webform_dialog') && !$webform->getSetting('ajax', TRUE)) {
+      $webform->setSettingOverride('ajax', TRUE);
+    }
+
+    // If share page (i.e. /webform_share/{webform}), enable Ajax support
+    // when this form is embedded in an iframe.
+    if ($this->isSharePage() && !$webform->getSetting('ajax', TRUE)) {
       $webform->setSettingOverride('ajax', TRUE);
     }
   }
@@ -579,7 +583,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     // Ajax: Scroll to.
     // @see \Drupal\webform\Form\WebformAjaxFormTrait::submitAjaxForm
     if ($this->isAjax()) {
-      $form['#webform_ajax_scroll_top'] = $this->getWebformSetting('ajax_scroll_top');
+      $form['#webform_ajax_scroll_top'] = $this->getWebformSetting('ajax_scroll_top', '');
     }
 
     // Alter element's form.
@@ -631,11 +635,11 @@ public function form(array $form, FormStateInterface $form_state) {
     // The data parameter is append to the URL after the form has
     // been submitted.
     //
-    // @see js/webform.form.wizard.js
+    // @see js/webform.wizard.track.js
     $track = $this->getWebform()->getSetting('wizard_track');
     if ($track && $this->getRequest()->isMethod('POST')) {
       $current_page = $this->getCurrentPage($form, $form_state);
-      if ($track == 'index') {
+      if ($track === 'index') {
         $pages = $this->getWebform()->getPages($this->operation);
         $track_pages = array_flip(array_keys($pages));
         $form['#attributes']['data-webform-wizard-current-page'] = ($track_pages[$current_page] + 1);
@@ -745,7 +749,7 @@ public function form(array $form, FormStateInterface $form_state) {
 
     // Add wizard progress tracker and page links to the webform.
     $pages = $webform->getPages($this->operation);
-    if ($pages) {
+    if ($pages && $operation !== 'edit_all') {
       $current_page = $this->getCurrentPage($form, $form_state);
 
       // Add hidden pages submit actions.
@@ -767,7 +771,7 @@ public function form(array $form, FormStateInterface $form_state) {
 
     // Required indicator.
     $current_page = $this->getCurrentPage($form, $form_state);
-    if ($current_page != 'webform_preview' && $this->getWebformSetting('form_required') && $webform->hasRequired()) {
+    if ($current_page !== WebformInterface::PAGE_PREVIEW && $this->getWebformSetting('form_required') && $webform->hasRequired()) {
       $form['required'] = [
         '#theme' => 'webform_required',
         '#label' => $this->getWebformSetting('form_required_label'),
@@ -775,7 +779,10 @@ public function form(array $form, FormStateInterface $form_state) {
     }
 
     // Append elements to the webform.
-    $form['elements'] = $elements;
+    $form['elements'] = [
+      '#type' => 'container',
+      '#attributes' => ['class' => ['webform-elements']],
+    ] + $elements;
 
     // Pages: Set current wizard or preview page.
     $this->displayCurrentPage($form, $form_state);
@@ -830,14 +837,14 @@ protected function getCustomForm(array &$form, FormStateInterface $form_state) {
         return $this->getMessageManager()->append($form, WebformMessageManagerInterface::PREPOPULATE_SOURCE_ENTITY_REQUIRED, 'warning');
       }
       $source_entity_type = $webform->getSetting('form_prepopulate_source_entity_type');
-      if ($source_entity_type && $this->getSourceEntity() && $source_entity_type != $this->getSourceEntity()->getEntityTypeId()) {
+      if ($source_entity_type && $this->getSourceEntity() && $source_entity_type !== $this->getSourceEntity()->getEntityTypeId()) {
         $this->getMessageManager()->log(WebformMessageManagerInterface::PREPOPULATE_SOURCE_ENTITY_TYPE, 'notice');
         return $this->getMessageManager()->append($form, WebformMessageManagerInterface::PREPOPULATE_SOURCE_ENTITY_TYPE, 'warning');
       }
     }
 
     // Display inline confirmation message with back to link.
-    if ($form_state->get('current_page') === 'webform_confirmation') {
+    if ($form_state->get('current_page') === WebformInterface::PAGE_CONFIRMATION) {
       $form['confirmation'] = [
         '#theme' => 'webform_confirmation',
         '#webform' => $webform,
@@ -847,7 +854,16 @@ protected function getCustomForm(array &$form, FormStateInterface $form_state) {
       // Add hidden back (aka reset) button used by the Ajaxified back to link.
       // NOTE: Below code could be used to add a 'Reset' button to any webform.
       // @see Drupal.behaviors.webformConfirmationBackAjax
-      $form['actions'] = ['#type' => 'actions'];
+      $form['actions'] = [
+        '#type' => 'actions',
+        '#attributes' => ['style' => 'display:none'],
+        // Do not process the actions element. This prevents the
+        // .form-actions class from being added, which then makes the button
+        // appear in dialogs.
+        // @see \Drupal\Core\Render\Element\Actions::processActions
+        // @see Drupal.behaviors.dialog.prepareDialogButtons
+        '#process' => [],
+      ];
       $form['actions']['reset'] = [
         '#type' => 'submit',
         '#value' => $this->t('Reset'),
@@ -948,8 +964,8 @@ protected function displayMessages(array $form, FormStateInterface $form_state)
     $webform = $this->getWebform();
     $source_entity = $this->getSourceEntity();
 
-    // Display test message.
-    if ($this->isGet() && $this->operation === 'test') {
+    // Display test message, except on share page.
+    if ($this->isGet() && $this->operation === 'test' && !$this->isSharePage()) {
       $this->getMessageManager()->display(WebformMessageManagerInterface::SUBMISSION_TEST, 'warning');
 
       // Display devel generate link for webform or source entity.
@@ -1008,7 +1024,7 @@ protected function displayMessages(array $form, FormStateInterface $form_state)
       }
       else {
         $draft_submission = $this->getStorage()->loadDraft($webform, $this->sourceEntity, $this->currentUser());
-        if (!$draft_submission || $webform_submission->id() != $draft_submission->id()) {
+        if (!$draft_submission || $webform_submission->id() !== $draft_submission->id()) {
           $this->getMessageManager()->display(WebformMessageManagerInterface::DRAFT_PENDING_SINGLE);
         }
       }
@@ -1117,7 +1133,7 @@ protected function attachBehaviors(array &$form, FormStateInterface $form_state)
       // Set 'data-webform-unsaved' attribute if unsaved wizard.
       $pages = $this->getPages($form, $form_state);
       $current_page = $this->getCurrentPage($form, $form_state);
-      if ($current_page && ($current_page != $this->getFirstPage($pages))) {
+      if ($current_page && ($current_page !== $this->getFirstPage($pages))) {
         $form['#attributes']['data-webform-unsaved'] = TRUE;
       }
       $form['#attached']['library'][] = 'webform/webform.form.unsaved';
@@ -1194,7 +1210,7 @@ protected function pagesElement(array $form, FormStateInterface $form_state) {
     }
 
     $current_page_name = $this->getCurrentPage($form, $form_state);
-    if (!$this->getWebformSetting('wizard_progress_link') && !($this->getWebformSetting('wizard_preview_link') && $current_page_name === 'webform_preview')) {
+    if (!$this->getWebformSetting('wizard_progress_link') && !($this->getWebformSetting('wizard_preview_link') && $current_page_name === WebformInterface::PAGE_PREVIEW)) {
       return NULL;
     }
 
@@ -1249,7 +1265,7 @@ protected function pagesElement(array $form, FormStateInterface $form_state) {
           'data-webform-page' => $page_name,
           'formnovalidate' => 'formnovalidate',
           'class' => ['webform-wizard-pages-link', 'js-webform-wizard-pages-link'],
-          'title' => $this->t("Edit '@label' (Page @start of @end)", $t_args),
+          'title' => $this->t("Edit '@label' (@start of @end)", $t_args),
         ],
         '#access' => $access,
       ];
@@ -1332,16 +1348,16 @@ protected function actions(array $form, FormStateInterface $form_state) {
         case 'name':
           $track_previous_page = $previous_page;
           $track_next_page = $next_page;
-          $track_last_page = 'webform_confirmation';
+          $track_last_page = WebformInterface::PAGE_CONFIRMATION;
           break;
       }
 
-      $is_first_page = ($current_page == $this->getFirstPage($pages)) ? TRUE : FALSE;
-      $is_last_page = (in_array($current_page, ['webform_preview', 'webform_confirmation', $this->getLastPage($pages)])) ? TRUE : FALSE;
-      $is_preview_page = ($current_page == 'webform_preview');
-      $is_next_page_preview = ($next_page == 'webform_preview') ? TRUE : FALSE;
-      $is_next_page_complete = ($next_page == 'webform_confirmation') ? TRUE : FALSE;
-      $is_next_page_optional_preview = ($is_next_page_preview && $preview_mode != DRUPAL_REQUIRED);
+      $is_first_page = ($current_page === $this->getFirstPage($pages)) ? TRUE : FALSE;
+      $is_last_page = (in_array($current_page, [WebformInterface::PAGE_PREVIEW, WebformInterface::PAGE_CONFIRMATION, $this->getLastPage($pages)])) ? TRUE : FALSE;
+      $is_preview_page = ($current_page === WebformInterface::PAGE_PREVIEW);
+      $is_next_page_preview = ($next_page === WebformInterface::PAGE_PREVIEW) ? TRUE : FALSE;
+      $is_next_page_complete = ($next_page === WebformInterface::PAGE_CONFIRMATION) ? TRUE : FALSE;
+      $is_next_page_optional_preview = ($is_next_page_preview && $preview_mode !== DRUPAL_REQUIRED);
 
       // Only show that save button if this is the last page of the wizard or
       // on preview page or right before the optional preview.
@@ -1526,13 +1542,13 @@ public function next(array &$form, FormStateInterface $form_state, $skip_preview
     // submit this form.
     // @see \Drupal\webform\WebformSubmissionForm::wizardSubmit
     if (empty($next_page)) {
-      $next_page = 'webform_confirmation';
+      $next_page = WebformInterface::PAGE_CONFIRMATION;
     }
 
     // Skip preview page and move to the confirmation page.
     // @see
-    if ($skip_preview && $next_page === 'webform_preview') {
-      $next_page = 'webform_confirmation';
+    if ($skip_preview && $next_page === WebformInterface::PAGE_PREVIEW) {
+      $next_page = WebformInterface::PAGE_CONFIRMATION;
     }
 
     // Set next page.
@@ -1575,7 +1591,7 @@ public function previous(array &$form, FormStateInterface $form_state) {
   protected function wizardSubmit(array &$form, FormStateInterface $form_state) {
     $current_page = $form_state->get('current_page');
 
-    if ($current_page === 'webform_confirmation') {
+    if ($current_page === WebformInterface::PAGE_CONFIRMATION) {
       $this->complete($form, $form_state);
       $this->submitForm($form, $form_state);
       $this->save($form, $form_state);
@@ -1611,7 +1627,7 @@ protected function wizardSubmit(array &$form, FormStateInterface $form_state) {
           '@start' => ($current_index + 1),
           '@end' => $total_pages,
         ];
-        $this->announce($this->t('"@title: @page" loaded. (Page @start of @end)', $t_args));
+        $this->announce($this->t('"@title: @page" loaded. (@start of @end)', $t_args));
       }
     }
   }
@@ -1742,7 +1758,7 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
     if (isset($trigger_element['#validate'])) {
       $handlers = array_filter($form['#validate'], function ($callback) {
         // Remove ::validateForm to prevent a recursion.
-        return (is_array($callback) || $callback != '::validateForm');
+        return (is_array($callback) || $callback !== '::validateForm');
       });
       // @see \Drupal\Core\Form\FormValidator::executeValidateHandlers
       foreach ($handlers as $callback) {
@@ -1795,7 +1811,7 @@ public function confirmForm(array &$form, FormStateInterface $form_state) {
       // @see \Drupal\webform\WebformSubmissionForm::setConfirmation
       if ($state === WebformSubmissionInterface::STATE_UPDATED) {
         if (!$this->getRequest()->get('destination')) {
-          $this->reset($form, $form_state);
+          $this->rebuild($form, $form_state);
         }
       }
       elseif ($confirmation_type === WebformInterface::CONFIRMATION_MESSAGE || $confirmation_type === WebformInterface::CONFIRMATION_NONE) {
@@ -2019,7 +2035,7 @@ protected function getUploadedManagedFileIds() {
    */
   protected function setFormPropertiesFromElements(array &$form, array &$elements) {
     foreach ($elements as $key => $value) {
-      if (is_string($key) && $key[0] == '#') {
+      if (is_string($key) && $key[0] === '#') {
         $value = $this->tokenManager->replace($value, $this->getEntity());
         if (isset($form[$key]) && is_array($form[$key]) && is_array($value)) {
           $form[$key] = NestedArray::mergeDeep($form[$key], $value);
@@ -2174,7 +2190,7 @@ protected function getPreviousPage(array $pages, $current_page) {
    */
   protected function displayCurrentPage(array &$form, FormStateInterface $form_state) {
     $current_page = $this->getCurrentPage($form, $form_state);
-    if ($current_page == 'webform_preview') {
+    if ($current_page === WebformInterface::PAGE_PREVIEW) {
       // Hide all elements except 'webform_actions'.
       foreach ($form['elements'] as $element_key => $element) {
         if (isset($element['#type']) && $element['#type'] === 'webform_actions') {
@@ -2212,7 +2228,7 @@ protected function displayCurrentPage(array &$form, FormStateInterface $form_sta
           $page_element =& $form['elements'][$page_key];
           $page_element_plugin = $this->elementManager->getElementInstance($page_element);
           if ($page_element_plugin instanceof WebformElementWizardPageInterface) {
-            if ($page_key != $current_page) {
+            if ($page_key !== $current_page) {
               $page_element_plugin->hidePage($page_element);
             }
             else {
@@ -2309,7 +2325,7 @@ protected function setConfirmation(FormStateInterface $form_state) {
           $redirect_url = $this->pathValidator->getUrlIfValid($confirmation_url);
         }
         if ($redirect_url) {
-          if ($confirmation_type == WebformInterface::CONFIRMATION_URL_MESSAGE) {
+          if ($confirmation_type === WebformInterface::CONFIRMATION_URL_MESSAGE) {
             $this->getMessageManager()->display(WebformMessageManagerInterface::SUBMISSION_CONFIRMATION_MESSAGE);
           }
           $this->setTrustedRedirectUrl($form_state, $redirect_url);
@@ -2335,7 +2351,7 @@ protected function setConfirmation(FormStateInterface $form_state) {
         return;
 
       case WebformInterface::CONFIRMATION_INLINE:
-        $form_state->set('current_page', 'webform_confirmation');
+        $form_state->set('current_page', WebformInterface::PAGE_CONFIRMATION);
         $form_state->setRebuild();
         return;
 
@@ -2782,7 +2798,7 @@ protected function isFormNoValidate() {
    *   TRUE if the webform is being initially loaded via GET method.
    */
   protected function isGet() {
-    return ($this->getRequest()->getMethod() == 'GET') ? TRUE : FALSE;
+    return ($this->getRequest()->getMethod() === 'GET') ? TRUE : FALSE;
   }
 
   /**
@@ -2795,7 +2811,7 @@ protected function isGet() {
    *   TRUE if the current request is a specific route (name).
    */
   protected function isRoute($route_name) {
-    return ($this->requestHandler->getRouteName($this->getEntity(), $this->getSourceEntity(), $route_name) == $this->getRouteMatch()->getRouteName()) ? TRUE : FALSE;
+    return ($this->requestHandler->getRouteName($this->getEntity(), $this->getSourceEntity(), $route_name) === $this->getRouteMatch()->getRouteName()) ? TRUE : FALSE;
   }
 
   /**
@@ -2814,7 +2830,7 @@ protected function isWebformEntityReferenceFromSourceEntity() {
       return FALSE;
     }
 
-    return ($webform->id() == $this->getWebform()->id()) ? TRUE : FALSE;
+    return ($webform->id() === $this->getWebform()->id()) ? TRUE : FALSE;
   }
 
   /****************************************************************************/
@@ -2877,7 +2893,7 @@ protected function getLimitSourceEntity() {
     $webform_submission = $this->getEntity();
 
     $source_entity = $webform_submission->getSourceEntity();
-    if ($source_entity && $source_entity->getEntityTypeId() != 'webform') {
+    if ($source_entity && $source_entity->getEntityTypeId() !== 'webform') {
       return $source_entity;
     }
     return NULL;
@@ -2924,6 +2940,20 @@ protected function getWebformSetting($name, $default_value = NULL) {
     }
   }
 
+  /****************************************************************************/
+  // Share functions.
+  /****************************************************************************/
+
+  /**
+   * Determine if the submission form is being embedded in a share page.
+   *
+   * @return bool
+   *   TRUE the submission form is being embedded in a share page.
+   */
+  protected function isSharePage() {
+    return (strpos($this->getRouteMatch()->getRouteName(), 'entity.webform.share_page') === 0);
+  }
+
   /****************************************************************************/
   // Ajax functions.
   // @see \Drupal\webform\Form\WebformAjaxFormTrait
diff --git a/web/modules/webform/src/WebformSubmissionInterface.php b/web/modules/webform/src/WebformSubmissionInterface.php
index 1e2ba8c776..899e56afe6 100644
--- a/web/modules/webform/src/WebformSubmissionInterface.php
+++ b/web/modules/webform/src/WebformSubmissionInterface.php
@@ -65,6 +65,24 @@ interface WebformSubmissionInterface extends ContentEntityInterface, EntityOwner
    */
   public function serial();
 
+  /**
+   * Gets the langcode of the field values held in the object.
+   *
+   * @return string
+   *   The langcode.
+   */
+  public function getLangcode();
+
+  /**
+   * Sets the langcode of the field values held in the object.
+   *
+   * @param string $langcode
+   *   The langcode.
+   *
+   * @return $this
+   */
+  public function setLangcode($langcode);
+
   /**
    * Returns the time that the submission was created.
    *
diff --git a/web/modules/webform/src/WebformSubmissionListBuilder.php b/web/modules/webform/src/WebformSubmissionListBuilder.php
index 21a466842a..c9a40fa870 100644
--- a/web/modules/webform/src/WebformSubmissionListBuilder.php
+++ b/web/modules/webform/src/WebformSubmissionListBuilder.php
@@ -383,7 +383,7 @@ public function __construct(EntityTypeInterface $entity_type, EntityStorageInter
         $this->customize = $this->webform->access('update')
           || $this->webform->getSetting('results_customize', TRUE);
 
-        if ($this->format['element_format'] == 'raw') {
+        if ($this->format['element_format'] === 'raw') {
           foreach ($this->columns as &$column) {
             $column['format'] = 'raw';
             if (isset($column['element'])) {
@@ -638,16 +638,16 @@ protected function buildFilterForm() {
     // State options.
     $state_options = [
       '' => $this->t('All [@total]', ['@total' => $this->getTotal(NULL, NULL, $this->sourceEntityTypeId)]),
-      self::STATE_STARRED => $this->t('Starred [@total]', ['@total' => $this->getTotal(NULL, self::STATE_STARRED, $this->sourceEntityTypeId)]),
-      self::STATE_UNSTARRED => $this->t('Unstarred [@total]', ['@total' => $this->getTotal(NULL, self::STATE_UNSTARRED, $this->sourceEntityTypeId)]),
-      self::STATE_LOCKED => $this->t('Locked [@total]', ['@total' => $this->getTotal(NULL, self::STATE_LOCKED, $this->sourceEntityTypeId)]),
-      self::STATE_UNLOCKED => $this->t('Unlocked [@total]', ['@total' => $this->getTotal(NULL, self::STATE_UNLOCKED, $this->sourceEntityTypeId)]),
+      static::STATE_STARRED => $this->t('Starred [@total]', ['@total' => $this->getTotal(NULL, static::STATE_STARRED, $this->sourceEntityTypeId)]),
+      static::STATE_UNSTARRED => $this->t('Unstarred [@total]', ['@total' => $this->getTotal(NULL, static::STATE_UNSTARRED, $this->sourceEntityTypeId)]),
+      static::STATE_LOCKED => $this->t('Locked [@total]', ['@total' => $this->getTotal(NULL, static::STATE_LOCKED, $this->sourceEntityTypeId)]),
+      static::STATE_UNLOCKED => $this->t('Unlocked [@total]', ['@total' => $this->getTotal(NULL, static::STATE_UNLOCKED, $this->sourceEntityTypeId)]),
     ];
     // Add draft to state options.
-    if (!$this->webform || $this->webform->getSetting('draft') != WebformInterface::DRAFT_NONE) {
+    if (!$this->webform || $this->webform->getSetting('draft') !== WebformInterface::DRAFT_NONE) {
       $state_options += [
-        self::STATE_COMPLETED => $this->t('Completed [@total]', ['@total' => $this->getTotal(NULL, self::STATE_COMPLETED, $this->sourceEntityTypeId)]),
-        self::STATE_DRAFT => $this->t('Draft [@total]', ['@total' => $this->getTotal(NULL, self::STATE_DRAFT, $this->sourceEntityTypeId)]),
+        static::STATE_COMPLETED => $this->t('Completed [@total]', ['@total' => $this->getTotal(NULL, static::STATE_COMPLETED, $this->sourceEntityTypeId)]),
+        static::STATE_DRAFT => $this->t('Draft [@total]', ['@total' => $this->getTotal(NULL, static::STATE_DRAFT, $this->sourceEntityTypeId)]),
       ];
     }
 
@@ -788,7 +788,7 @@ public function buildHeader() {
    */
   protected function buildHeaderColumn(array $column) {
     $name = $column['name'];
-    if ($this->format['header_format'] == 'key') {
+    if ($this->format['header_format'] === 'key') {
       $title = isset($column['key']) ? $column['key'] : $column['name'];
     }
     else {
@@ -857,7 +857,7 @@ public function buildRow(EntityInterface $entity) {
   public function buildRowColumn(array $column, EntityInterface $entity) {
     /** @var \Drupal\webform\WebformSubmissionInterface $entity */
 
-    $is_raw = ($column['format'] == 'raw');
+    $is_raw = ($column['format'] === 'raw');
     $name = $column['name'];
 
     switch ($name) {
@@ -878,7 +878,7 @@ public function buildRowColumn(array $column, EntityInterface $entity) {
         return ($is_raw) ? $source_entity->getEntityTypeId . ':' . $source_entity->id() : ($source_entity->hasLinkTemplate('canonical') ? $source_entity->toLink() : $source_entity->label());
 
       case 'langcode':
-        $langcode = $entity->langcode->value;
+        $langcode = $entity->getLangcode();
         if (!$langcode) {
           return '';
         }
@@ -925,14 +925,14 @@ public function buildRowColumn(array $column, EntityInterface $entity) {
         else {
           $link_url = $this->requestHandler->getUrl($entity, $entity->getSourceEntity(), $this->getSubmissionRouteName());
         }
-        if ($name == 'serial') {
+        if ($name === 'serial') {
           $link_text = $entity->serial();
         }
         else {
           $link_text = $entity->label();
         }
         $link = Link::fromTextAndUrl($link_text, $link_url)->toRenderable();
-        if ($name == 'serial') {
+        if ($name === 'serial') {
           $link['#attributes']['title'] = $entity->label();
           $link['#attributes']['aria-label'] = $entity->label();
         }
@@ -1306,7 +1306,7 @@ protected function getEntityIds() {
       // Must manually initialize the pager because the DISTINCT clause in the
       // query is breaking the row counting.
       // @see webform_query_alter()
-      pager_default_initialize($this->total, $this->limit);
+      \Drupal::service('pager.manager')->createPager($this->total, $this->limit);
       return $result;
     }
     else {
@@ -1393,27 +1393,27 @@ protected function getQuery($keys = '', $state = '', $source_entity = '') {
 
     // Filter by (submission) state.
     switch ($state) {
-      case self::STATE_STARRED:
+      case static::STATE_STARRED:
         $query->condition('sticky', 1);
         break;
 
-      case self::STATE_UNSTARRED:
+      case static::STATE_UNSTARRED:
         $query->condition('sticky', 0);
         break;
 
-      case self::STATE_LOCKED:
+      case static::STATE_LOCKED:
         $query->condition('locked', 1);
         break;
 
-      case self::STATE_UNLOCKED:
+      case static::STATE_UNLOCKED:
         $query->condition('locked', 0);
         break;
 
-      case self::STATE_DRAFT:
+      case static::STATE_DRAFT:
         $query->condition('in_draft', 1);
         break;
 
-      case self::STATE_COMPLETED:
+      case static::STATE_COMPLETED:
         $query->condition('in_draft', 0);
         break;
     }
diff --git a/web/modules/webform/src/WebformSubmissionNotesForm.php b/web/modules/webform/src/WebformSubmissionNotesForm.php
index 3dc0b8709f..2b4805a81c 100644
--- a/web/modules/webform/src/WebformSubmissionNotesForm.php
+++ b/web/modules/webform/src/WebformSubmissionNotesForm.php
@@ -18,7 +18,7 @@ class WebformSubmissionNotesForm extends ContentEntityForm {
   use WebformDialogFormTrait;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/src/WebformSubmissionStorage.php b/web/modules/webform/src/WebformSubmissionStorage.php
index 3338d84341..aae49aa3ff 100644
--- a/web/modules/webform/src/WebformSubmissionStorage.php
+++ b/web/modules/webform/src/WebformSubmissionStorage.php
@@ -67,7 +67,7 @@ class WebformSubmissionStorage extends SqlContentEntityStorage implements Webfor
   protected $fileSystem;
 
   /**
-   * Webform access rules manager service.
+   * The webform access rules manager service.
    *
    * @var \Drupal\webform\WebformAccessRulesManagerInterface
    */
@@ -222,7 +222,7 @@ public function loadFromToken($token, WebformInterface $webform, EntityInterface
     $entity = reset($entities);
 
     // Make sure the submission is associated with the webform.
-    if ($entity->getWebform()->id() != $webform->id()) {
+    if ($entity->getWebform()->id() !== $webform->id()) {
       return NULL;
     }
 
@@ -281,11 +281,8 @@ public function getTotal(WebformInterface $webform = NULL, EntityInterface $sour
     $query = $this->getQuery();
     $query->accessCheck(FALSE);
     $this->addQueryConditions($query, $webform, $source_entity, $account, $options);
-
-    // Issue: Query count method is not working for SQL Lite.
-    // return $query->count()->execute();
-    // Work-around: Manually count the number of entity ids.
-    return count($query->execute());
+    $query->count();
+    return $query->execute();
   }
 
   /**
@@ -311,6 +308,7 @@ public function hasSubmissionValue(WebformInterface $webform, $element_key) {
       ->fields('sd', ['sid'])
       ->condition('sd.webform_id', $webform->id())
       ->condition('sd.name', $element_key)
+      ->range(0, 1)
       ->execute();
     return $result->fetchAssoc() ? TRUE : FALSE;
   }
@@ -437,7 +435,7 @@ private function _addQueryConditions($query, WebformInterface $webform = NULL, E
     if ($account) {
       $query->condition('uid', $account->id());
       // Add anonymous submission ids stored in $_SESSION.
-      if ($account->isAnonymous() && $account->id() == $this->currentUser->id()) {
+      if ($account->isAnonymous() && (int) $account->id() === (int) $this->currentUser->id()) {
         $sids = $this->getAnonymousSubmissionIds($account);
         if (empty($sids)) {
           // Look for NULL sid to force returning no results.
@@ -557,7 +555,7 @@ protected function getTerminusSubmission(WebformInterface $webform, EntityInterf
     $options += ['in_draft' => FALSE];
     $query = $this->getQuery();
     $this->addQueryConditions($query, $webform, $source_entity, $account, $options);
-    $query->sort('sid', ($terminus == 'first') ? 'ASC' : 'DESC');
+    $query->sort('sid', ($terminus === 'first') ? 'ASC' : 'DESC');
     $query->range(0, 1);
     return ($entity_ids = $query->execute()) ? $this->load(reset($entity_ids)) : NULL;
   }
@@ -585,7 +583,7 @@ protected function getSiblingSubmission(WebformSubmissionInterface $webform_subm
     $query = $this->getQuery();
     $this->addQueryConditions($query, $webform, $source_entity, $account, $options);
 
-    if ($direction == 'previous') {
+    if ($direction === 'previous') {
       $query->condition('sid', $webform_submission->id(), '<');
       $query->sort('sid', 'DESC');
     }
@@ -910,7 +908,7 @@ public function getCustomSetting($name, $default, WebformInterface $webform = NU
       }
     }
 
-    $source_entity_key = $key .'.' . $source_entity->getEntityTypeId() . '.' . $source_entity->id();
+    $source_entity_key = $key . '.' . $source_entity->getEntityTypeId() . '.' . $source_entity->id();
     if ($results_customize && $webform->hasUserData($source_entity_key)) {
       return $webform->getUserData($source_entity_key);
     }
@@ -1168,7 +1166,7 @@ public function delete(array $entities) {
           $file_directory = $stream_wrapper . '://webform/' . $webform->id() . '/' . $entity->id();
           // Clear empty webform submission directory.
           if (file_exists($file_directory)
-            && empty(file_scan_directory($file_directory, '/.*/'))) {
+            && empty($this->fileSystem->scanDirectory($file_directory, '/.*/'))) {
             $this->fileSystem->deleteRecursive($file_directory);
           }
         }
@@ -1224,7 +1222,7 @@ public function purge($count) {
 
     $query = $this->entityManager->getStorage('webform')->getQuery();
     $query->accessCheck(FALSE);
-    $query->condition('settings.purge', [self::PURGE_DRAFT, self::PURGE_COMPLETED, self::PURGE_ALL], 'IN');
+    $query->condition('settings.purge', [WebformSubmissionStorageInterface::PURGE_DRAFT, WebformSubmissionStorageInterface::PURGE_COMPLETED, WebformSubmissionStorageInterface::PURGE_ALL], 'IN');
     $query->condition('settings.purge_days', 0, '>');
     $webforms_to_purge = array_values($query->execute());
 
@@ -1241,11 +1239,11 @@ public function purge($count) {
         $query->condition('created', $this->time->getRequestTime() - ($webform->getSetting('purge_days') * $days_to_seconds), '<');
         $query->condition('webform_id', $webform->id());
         switch ($webform->getSetting('purge')) {
-          case self::PURGE_DRAFT:
+          case WebformSubmissionStorageInterface::PURGE_DRAFT:
             $query->condition('in_draft', 1);
             break;
 
-          case self::PURGE_COMPLETED:
+          case WebformSubmissionStorageInterface::PURGE_COMPLETED:
             $query->condition('in_draft', 0);
             break;
         }
@@ -1254,7 +1252,7 @@ public function purge($count) {
         if (!empty($result)) {
           $webform_submissions_to_purge = array_merge($webform_submissions_to_purge, $result);
         }
-        if (count($webform_submissions_to_purge) == $count) {
+        if (count($webform_submissions_to_purge) === $count) {
           // We've collected enough webform submissions for purging in this run.
           break;
         }
@@ -1520,7 +1518,7 @@ public function userLogin(UserInterface $account) {
    */
   public function getAnonymousSubmissionIds(AccountInterface $account) {
     // Make sure the account and current user are identical.
-    if ($account->id() != $this->currentUser->id()) {
+    if ((int) $account->id() !== (int) $this->currentUser->id()) {
       return NULL;
     }
 
@@ -1568,7 +1566,7 @@ public function getAnonymousSubmissionIds(AccountInterface $account) {
    */
   protected function setAnonymousSubmission(WebformSubmissionInterface $webform_submission) {
     // Make sure the account and current user are identical.
-    if ($webform_submission->getOwnerId() != $this->currentUser->id()) {
+    if ((int)$webform_submission->getOwnerId() !== (int) $this->currentUser->id()) {
       return;
     }
 
diff --git a/web/modules/webform/src/WebformSubmissionViewBuilder.php b/web/modules/webform/src/WebformSubmissionViewBuilder.php
index a6f0a2e640..080050bd3c 100644
--- a/web/modules/webform/src/WebformSubmissionViewBuilder.php
+++ b/web/modules/webform/src/WebformSubmissionViewBuilder.php
@@ -29,7 +29,7 @@ class WebformSubmissionViewBuilder extends EntityViewBuilder implements WebformS
   protected $routeMatch;
 
   /**
-   * Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
diff --git a/web/modules/webform/src/WebformThemeManager.php b/web/modules/webform/src/WebformThemeManager.php
index d197575a12..e6e0045991 100644
--- a/web/modules/webform/src/WebformThemeManager.php
+++ b/web/modules/webform/src/WebformThemeManager.php
@@ -110,13 +110,14 @@ public function getThemeName($name) {
    *   An associative array containing theme name.
    */
   public function getThemeNames() {
-    $themes = ['' => $this->t('Default')];
+    $themes = [];
     foreach ($this->themeHandler->listInfo() as $name => $theme) {
       if ($theme->status === 1) {
         $themes[$name] = $theme->info['name'];
       }
     }
-    return $themes;
+    asort($themes);
+    return ['' => $this->t('Default')] + $themes;
   }
 
   /**
diff --git a/web/modules/webform/src/WebformTranslationManager.php b/web/modules/webform/src/WebformTranslationManager.php
index 684c19f892..f7cc799733 100644
--- a/web/modules/webform/src/WebformTranslationManager.php
+++ b/web/modules/webform/src/WebformTranslationManager.php
@@ -40,7 +40,7 @@ class WebformTranslationManager implements WebformTranslationManagerInterface {
   protected $configFactory;
 
   /**
-   * Webform element manager.
+   * The webform element manager.
    *
    * @var \Drupal\webform\Plugin\WebformElementManagerInterface
    */
@@ -177,7 +177,7 @@ public function getSourceElements(WebformInterface $webform) {
   public function getTranslationElements(WebformInterface $webform, $langcode) {
     $elements = $this->getSourceElements($webform);
     $translation_elements = $this->getElements($webform, $langcode);
-    if ($elements == $translation_elements) {
+    if ($elements === $translation_elements) {
       return $elements;
     }
     WebformElementHelper::merge($elements, $translation_elements);
diff --git a/web/modules/webform/templates/webform-element-audio-file.html.twig b/web/modules/webform/templates/webform-element-audio-file.html.twig
index 4405eeb367..58b70eb241 100644
--- a/web/modules/webform/templates/webform-element-audio-file.html.twig
+++ b/web/modules/webform/templates/webform-element-audio-file.html.twig
@@ -11,7 +11,7 @@
  * - file_link: Link to the file.
  *
  * @see http://caniuse.com/#feat=audio
- * @see http://www.w3schools.com/html/html5_audio.asp
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio
  */
 #}
 {% if extension == 'mp3' %}
diff --git a/web/modules/webform/templates/webform-element-more.html.twig b/web/modules/webform/templates/webform-element-more.html.twig
index 52c706caf6..42a3dac319 100644
--- a/web/modules/webform/templates/webform-element-more.html.twig
+++ b/web/modules/webform/templates/webform-element-more.html.twig
@@ -17,10 +17,10 @@
 #}
 {{ attach_library('webform/webform.element.more') }}
 {%
-set classes = [
-  'js-webform-element-more',
-  'webform-element-more',
-]
+  set classes = [
+    'js-webform-element-more',
+    'webform-element-more',
+  ]
 %}
 <div{{ attributes.addClass(classes) }}>
   <div class="webform-element-more--link"><a role="button" href="#{{ attributes.id }}--content">{{ more_title }}</a></div>
diff --git a/web/modules/webform/templates/webform-element-video-file.html.twig b/web/modules/webform/templates/webform-element-video-file.html.twig
index abef2d223b..a3d74ed53d 100644
--- a/web/modules/webform/templates/webform-element-video-file.html.twig
+++ b/web/modules/webform/templates/webform-element-video-file.html.twig
@@ -11,7 +11,7 @@
  * - file_link: Link to the file.
  *
  * @see http://caniuse.com/#feat=video
- * @see http://www.w3schools.com/html/html5_audio.asp
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video
  */
 #}
 {% if extension == 'mp4' %}
diff --git a/web/modules/webform/templates/webform-handler-action-summary.html.twig b/web/modules/webform/templates/webform-handler-action-summary.html.twig
index a83868182b..8acd2d68ba 100644
--- a/web/modules/webform/templates/webform-handler-action-summary.html.twig
+++ b/web/modules/webform/templates/webform-handler-action-summary.html.twig
@@ -10,7 +10,6 @@
  * @ingroup themeable
  */
 #}
-
 {% if settings.debug %}<b class="color-error">{{ 'Debugging is enabled'|t }}</b><br />{% endif %}
 {% if settings.sticky is not null %}<b>{{ 'Status:'|t }}</b> {{ settings.sticky ? 'Flag/Star'|t : 'Unflag/Unstar'|t }}<br />{% endif %}
 {% if settings.locked is not null %}<b>{{ 'Lock:'|t }}</b> {{ settings.locked ? 'Locked'|t : 'Unlocked'|t }}<br />{% endif %}
diff --git a/web/modules/webform/templates/webform-handler-debug-summary.html.twig b/web/modules/webform/templates/webform-handler-debug-summary.html.twig
index 38128ed524..66db74df3e 100644
--- a/web/modules/webform/templates/webform-handler-debug-summary.html.twig
+++ b/web/modules/webform/templates/webform-handler-debug-summary.html.twig
@@ -10,5 +10,4 @@
  * @ingroup themeable
  */
 #}
-
 {{ 'Submission values will be displayed onscreen.'|t }}
diff --git a/web/modules/webform/templates/webform-handler-email-summary.html.twig b/web/modules/webform/templates/webform-handler-email-summary.html.twig
index 8822649090..7042bfb5c6 100644
--- a/web/modules/webform/templates/webform-handler-email-summary.html.twig
+++ b/web/modules/webform/templates/webform-handler-email-summary.html.twig
@@ -10,6 +10,7 @@
  * @ingroup themeable
  */
 #}
+
 {% if settings.debug %}<b class="color-error">{{ 'Debugging is enabled'|t }}</b><br />{% endif %}
 <b>{{ 'To:'|t }}</b> {{ settings.to_mail|replace({',': ', '}) }}<br />
 {% if settings.cc_mail %}<b>{{ 'CC:'|t }}</b> {{ settings.cc_mail|replace({',': ', '}) }}<br />{% endif %}
diff --git a/web/modules/webform/templates/webform-handler-remote-post-summary.html.twig b/web/modules/webform/templates/webform-handler-remote-post-summary.html.twig
index 696085829d..a99f6d1355 100644
--- a/web/modules/webform/templates/webform-handler-remote-post-summary.html.twig
+++ b/web/modules/webform/templates/webform-handler-remote-post-summary.html.twig
@@ -18,5 +18,6 @@
 {% if settings.converted_url %}<b>{{ 'Converted URL:'|t }}</b> {{ settings.converted_url }}<br />{% endif %}
 {% if settings.error_url %}<b>{{ 'Error URL:'|t }}</b> {{ settings.error_url }}<br />{% endif %}
 <b>{{ 'Method:'|t }}</b> {{ settings.method }}<br />
-{% if settings.method == 'POST' %}<b>{{ 'Type:'|t }}</b> {{ settings.type }}<br />{% endif %}
+{% if settings.method == 'POST' %}<b>{{ 'Post type:'|t }}</b> {{ settings.type }}<br />{% endif %}
+{% if settings.cast %}<b>{{ 'Type casting:'|t }}</b> {{ 'Enabled' }}<br />{% endif %}
 {% if settings.message or settings.messages %}<b>{{ 'Response message:'|t }}</b> {{ 'Yes'|t }}<br/>{% endif %}
diff --git a/web/modules/webform/templates/webform-handler-settings-summary.html.twig b/web/modules/webform/templates/webform-handler-settings-summary.html.twig
index c139e50c54..cf760cc2b5 100644
--- a/web/modules/webform/templates/webform-handler-settings-summary.html.twig
+++ b/web/modules/webform/templates/webform-handler-settings-summary.html.twig
@@ -10,7 +10,6 @@
  * @ingroup themeable
  */
 #}
-
 {% if settings.debug %}<b class="color-error">{{ 'Debugging is enabled'|t }}</b><br />{% endif %}
 {% for setting in settings.settings %}
   <b>{{ setting.title }}:</b> {{ setting.value }}<br />
diff --git a/web/modules/webform/templates/webform-horizontal-rule.html.twig b/web/modules/webform/templates/webform-horizontal-rule.html.twig
index 63906ca432..d1a2b80e0e 100644
--- a/web/modules/webform/templates/webform-horizontal-rule.html.twig
+++ b/web/modules/webform/templates/webform-horizontal-rule.html.twig
@@ -13,8 +13,8 @@
 #}
 {{ attach_library('webform/webform.element.horizontal_rule') }}
 {%
-set classes = [
-  'webform-horizontal-rule',
-]
+  set classes = [
+    'webform-horizontal-rule',
+  ]
 %}
 <hr{{ attributes.addClass(classes) }} />
diff --git a/web/modules/webform/templates/webform-message.html.twig b/web/modules/webform/templates/webform-message.html.twig
index 920fb868f9..ad03702aa3 100644
--- a/web/modules/webform/templates/webform-message.html.twig
+++ b/web/modules/webform/templates/webform-message.html.twig
@@ -23,5 +23,5 @@
   ]
 %}
 {% if not closed %}
-<div{{ attributes.addClass(classes) }}>{{ message }}</div>
+  <div{{ attributes.addClass(classes) }}>{{ message }}</div>
 {% endif %}
diff --git a/web/modules/webform/templates/webform-progress-bar.html.twig b/web/modules/webform/templates/webform-progress-bar.html.twig
index e3227e6e67..8fed60ca2b 100644
--- a/web/modules/webform/templates/webform-progress-bar.html.twig
+++ b/web/modules/webform/templates/webform-progress-bar.html.twig
@@ -17,17 +17,20 @@
  */
 #}
 {{ attach_library('webform/webform.progress.bar') }}
-
+{% spaceless %}
 {% if progress|length < max_pages %}
-<ol class="webform-progress-bar" data-steps="{{ progress|length }}">
-{% for index, page in progress %}{%
-  set classes = [
-    'webform-progress-bar__page',
-    index < current_index ? 'webform-progress-bar__page--done',
-    index == current_index ? 'webform-progress-bar__page--current',
-  ]
-%}<li{{ attributes.setAttribute('data-webform-page', page.name).setAttribute('class', '').addClass(classes) }}>
-  <b>{{ page.title }}</b>{% if (loop.first	or loop.last) %}<span></span>{% endif %}
-</li>{% endfor %}
-</ol>
+  <ol class="webform-progress-bar" data-steps="{{ progress|length }}">
+  {% for index, page in progress %}
+    {%
+      set classes = [
+        'webform-progress-bar__page',
+        index < current_index ? 'webform-progress-bar__page--done',
+        index == current_index ? 'webform-progress-bar__page--current',
+      ]
+    %}
+    <li{{ attributes.setAttribute('data-webform-page', page.name).setAttribute('class', '').addClass(classes) }}>
+      <b>{{ page.title }}</b>{% if (loop.first	or loop.last) %}<span></span>{% endif %}
+    </li>{% endfor %}
+  </ol>
 {% endif %}
+{% endspaceless %}
diff --git a/web/modules/webform/templates/webform-progress-tracker.html.twig b/web/modules/webform/templates/webform-progress-tracker.html.twig
index 2de6d27158..688e6e2782 100644
--- a/web/modules/webform/templates/webform-progress-tracker.html.twig
+++ b/web/modules/webform/templates/webform-progress-tracker.html.twig
@@ -19,7 +19,7 @@
 #}
 {{ attach_library('webform/webform.progress.tracker') }}
 
-<ul class="webform-progress-tracker progress-tracker progress-tracker--center">
+<ul class="webform-progress-tracker progress-tracker progress-tracker--center" data-webform-progress-steps>
   {% for index, page in progress %}
     {% set is_completed = index < current_index %}
     {% set is_active = index == current_index %}
@@ -30,14 +30,19 @@
         is_active ? 'is-active',
       ]
     %}
-    <li{{ attributes.setAttribute('data-webform-page', page.name).setAttribute('title', page.title).setAttribute('class', '').addClass(classes) }}>
-      <span class="progress-marker">{{ index + 1 }}</span>
+    {%
+      set attributes = create_attribute()
+        .setAttribute('data-webform-' ~ page.type, page.name)
+        .setAttribute('title', page.title)
+        .setAttribute('class', '')
+        .addClass(classes)
+    %}
+    <li{{ attributes }}>
+      <span class="progress-marker" data-webform-progress-step data-webform-progress-link>{{ index + 1 }}</span>
       {% if progress|length < max_pages %}
         <span class="progress-text">
-          <span class="progress-title">
-            {% if is_active or is_completed %}
-              <span class="visually-hidden">{{ is_active ? 'Current'|t : 'Completed'|t }}: </span>
-            {% endif %}
+          <span class="progress-title" data-webform-progress-link>
+            <span class="visually-hidden" data-webform-progress-state>{% if is_active or is_completed %}{{ is_active ? 'Current'|t : 'Completed'|t }}{% endif %}</span>
             {{ page.title }}
           </span>
         </span>
diff --git a/web/modules/webform/templates/webform-progress.html.twig b/web/modules/webform/templates/webform-progress.html.twig
index ad0f0fdeb9..fe634fa4c0 100644
--- a/web/modules/webform/templates/webform-progress.html.twig
+++ b/web/modules/webform/templates/webform-progress.html.twig
@@ -26,12 +26,12 @@
   {% if summary or percentage %}
     <div class="webform-progress__status">
       {% if summary %}
-        <span class="webform-progress__summary">{{ summary }}</span>
+        <span class="webform-progress__summary" data-webform-progress-summary>{{ summary }}</span>
         {% if percentage %}
-          <span class="webform-progress__percentage">({{ percentage }})</span>
+          <span class="webform-progress__percentage">(<span data-webform-progress-percentage>{{ percentage }}</span>)</span>
         {% endif %}
       {% else %}
-        <span class="webform-progress__percentage">{{ percentage }}</span>
+        <span class="webform-progress__percentage" data-webform-progress-percentage>{{ percentage }}</span>
       {% endif %}
     </div>
   {% endif %}
diff --git a/web/modules/webform/templates/webform-submission-data.html.twig b/web/modules/webform/templates/webform-submission-data.html.twig
index b94570cd70..6f1b21b3dd 100644
--- a/web/modules/webform/templates/webform-submission-data.html.twig
+++ b/web/modules/webform/templates/webform-submission-data.html.twig
@@ -13,11 +13,11 @@
  */
 #}
 {%
-set classes = [
-'webform-submission-data',
-'webform-submission-data--webform-' ~ webform.id()|clean_class,
-view_mode ? 'webform-submission-data--view-mode-' ~ view_mode|clean_class,
-]
+  set classes = [
+    'webform-submission-data',
+    'webform-submission-data--webform-' ~ webform.id()|clean_class,
+    view_mode ? 'webform-submission-data--view-mode-' ~ view_mode|clean_class,
+  ]
 %}
 <div{{ attributes.addClass(classes) }}>
 {{ elements }}
diff --git a/web/modules/webform/templates/webform-submission-information.html.twig b/web/modules/webform/templates/webform-submission-information.html.twig
index 3560617c8a..7f036913e1 100644
--- a/web/modules/webform/templates/webform-submission-information.html.twig
+++ b/web/modules/webform/templates/webform-submission-information.html.twig
@@ -74,7 +74,6 @@
       </div>
     {% endif %}
   {% endif %}
-
 {% else %}
   <div><b>{{ 'Submission Number'|t }}:</b> {{ serial }}</div>
   <div><b>{{ 'Created'|t }}:</b> {{ created }}</div>
diff --git a/web/modules/webform/templates/webform-submission.html.twig b/web/modules/webform/templates/webform-submission.html.twig
index 1675c0b876..7f35470c5b 100644
--- a/web/modules/webform/templates/webform-submission.html.twig
+++ b/web/modules/webform/templates/webform-submission.html.twig
@@ -14,12 +14,12 @@
  */
 #}
 {%
-set classes = [
-'webform-submission',
-'webform-submission--webform-' ~ webform.id()|clean_class,
-webform_submission.isSticky() ? 'webform-submission--sticky',
-view_mode ? 'webform-submission--view-mode-' ~ view_mode|clean_class,
-]
+  set classes = [
+    'webform-submission',
+    'webform-submission--webform-' ~ webform.id()|clean_class,
+    webform_submission.isSticky() ? 'webform-submission--sticky',
+    view_mode ? 'webform-submission--view-mode-' ~ view_mode|clean_class,
+  ]
 %}
 <div{{ attributes.addClass(classes) }}>
 {{ navigation }}
diff --git a/web/modules/webform/templates/webform-variant-override-summary.html.twig b/web/modules/webform/templates/webform-variant-override-summary.html.twig
index da97b476d2..e4f5740a18 100644
--- a/web/modules/webform/templates/webform-variant-override-summary.html.twig
+++ b/web/modules/webform/templates/webform-variant-override-summary.html.twig
@@ -10,7 +10,6 @@
  * @ingroup themeable
  */
 #}
-
 {% if settings.debug %}<b class="color-error">{{ 'Debugging is enabled'|t }}</b><br />{% endif %}
 {% if settings.settings %}<b>{{ 'Settings:'|t }}</b> {{ 'Overridden'|t }}<br />{% endif %}
 {% if settings.elements %}<b>{{ 'Elements:'|t }}</b> {{ 'Overridden'|t }}<br />{% endif %}
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml
index 21ccee432f..0104106e63 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax.yml
@@ -19,7 +19,7 @@ elements: |
     '#title': textfield
     '#type': textfield
     '#required': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -31,7 +31,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -61,6 +61,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -86,11 +91,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml
index 2eeba8cbfd..c23b153cd0 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_inline.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml
index 6a33ff18c1..14ee81a004 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_message.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_modal.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_modal.yml
index b4b00eab61..e3bbf0bf21 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_modal.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_modal.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml
index d336b2747c..99cd6023d2 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_page.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml
index 619a30003e..351b71a348 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url.yml
@@ -17,7 +17,7 @@ category: 'Test: Ajax'
 elements: |
   description:
     '#markup': 'This webform will redirect to the homepage when submitted.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -29,7 +29,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -59,6 +59,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -84,11 +89,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml
index 4865f70fe5..196fef8b80 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_ajax_confirmation_url_msg.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite.yml
index 276565c8c7..9482bb625b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite.yml
@@ -103,7 +103,7 @@ elements: |
         one: One
         two: Two
         three: Three
-  
+
 css: ''
 javascript: ''
 settings:
@@ -115,7 +115,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -145,6 +145,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -170,11 +175,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom.yml
index 895672b275..4350225b69 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom.yml
@@ -65,7 +65,7 @@ elements: |
         martial_status: Single
         employment_status: Unemployed
         age: 20
-  
+
 css: ''
 javascript: ''
 settings:
@@ -77,7 +77,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -107,6 +107,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -132,11 +137,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom_file.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom_file.yml
index 67a5d535e7..179e6e8f7c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom_file.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_custom_file.yml
@@ -36,7 +36,7 @@ elements: |
       managed_file:
         '#type': managed_file
         '#title': managed_file
-  
+
 css: ''
 javascript: ''
 settings:
@@ -48,7 +48,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -78,6 +78,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -103,11 +108,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -207,6 +218,45 @@ handlers:
     handler_id: debug
     status: true
     conditions: {  }
-    weight: 0
+    weight: -49
     settings: {  }
+  email:
+    id: email
+    label: Email
+    handler_id: email
+    status: true
+    conditions: {  }
+    weight: -50
+    settings:
+      states:
+        - completed
+      to_mail: _default
+      to_options: {  }
+      cc_mail: ''
+      cc_options: {  }
+      bcc_mail: ''
+      bcc_options: {  }
+      from_mail: _default
+      from_options: {  }
+      from_name: _default
+      subject: _default
+      body: _default
+      excluded_elements: {  }
+      ignore_access: false
+      exclude_empty: true
+      exclude_empty_checkbox: false
+      exclude_attachments: false
+      html: true
+      attachments: true
+      twig: false
+      debug: true
+      reply_to: ''
+      return_path: ''
+      sender_mail: ''
+      sender_name: ''
+      theme_name: ''
+      parameters: {  }
 variants: {  }
+uuid: b754b5b4-0b50-4a42-a23c-30f95cd9870e
+_core:
+  default_config_hash: l67ofWFfSw0nP4K6ZBRppS9Dv_uBzGiAeEUKwW7-IwA
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format.yml
index b6137bf194..a24cf9aee7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format.yml
@@ -455,7 +455,7 @@ elements: |
           q2: 1
           q3: 1
         '#format': table
-  
+
 css: ''
 javascript: ''
 settings:
@@ -467,7 +467,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -497,6 +497,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -522,11 +527,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format_multiple.yml
index ec7347a253..8c1d4ad49a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_composite_format_multiple.yml
@@ -711,7 +711,7 @@ elements: |
             phone: '+1 212-333-4444'
             ext: 0
         '#format_items': table
-  
+
 css: ''
 javascript: ''
 settings:
@@ -723,7 +723,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -753,6 +753,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -778,11 +783,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml
index 93e30b3554..fb1919da6f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_inline.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml
index 380dfd7fc9..a55d446a09 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_message.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_modal.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_modal.yml
index 9cca671181..8e4f398103 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_modal.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_modal.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_none.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_none.yml
index f42ac3c790..87e022c380 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_none.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_none.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml
index c992d8f984..34ada3cc5c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml
index 046f32ff43..10910648eb 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_page_custom.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml
index 223e133640..12ec1647bf 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url.yml
@@ -17,7 +17,7 @@ category: 'Test: Confirmation'
 elements: |
   description:
     '#markup': 'This webform will redirect to the homepage when submitted.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -29,7 +29,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -59,6 +59,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -84,11 +89,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml
index d8a9e18d38..da57b041f0 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_confirmation_url_message.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': textfield
     '#title': test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element.yml
index 36480b028f..ac11bf0428 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element.yml
@@ -63,7 +63,7 @@ elements: |
       '#default_value': |
         {textarea line 1}
         {textarea line 2}
-        
+
     textfield:
       '#type': textfield
       '#title': textfield
@@ -237,7 +237,7 @@ elements: |
       '#default_value':
         - 1
         - 2
-  
+
 css: ''
 javascript: ''
 settings:
@@ -249,7 +249,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -279,6 +279,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -304,11 +309,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml
index fb6eadcef4..c3ce82714a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_access.yml
@@ -105,7 +105,7 @@ elements: |
       '#access_view_roles': {  }
       '#access_view_permissions':
         - 'access user profiles'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -117,7 +117,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -147,6 +147,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -172,11 +177,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml
index 7b1e7c913b..e853ee7300 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions.yml
@@ -7,7 +7,7 @@ dependencies:
 open: null
 close: null
 weight: 0
-uid: 1
+uid: 0
 template: false
 archive: false
 id: test_element_actions
@@ -138,7 +138,7 @@ elements: |
     '#draft_hide': true
     '#wizard_prev_hide': true
     '#wizard_next_hide': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -150,7 +150,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -180,6 +180,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -205,11 +210,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml
index 9bb87039fc..28c0128409 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_actions_buttons.yml
@@ -58,7 +58,7 @@ elements: |
       class:
         - preview_next_button_attributes
       style: 'color: orange'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -70,7 +70,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -100,6 +100,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -125,11 +130,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_address.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_address.yml
index ed713393b7..f6354b36f9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_address.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_address.yml
@@ -70,7 +70,7 @@ elements: |
         administrative_area: CA
         country_code: US
         langcode: en
-  
+
 css: ''
 javascript: ''
 settings:
@@ -82,7 +82,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -112,6 +112,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -137,11 +142,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml
index 4697c41032..9f56f64659 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_allowed_tags.yml
@@ -19,7 +19,7 @@ elements: |
     '#type': item
     '#title': 'Below markup contains HTML tags'
     '#markup': 'Hello <ignored></tag><b>…Goodbye</b>'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -31,7 +31,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -61,6 +61,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -86,11 +91,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml
index f93db6a6e9..7ee29fce5e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_attributes.yml
@@ -22,7 +22,7 @@ elements: |
       one
       two
       three
-      
+
     '#class__description': 'This is a custom class description.'
     '#style__description': 'This is a custom style description.'
     '#attributes__description': 'This is a custom attributes description.'
@@ -33,7 +33,7 @@ elements: |
         - four
       style: 'color: red'
       custom: test
-  
+
 css: ''
 javascript: ''
 settings:
@@ -45,7 +45,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -75,6 +75,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -100,11 +105,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml
index bfb392a1e7..505554da23 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_autocomplete.yml
@@ -37,7 +37,7 @@ elements: |
     '#autocomplete_existing': true
     '#autocomplete_limit': 5
     '#autocomplete_match': 1
-  
+
 css: ''
 javascript: ''
 settings:
@@ -49,7 +49,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -79,6 +79,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -104,11 +109,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_captcha.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_captcha.yml
index 15edeea26f..2724d1c802 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_captcha.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_captcha.yml
@@ -40,7 +40,7 @@ elements: |
   captcha_recaptcha:
     '#type': captcha
     '#captcha_type': recaptcha/reCAPTCHA
-  
+
 css: ''
 javascript: ''
 settings:
@@ -52,7 +52,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -82,6 +82,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -107,11 +112,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox.yml
index b0c4158f69..eb96ebcdbe 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox.yml
@@ -31,7 +31,7 @@ elements: |
     '#title': checkbox_return_value_raw
     '#return_value': custom_return_value_raw
     '#format': raw
-  
+
 css: ''
 javascript: ''
 settings:
@@ -43,7 +43,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -73,6 +73,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -98,11 +103,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox_value.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox_value.yml
index c787921c5e..8fa88538ab 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox_value.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkbox_value.yml
@@ -34,7 +34,7 @@ elements: |
         One: One
         Two: Two
         Three: Three
-  
+
 css: ''
 javascript: ''
 settings:
@@ -46,7 +46,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -76,6 +76,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -101,11 +106,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes.yml
index c393baafc7..2d1605d863 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes.yml
@@ -96,6 +96,20 @@ elements: |
       '#title': checkboxes_buttons
       '#options': yes_no
       '#options_display': buttons
+    checkboxes_buttons_horizontal:
+      '#type': checkboxes
+      '#title': checkboxes_buttons_horizontal
+      '#options_display': buttons_horizontal
+      '#options_description_display': description
+      '#options':
+        one: 'One'
+        two: 'Two'
+        three: 'Three -- This is a description'
+    checkboxes_buttons_vertical:
+      '#type': checkboxes
+      '#title': checkboxes_buttons_vertical
+      '#options': yes_no
+      '#options_display': buttons_vertical
     checkboxes_buttons_inline:
       '#type': checkboxes
       '#title': checkboxes_buttons_inline
@@ -194,7 +208,7 @@ elements: |
           '#disabled': true
         three:
           '#disabled': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -206,7 +220,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -236,6 +250,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -261,11 +280,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes_all_none.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes_all_none.yml
new file mode 100644
index 0000000000..0e253ede09
--- /dev/null
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_checkboxes_all_none.yml
@@ -0,0 +1,254 @@
+langcode: en
+status: open
+dependencies:
+  enforced:
+    module:
+      - webform_test
+open: null
+close: null
+weight: 0
+uid: null
+template: false
+archive: false
+id: test_element_checkboxes_all_none
+title: 'Test: Element: Checkboxes all or none'
+description: 'Test the checkboxes all/none of the above.'
+category: 'Test: Element'
+elements: |
+  checkboxes_all:
+    '#type': checkboxes
+    '#title': checkboxes_all
+    '#options_all': true
+    '#options':
+      one: 'One'
+      two: 'Two'
+      three: 'Three'
+  checkboxes_none:
+    '#type': checkboxes
+    '#title': checkboxes_none
+    '#options_none': true
+    '#options':
+      one: 'One'
+      two: 'Two'
+      three: 'Three'
+  checkboxes_both:
+    '#type': checkboxes
+    '#title': checkboxes_both
+    '#options_all': true
+    '#options_none': true
+    '#options':
+      one: 'One'
+      two: 'Two'
+      three: 'Three'
+  checkboxes_randomize:
+    '#type': checkboxes
+    '#title': checkboxes_randomize
+    '#options_randomize': true
+    '#options_all': true
+    '#options_none': true
+    '#options':
+      one: 'One'
+      two: 'Two'
+      three: 'Three'
+  checkboxes_other_none:
+    '#type': webform_checkboxes_other
+    '#title': checkboxes_other_none
+    '#options_none': true
+    '#options':
+      one: 'One'
+      two: 'Two'
+      three: 'Three'
+  webform_entity_checkboxes_all:
+    '#type': webform_entity_checkboxes
+    '#title': webform_entity_checkboxes_all
+    '#options_all': true
+    '#target_type': user
+    '#selection_handler': 'default:user'
+    '#selection_settings':
+      include_anonymous: true
+    '#default_value':
+      - 1
+css: ''
+javascript: ''
+settings:
+  ajax: false
+  ajax_scroll_top: form
+  ajax_progress_type: ''
+  ajax_effect: ''
+  ajax_speed: null
+  page: true
+  page_submit_path: ''
+  page_confirm_path: ''
+  page_theme_name: ''
+  form_title: source_entity_webform
+  form_submit_once: false
+  form_exception_message: ''
+  form_open_message: ''
+  form_close_message: ''
+  form_previous_submissions: true
+  form_confidential: false
+  form_confidential_message: ''
+  form_remote_addr: true
+  form_convert_anonymous: false
+  form_prepopulate: false
+  form_prepopulate_source_entity: false
+  form_prepopulate_source_entity_required: false
+  form_prepopulate_source_entity_type: ''
+  form_reset: false
+  form_disable_autocomplete: false
+  form_novalidate: false
+  form_disable_inline_errors: false
+  form_required: false
+  form_unsaved: false
+  form_disable_back: false
+  form_submit_back: false
+  form_autofocus: false
+  form_details_toggle: false
+  form_access_denied: default
+  form_access_denied_title: ''
+  form_access_denied_message: ''
+  form_access_denied_attributes: {  }
+  form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
+  submission_label: ''
+  submission_log: false
+  submission_views: {  }
+  submission_views_replace: {  }
+  submission_user_columns: {  }
+  submission_user_duplicate: false
+  submission_access_denied: default
+  submission_access_denied_title: ''
+  submission_access_denied_message: ''
+  submission_access_denied_attributes: {  }
+  submission_exception_message: ''
+  submission_locked_message: ''
+  submission_excluded_elements: {  }
+  submission_exclude_empty: false
+  submission_exclude_empty_checkbox: false
+  previous_submission_message: ''
+  previous_submissions_message: ''
+  autofill: false
+  autofill_message: ''
+  autofill_excluded_elements: {  }
+  wizard_progress_bar: true
+  wizard_progress_pages: false
+  wizard_progress_percentage: false
+  wizard_progress_link: false
+  wizard_progress_states: false
+  wizard_auto_forward: true
+  wizard_start_label: ''
+  wizard_preview_link: false
+  wizard_confirmation: true
+  wizard_confirmation_label: ''
+  wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
+  preview: 1
+  preview_label: ''
+  preview_title: ''
+  preview_message: ''
+  preview_attributes: {  }
+  preview_excluded_elements: {  }
+  preview_exclude_empty: true
+  preview_exclude_empty_checkbox: false
+  draft: none
+  draft_multiple: false
+  draft_auto_save: false
+  draft_saved_message: ''
+  draft_loaded_message: ''
+  draft_pending_single_message: ''
+  draft_pending_multiple_message: ''
+  confirmation_type: message
+  confirmation_title: ''
+  confirmation_message: ''
+  confirmation_url: ''
+  confirmation_attributes: {  }
+  confirmation_back: true
+  confirmation_back_label: ''
+  confirmation_back_attributes: {  }
+  confirmation_exclude_query: false
+  confirmation_exclude_token: false
+  confirmation_update: false
+  limit_total: null
+  limit_total_interval: null
+  limit_total_message: ''
+  limit_total_unique: false
+  limit_user: null
+  limit_user_interval: null
+  limit_user_message: ''
+  limit_user_unique: false
+  entity_limit_total: null
+  entity_limit_total_interval: null
+  entity_limit_user: null
+  entity_limit_user_interval: null
+  purge: none
+  purge_days: null
+  results_disabled: false
+  results_disabled_ignore: false
+  results_customize: false
+  token_view: false
+  token_update: false
+access:
+  create:
+    roles:
+      - anonymous
+      - authenticated
+    users: {  }
+    permissions: {  }
+  view_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  purge_any:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  view_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  update_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  delete_own:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  administer:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  test:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+  configuration:
+    roles: {  }
+    users: {  }
+    permissions: {  }
+handlers:
+  debug:
+    id: debug
+    label: Debug
+    handler_id: debug
+    status: true
+    conditions: {  }
+    weight: 1
+    settings: {  }
+variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml
index 890079bed3..fdc5102ec5 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_codemirror.yml
@@ -113,7 +113,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -143,6 +143,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -168,11 +173,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml
index 35a45f5477..3101d6d490 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite.yml
@@ -57,7 +57,7 @@ elements: |
         '#field_suffix': ' yrs. old'
         '#min': 1
         '#max': 125
-  
+
 css: ''
 javascript: ''
 settings:
@@ -69,7 +69,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -99,6 +99,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -124,11 +129,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite_wrapper.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite_wrapper.yml
index 21daebba50..f8aecbddc9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite_wrapper.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_composite_wrapper.yml
@@ -133,7 +133,7 @@ elements: |
       visible:
         ':input[name="states_checkbox"]':
           checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -145,7 +145,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -175,6 +175,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -200,11 +205,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_ajax.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_ajax.yml
index dda816af2f..5032b0d532 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_ajax.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_ajax.yml
@@ -50,7 +50,7 @@ elements: |
       Please enter a value for a and b.
       {% endif %}
       {% endspaceless %}
-  
+
   webform_computed_twig_token:
     '#type': webform_computed_twig
     '#title': webform_computed_twig_token
@@ -65,7 +65,7 @@ elements: |
       Please enter a value for a and b.
       {% endif %}
       {% endspaceless %}
-  
+
   horizontal_rule:
     '#type': webform_horizontal_rule
   composite:
@@ -88,9 +88,9 @@ elements: |
       Please enter a value for composite textfield.
       {% endif %}
       {% endspaceless %}
-  
+
     '#ajax': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -102,7 +102,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -132,6 +132,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -157,11 +162,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_debug.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_debug.yml
index e066ab8dfe..a61bd347bd 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_debug.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_debug.yml
@@ -150,7 +150,7 @@ elements: |
         {# data.datelist_03 #}
         <pre>{{ webform_debug(data|without('computed_twig_data_01', 'computed_twig_data_ajax_01', 'computed_twig_data_02', 'computed_twig_data_ajax_02', 'computed_twig_data_03', 'computed_twig_data_ajax_03') ) }}</pre>
       '#ajax': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -162,7 +162,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -192,6 +192,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -217,11 +222,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml
index cb458ac62e..ed317c6d8c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_token.yml
@@ -29,7 +29,7 @@ elements: |
     '#default_value': |
       <p>This is a <strong>text format</strong> string.</p>
       <p>It contains &quot;double&quot; and 'single' quotes with special characters like &lt;, &gt;, &lt;&gt;, and &gt;&lt;.</p>
-  
+
   xss:
     '#type': textfield
     '#title': xss
@@ -42,7 +42,7 @@ elements: |
       <b class="webform_computed_token_auto">complex string :</b> [webform_submission:values:complex_string]<br />
       <b class="webform_computed_token_auto">text_format:</b> [webform_submission:values:text_format]<br />
       <b class="webform_computed_token_auto">xss:</b> [webform_submission:values:xss]<br />
-  
+
   webform_computed_token_html:
     '#type': webform_computed_token
     '#title': webform_computed_token_html
@@ -52,7 +52,7 @@ elements: |
       <b class="webform_computed_token_html">complex string :</b> [webform_submission:values:complex_string]<br />
       <b class="webform_computed_token_html">text_format:</b> [webform_submission:values:text_format]<br />
       <b class="webform_computed_token_html">xss:</b> [webform_submission:values:xss]<br />
-  
+
   webform_computed_token_text:
     '#type': webform_computed_token
     '#title': webform_computed_token_text
@@ -62,7 +62,7 @@ elements: |
       complex string : [webform_submission:values:complex_string]
       text_format: [webform_submission:values:text_format]
       xss: [webform_submission:values:xss]
-  
+
   webform_computed_token_store:
     '#type': webform_computed_token
     '#title': webform_computed_token_store
@@ -70,7 +70,7 @@ elements: |
     '#display_on': none
     '#store': true
     '#template': 'sid: [webform_submission:sid]'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -82,7 +82,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -112,6 +112,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -137,11 +142,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml
index 4fef3f6bf3..56cbda80fd 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_computed_twig.yml
@@ -33,7 +33,7 @@ elements: |
     '#default_value': |
       <p>This is a <strong>text format</strong> string.</p>
       <p>It contains &quot;double&quot; and 'single' quotes with special characters like &lt;, &gt;, &lt;&gt;, and &gt;&lt;.</p>
-  
+
   xss:
     '#type': textfield
     '#title': xss
@@ -47,7 +47,7 @@ elements: |
       <b class="webform_computed_twig_auto">complex string:</b> {{ webform_token('[webform_submission:values:complex_string]', webform_submission) }}<br />
       <b class="webform_computed_twig_auto">text_format:</b> {{ webform_token('[webform_submission:values:text_format]', webform_submission) }}<br />
       <b class="webform_computed_twig_auto">xss:</b> {{ webform_token('[webform_submission:values:xss]', webform_submission) }}<br />
-  
+
   webform_computed_twig_html:
     '#type': webform_computed_twig
     '#title': webform_computed_twig_html
@@ -58,7 +58,7 @@ elements: |
       <b class="webform_computed_twig_html">complex string:</b> {{ webform_token('[webform_submission:values:complex_string]', webform_submission) }}<br />
       <b class="webform_computed_twig_html">text_format:</b> {{ webform_token('[webform_submission:values:text_format]', webform_submission) }}<br />
       <b class="webform_computed_twig_html">xss:</b> {{ webform_token('[webform_submission:values:xss]', webform_submission) }}<br />
-  
+
   webform_computed_twig_text:
     '#type': webform_computed_twig
     '#title': webform_computed_twig_text
@@ -69,7 +69,7 @@ elements: |
       complex string: {{ webform_token('[webform_submission:values:complex_string]', webform_submission) }}
       text_format: {{ webform_token('[webform_submission:values:text_format]', webform_submission) }}
       xss: {{ webform_token('[webform_submission:values:xss]', webform_submission) }}
-  
+
   webform_computed_twig_data:
     '#type': webform_computed_twig
     '#title': webform_computed_twig_data
@@ -79,7 +79,7 @@ elements: |
       <b class="webform_computed_twig_data">complex string:</b> {{ data.complex_string }}<br />
       <b class="webform_computed_twig_data">text_format:</b> {{ data.text_format.value }}<br />
       <b class="webform_computed_twig_data">xss:</b> {{ data.xss }}<br />
-  
+
   webform_computed_twig_store:
     '#type': webform_computed_twig
     '#title': webform_computed_twig_store
@@ -97,7 +97,7 @@ elements: |
     '#title': webform_computed_twig_spaceless
     '#whitespace': spaceless
     '#template': ' <em>This is spaceless</em>  <br/> '
-  
+
 css: ''
 javascript: ''
 settings:
@@ -109,7 +109,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -139,6 +139,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -164,11 +169,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_container.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_container.yml
index aab258ab65..1e81e42bae 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_container.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_container.yml
@@ -74,7 +74,7 @@ elements: |
     fieldset_title_display_invisible_textfield:
       '#type': textfield
       '#title': fieldset_title_display_invisible_textfield
-  
+
 css: ''
 javascript: ''
 settings:
@@ -86,7 +86,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -116,6 +116,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -141,11 +146,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_counter.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_counter.yml
index 3cf61b0577..6d6594fb87 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_counter.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_counter.yml
@@ -88,7 +88,7 @@ elements: |
       '#counter_type': word
       '#counter_maximum': 10
       '#counter_maximum_message': '%d character(s) remaining. This is custom text'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -100,7 +100,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -130,6 +130,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -155,11 +160,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml
index a8c617a0e4..f173128d2f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_date.yml
@@ -82,7 +82,7 @@ elements: |
     '#title': date_datepicker_placeholder
     '#datepicker': true
     '#placeholder': '{date}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -94,7 +94,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -124,6 +124,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -149,11 +154,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml
index 90f7215fa0..e7cf52eb18 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datelist.yml
@@ -95,7 +95,7 @@ elements: |
         '#title': datelist
     '#default_value':
       - datelist: '2009-08-18T01:00:00-05:00'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -107,7 +107,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -137,6 +137,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -162,11 +167,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml
index 6cb03e95df..e468ba8fdc 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_datetime.yml
@@ -123,7 +123,7 @@ elements: |
     '#description': |
       @see <a href="https://www.drupal.org/node/2917107">Issue #2917107: Date and Time validation problem</a><br/>
       @see <a href="https://www.drupal.org/node/2723159">Issue #2723159: Datetime form element cannot validate when using a format without seconds</a><br/>
-  
+
     '#date_date_element': datepicker
     '#date_time_element': text
     '#date_time_format': 'H:i'
@@ -153,7 +153,7 @@ elements: |
         '#autocomplete': 'off'
     '#default_value':
       - datetime: '2009-08-18T01:00:00-05:00'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -165,7 +165,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -195,6 +195,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -220,11 +225,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_description_tooltip.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_description_tooltip.yml
index 099f51fdbf..fb141eff78 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_description_tooltip.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_description_tooltip.yml
@@ -466,7 +466,7 @@ elements: |
       '#title': 'Machine name'
       '#description': 'This is a description for the ''machine_name'' element.'
       '#description_display': tooltip
-  
+
 css: ''
 javascript: ''
 settings:
@@ -478,7 +478,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -508,6 +508,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -533,11 +538,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_details.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_details.yml
index def00d1726..6e299456b4 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_details.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_details.yml
@@ -46,7 +46,7 @@ elements: |
     '#open': true
     details_help_markup:
       '#markup': '<p>This is some markup</p>'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -58,7 +58,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -88,6 +88,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -113,11 +118,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml
index 26610a6738..62fb11d0c8 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_disabled.yml
@@ -363,7 +363,7 @@ elements: |
     '#type': webform_video_file
     '#title': 'Video file'
     '#disabled': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -375,7 +375,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -405,6 +405,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -430,11 +435,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_confirm.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_confirm.yml
index 80bb1cd77a..4efec14d1f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_confirm.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_confirm.yml
@@ -42,7 +42,7 @@ elements: |
     '#type': webform_email_confirm
     '#title': email_confirm_flexbox
     '#flexbox': 1
-  
+
 css: ''
 javascript: ''
 settings:
@@ -54,7 +54,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -84,6 +84,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -109,11 +114,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_multiple.yml
index ccc9357b4b..a7ce66cc07 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_email_multiple.yml
@@ -27,7 +27,7 @@ elements: |
     '#type': webform_email_multiple
     '#title': email_multiple_three
     '#cardinality': 3
-  
+
 css: ''
 javascript: ''
 settings:
@@ -39,7 +39,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -69,6 +69,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -94,11 +99,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_autocomplete.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_autocomplete.yml
index 2975d4baae..f9d5059e25 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_autocomplete.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_autocomplete.yml
@@ -65,7 +65,7 @@ elements: |
         display_name: entity_reference
         arguments: ''
     '#default_value': 1
-  
+
 css: ''
 javascript: ''
 settings:
@@ -77,7 +77,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -107,6 +107,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -132,11 +137,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml
index fb960d65ea..2a68afa6fe 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_entity_reference.yml
@@ -62,7 +62,7 @@ elements: |
         include_anonymous: true
       '#default_value':
         - 1
-  
+
 css: ''
 javascript: ''
 settings:
@@ -74,7 +74,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -104,6 +104,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -129,11 +134,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_columns.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_columns.yml
index aa8f70b2e3..9417200623 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_columns.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_columns.yml
@@ -29,7 +29,7 @@ elements: |
     '#title': webform_excluded_columns
     '#default_value':
       webform_excluded_columns: webform_excluded_columns
-  
+
 css: ''
 javascript: ''
 settings:
@@ -41,7 +41,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -71,6 +71,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -96,11 +101,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_elements.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_elements.yml
index a8ab2144e5..1db4a10838 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_elements.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_excluded_elements.yml
@@ -37,7 +37,7 @@ elements: |
     '#default_value':
       webform_excluded_elements: webform_excluded_elements
       webform_excluded_elements_markup: webform_excluded_elements_markup
-  
+
 css: ''
 javascript: ''
 settings:
@@ -49,7 +49,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -79,6 +79,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -104,11 +109,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_fieldset.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_fieldset.yml
index b59dc32bd9..214d4d1579 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_fieldset.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_fieldset.yml
@@ -60,7 +60,7 @@ elements: |
     '#field_suffix': suffix
     fieldset_markup:
       '#markup': '<p>This is some markup</p>'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -72,7 +72,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -102,6 +102,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -127,11 +132,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml
index f15c2f203c..c0d9c375ec 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox.yml
@@ -936,7 +936,7 @@ elements: |
     toggle_rating:
       '#type': rating
       '#title': rating
-  
+
 css: ''
 javascript: ''
 settings:
@@ -948,7 +948,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -978,6 +978,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -1003,11 +1008,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml
index dbd938e3de..63eb5a34d4 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_flexbox_flex.yml
@@ -805,7 +805,7 @@ elements: |
         style: 'padding: 30px; background: #ccc; text-align: center'
       flex:
         '#markup': 1
-  
+
 css: ''
 javascript: ''
 settings:
@@ -817,7 +817,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -847,6 +847,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -872,11 +877,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml
index 04d60d86b2..7e75b0bfad 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format.yml
@@ -1304,7 +1304,7 @@ elements: |
         '#title': 'Machine name (Raw value)'
         '#default_value': loremipsum
         '#format': raw
-  
+
 css: ''
 javascript: ''
 settings:
@@ -1316,7 +1316,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -1346,6 +1346,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -1371,11 +1376,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_custom.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_custom.yml
index d097e9b8cf..5153083db1 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_custom.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_custom.yml
@@ -21,10 +21,10 @@ elements: |
     '#format': custom
     '#format_html': |
       <em>{{ value }}</em>
-      
+
     '#format_text': |
       /{{ value }}/
-      
+
     '#default_value': '{textfield_custom}'
   textfield_custom_token:
     '#type': textfield
@@ -32,10 +32,10 @@ elements: |
     '#format': custom
     '#format_html': |
       <em>[webform_submission:values:textfield_custom_token:raw]</em>
-      
+
     '#format_text': |
       /[webform_submission:values:textfield_custom_token:raw]/
-      
+
     '#default_value': '{textfield_custom_token}'
   textfield_custom_token_exception:
     '#type': textfield
@@ -43,10 +43,10 @@ elements: |
     '#format': custom
     '#format_html': |
       <em>EXCEPTION[webform_submission:values:textfield_custom_token_exception]</em>
-      
+
     '#format_text': |
       /EXCEPTION[webform_submission:values:textfield_custom_token_exception]/
-      
+
     '#default_value': '{textfield_custom_token_exception}'
   textfield_custom_value_multiple:
     '#type': textfield
@@ -55,10 +55,10 @@ elements: |
     '#format': custom
     '#format_html': |
       <em>{{ value }}</em>
-      
+
     '#format_text': |
       /{{ value }}/
-      
+
     '#format_items': custom
     '#format_items_html': |
       <table>
@@ -66,12 +66,12 @@ elements: |
         <tr {% if loop.index is divisible by(2) %}style="background-color: #ffc"{% endif %}><td>{{ item }}</td></tr>
       {% endfor %}
       </table>
-      
+
     '#format_items_text': |
       {% for item in items %}
       ⦿ {{ item }}
       {% endfor %}
-      
+
     '#default_value':
       - One
       - Two
@@ -92,7 +92,7 @@ elements: |
       item['original:image']: <div style="width: 100px">{{ item['original:image'] }}</div>
       item['original:link']: <div style="width: 100px">{{ item['original:link'] }}</div>
       item['original:modal']: <div style="width: 100px">{{ item['original:modal'] }}</div>
-      
+
     '#format_text': |
       value: {{ value }}
       item['value']: {{ item['value'] }}
@@ -100,7 +100,7 @@ elements: |
       item['link']: {{ item['link'] }}
       item['id']: {{ item['id'] }}
       item['url']: {{ item['url'] }}
-      
+
   address_custom:
     '#type': webform_address
     '#title': address_custom
@@ -112,7 +112,7 @@ elements: |
       element.state_province: {{ element.state_province }}<br/>
       element.postal_code: {{ element.postal_code }}<br/>
       element.country: {{ element.country }}<br/>
-      
+
     '#format_text': |
       element.address: {{ element.address }}
       element.address_2: {{ element.address_2 }}
@@ -120,7 +120,7 @@ elements: |
       element.state_province: {{ element.state_province }}
       element.postal_code: {{ element.postal_code }}
       element.country: {{ element.country }}
-      
+
     '#state_province__type': webform_select_other
     '#country__type': webform_select_other
     '#default_value':
@@ -155,7 +155,7 @@ elements: |
       element.state_province: {{ element.state_province }}<br/>
       element.postal_code: {{ element.postal_code }}<br/>
       element.country: {{ element.country }}<br/>
-      
+
     '#format_text': |
       element.address: {{ element.address }}
       element.address_2: {{ element.address_2 }}
@@ -163,7 +163,7 @@ elements: |
       element.state_province: {{ element.state_province }}
       element.postal_code: {{ element.postal_code }}
       element.country: {{ element.country }}
-      
+
     '#format_items': custom
     '#format_items_html': |
       {% for item in items %}
@@ -171,14 +171,14 @@ elements: |
       {{ item }}
       <div>*****</div>
       {% endfor %}
-      
+
     '#format_items_text': |
       {% for item in items %}
       *****
       {{ item }}
       *****
       {% endfor %}
-      
+
     '#state_province__type': webform_select_other
     '#country__type': webform_select_other
   fieldset_custom:
@@ -187,10 +187,10 @@ elements: |
     '#format': custom
     '#format_html': |
       {{ item.details }}
-      
+
     '#format_text': |
       {{ item.details }}
-      
+
     fieldset_custom_textfield:
       '#type': textfield
       '#title': fieldset_custom_textfield
@@ -203,17 +203,17 @@ elements: |
       <h3>fieldset_custom_children</h3>
       <hr />
       {{ children }}
-      
+
     '#format_text': |
       fieldset_custom_children
       ------------------------
       {{ children }}
-      
+
     fieldset_custom_children_textfield:
       '#type': textfield
       '#title': fieldset_custom_children_textfield
       '#default_value': '{fieldset_custom_children_textfield}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -225,7 +225,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -255,6 +255,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -280,11 +285,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml
index 085ab5c755..86752b16a0 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_multiple.yml
@@ -1578,7 +1578,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -1608,6 +1608,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -1633,11 +1638,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml
index 6ff02bb021..f39380aa88 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_format_token.yml
@@ -26,7 +26,7 @@ elements: |
       - 1
       - 2
       - 3
-  
+
 css: ''
 javascript: ''
 settings:
@@ -38,7 +38,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -68,6 +68,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -93,11 +98,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -219,7 +230,7 @@ handlers:
         <h3>ul:</h3>[webform_submission:values:checkboxes:value:ul]<hr />
         <h3>ol:</h3>[webform_submission:values:checkboxes:value:ol]<hr />
         <h3>raw:</h3>[webform_submission:values:checkboxes:raw]<hr />
-        
+
       excluded_elements: {  }
       ignore_access: false
       exclude_empty: true
@@ -258,25 +269,25 @@ handlers:
       body: |
         default:
         [webform_submission:values:checkboxes]
-        
+
         comma:
         [webform_submission:values:checkboxes:value:comma]
-        
+
         semicolon:
         [webform_submission:values:checkboxes:value:semicolon]
-        
+
         and:
         [webform_submission:values:checkboxes:value:and]
-        
+
         ul:
         [webform_submission:values:checkboxes:value:ul]
-        
+
         ol:
         [webform_submission:values:checkboxes:value:ol]
-        
+
         raw:
         [webform_submission:values:checkboxes:raw]
-        
+
       excluded_elements: {  }
       ignore_access: false
       exclude_empty: true
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml
index eae85003dd..46a83e514d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help.yml
@@ -132,7 +132,7 @@ elements: |
     '#help_display': element_after
     'help_after_details':
       '#markup': '{This is markup}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -144,7 +144,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -174,6 +174,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -199,11 +204,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help_display.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help_display.yml
index 08df870e92..c9dda5fcef 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help_display.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_help_display.yml
@@ -1909,7 +1909,7 @@ elements: |
       '#help_display': element_after
     machine_name_hr:
       '#type': webform_horizontal_rule
-  
+
 css: ''
 javascript: ''
 settings:
@@ -1921,7 +1921,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -1951,6 +1951,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -1976,11 +1981,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_horizontal_rule.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_horizontal_rule.yml
index 4ff05e0110..0c2cbfe73e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_horizontal_rule.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_horizontal_rule.yml
@@ -101,7 +101,7 @@ elements: |
     '#attributes':
       class:
         - webform-horizontal-rule--glyph
-  
+
 css: ''
 javascript: ''
 settings:
@@ -113,7 +113,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -143,6 +143,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -168,11 +173,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml
index 40ab375b6c..472ca8def4 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_editor.yml
@@ -41,7 +41,7 @@ elements: |
     '#required': true
     '#default_value': 'Hello <b>World!!!</b>'
     '#format': false
-  
+
 css: ''
 javascript: ''
 settings:
@@ -53,7 +53,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -83,6 +83,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -108,11 +113,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml
index a360b3a3ee..382dc01386 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_escape.yml
@@ -524,7 +524,7 @@ elements: |
     table:
       '#type': table
       '#title': 'Table | <script>alert(''This markup is not escaped properly!!!'') </script>'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -536,7 +536,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -566,6 +566,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -591,11 +596,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml
index d85e37c556..dddb200dfa 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_html_markup.yml
@@ -524,7 +524,7 @@ elements: |
     table:
       '#type': table
       '#title': '<u>Table</u>'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -536,7 +536,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -566,6 +566,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -591,11 +596,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml
index 68aef76d72..757df8111b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_ignored_properties.yml
@@ -81,7 +81,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -111,6 +111,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -136,11 +141,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file.yml
index 8c2e0a70e1..2960151367 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file.yml
@@ -22,7 +22,7 @@ elements: |
     '#type': webform_image_file
     '#title': 'webform_image_file_advanced (max: 20x20)'
     '#max_resolution': 20x20
-  
+
 css: ''
 javascript: ''
 settings:
@@ -34,7 +34,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -64,6 +64,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -89,11 +94,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file_attach.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file_attach.yml
index cc9380b942..f812b59fd7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file_attach.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_file_attach.yml
@@ -20,7 +20,7 @@ elements: |
     '#title': webform_image_file_attachment
     '#file_extensions': gif
     '#attachment_image_style': thumbnail
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_resolution.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_resolution.yml
index f7d596b094..e685e9e42e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_resolution.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_image_resolution.yml
@@ -25,7 +25,7 @@ elements: |
     '#height_title': '{height_title}'
     '#width_title': '{width_title}'
     '#default_value': 300x400
-  
+
 css: ''
 javascript: ''
 settings:
@@ -37,7 +37,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -67,6 +67,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -92,11 +97,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_input_mask.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_input_mask.yml
index 6be99b84d0..c682f30017 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_input_mask.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_input_mask.yml
@@ -81,7 +81,7 @@ elements: |
     '#type': textfield
     '#title': module
     '#input_mask': '999'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -93,7 +93,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -123,6 +123,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -148,11 +153,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml
index a2ec8d7352..ca7a7eb990 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_invalid.yml
@@ -26,7 +26,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -56,6 +56,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -81,11 +86,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml
index 4a45615dd1..2aaac015b3 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_likert.yml
@@ -78,7 +78,7 @@ elements: |
       - 'Option 1'
       - 'Option 2'
       - 'Option 3'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -90,7 +90,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -120,6 +120,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -145,11 +150,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_loc_places.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_loc_places.yml
index 4bd2fe9516..d4f49943f2 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_loc_places.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_loc_places.yml
@@ -69,7 +69,7 @@ elements: |
     '#geolocation': true
     '#hidden': true
     '#geocomplete': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -81,7 +81,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -111,6 +111,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -136,11 +141,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml
index fb4e07a86e..ec8bf83384 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file.yml
@@ -64,7 +64,11 @@ elements: |
     '#file_extensions': txt
     '#file_placeholder': 'This is the multiple file upload placeholder'
     '#multiple': true
-  
+  managed_file_extensions:
+    '#type': managed_file
+    '#title': managed_file_extensions
+    '#file_extensions': 'txt, text'
+
 css: ''
 javascript: ''
 settings:
@@ -76,7 +80,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -106,6 +110,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -131,11 +140,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_dis.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_dis.yml
index 6cbf437593..c45457f0a3 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_dis.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_dis.yml
@@ -19,7 +19,7 @@ elements: |
     '#type': managed_file
     '#title': managed_file
     '#file_extensions': txt
-  
+
 css: ''
 javascript: ''
 settings:
@@ -31,7 +31,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -61,6 +61,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -86,11 +91,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_help.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_help.yml
index 0e074e390b..54ed35cb5b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_help.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_help.yml
@@ -64,7 +64,7 @@ elements: |
       '#type': managed_file
       '#title': managed_file_help_none
       '#file_help': none
-  
+
 css: ''
 javascript: ''
 settings:
@@ -76,7 +76,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -106,6 +106,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -131,11 +136,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_limit.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_limit.yml
index 153a1914f6..1891d9629f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_limit.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_limit.yml
@@ -34,6 +34,7 @@ elements: |
       managed_file:
         '#type': managed_file
         '#title': managed_file
+
 css: ''
 javascript: ''
 settings:
@@ -45,7 +46,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -75,6 +76,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: '1 MB'
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -100,11 +106,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_name.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_name.yml
index fa8c71a29d..59e222fef5 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_name.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_name.yml
@@ -31,7 +31,7 @@ elements: |
     '#type': managed_file
     '#title': 'File truncate (255)'
     '#file_name': 'file_truncate_123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -43,7 +43,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -73,6 +73,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -98,11 +103,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_prev.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_prev.yml
index 406dece42e..0c1b9b0a16 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_prev.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_managed_file_prev.yml
@@ -59,7 +59,7 @@ elements: |
     '#file_preview': url
     '#file_extensions': txt
     '#multiple': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -71,7 +71,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -101,6 +101,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -126,11 +131,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml
index bbd523396b..d9cd259edf 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_mapping.yml
@@ -130,7 +130,7 @@ elements: |
         two: Two
         three: Three
       '#destination__type': webform_email_multiple
-  
+
 css: ''
 javascript: ''
 settings:
@@ -142,7 +142,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -172,6 +172,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -197,11 +202,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml
index 18f48ccaa1..7430a11a58 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_markup.yml
@@ -33,7 +33,7 @@ elements: |
     '#type': webform_markup
     '#markup': '<p>Alter this markup.</p>'
     '#display_on': both
-  
+
 css: ''
 javascript: ''
 settings:
@@ -45,7 +45,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -75,6 +75,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -100,11 +105,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml
index e06e765640..e6f87de55d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_media_file.yml
@@ -71,7 +71,7 @@ elements: |
       '#type': webform_video_file
       '#title': 'video_file (mp4)'
       '#file_extensions': mp4
-  
+
 css: ''
 javascript: ''
 settings:
@@ -83,7 +83,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -113,6 +113,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -138,11 +143,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml
index c72efbda30..3cb142b42e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_message.yml
@@ -91,7 +91,7 @@ elements: |
       '#message_close': true
       '#message_id': webform_test_message_custom
       '#message_storage': custom
-  
+
 css: ''
 javascript: ''
 settings:
@@ -103,7 +103,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -133,6 +133,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -158,11 +163,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_more.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_more.yml
index f02c4d85bc..f5c8e1c772 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_more.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_more.yml
@@ -64,7 +64,7 @@ elements: |
     '#more': '{This is an example of more}'
     '#description': '{This is a description}'
     '#description_display': tooltip
-  
+
 css: ''
 javascript: ''
 settings:
@@ -76,7 +76,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -106,6 +106,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -131,11 +136,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml
index a04aa0848e..534c6bcd36 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple.yml
@@ -278,7 +278,7 @@ elements: |
         '#attributes':
           class:
             - custom-element
-  
+
 css: ''
 javascript: ''
 settings:
@@ -290,7 +290,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -320,6 +320,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -345,11 +350,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml
index 09576c81d3..2a35350d5b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_date.yml
@@ -39,7 +39,7 @@ elements: |
       '#type': datelist
       '#title': datelist_basic
       '#multiple': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -51,7 +51,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -81,6 +81,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -106,11 +111,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml
index 20cd086492..cfaa38a3bc 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_property.yml
@@ -50,7 +50,7 @@ elements: |
     '#title': webform_element_multiple_custom_access
     '#default_value': 5
     '#access': false
-  
+
 css: ''
 javascript: ''
 settings:
@@ -62,7 +62,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -92,6 +92,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -117,11 +122,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml
index a81415c817..1f1f080513 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_multiple_text.yml
@@ -82,7 +82,7 @@ elements: |
       '#type': number
       '#title': number_basic
       '#multiple': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -94,7 +94,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -124,6 +124,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -149,11 +154,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml
index 5d1f3b79f9..5e4b62750c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_options.yml
@@ -75,7 +75,7 @@ elements: |
       '#title': webform_element_options_custom_type_multiple
       '#custom__type': webform_multiple
       '#default_value': { }
-  
+
 css: ''
 javascript: ''
 settings:
@@ -87,7 +87,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -117,6 +117,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -142,11 +147,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml
index 7d8c129442..33177610ce 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_other.yml
@@ -48,6 +48,7 @@ elements: |
       '#other__counter_minimum': '4'
       '#other__counter_maximum': '10'
       '#required': true
+      '#required_error': 'This is a custom required error message.'
     select_other_multiple:
       '#type': webform_select_other
       '#title': 'Select other multiple'
@@ -147,7 +148,7 @@ elements: |
         Two: Two
         Three: Three
       '#wrapper_type': container
-  
+
 css: ''
 javascript: ''
 settings:
@@ -159,7 +160,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -189,6 +190,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -214,11 +220,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_prepopulate.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_prepopulate.yml
index 037a6519b5..6c38584e7c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_prepopulate.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_prepopulate.yml
@@ -47,6 +47,7 @@ elements: |
       '#type': managed_file
       '#title': managed_file_prepopulate_02
       '#prepopulate': true
+
 css: ''
 javascript: ''
 settings:
@@ -58,7 +59,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -88,6 +89,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -113,11 +119,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml
index b3f644e90e..33e44db777 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_private.yml
@@ -23,7 +23,7 @@ elements: |
       '#type': textfield
       '#title': private
       '#private': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -35,7 +35,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -65,6 +65,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -96,11 +101,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml
index 55be033777..b990884542 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_radios.yml
@@ -111,6 +111,20 @@ elements: |
       '#title': radios_buttons
       '#options': yes_no
       '#options_display': buttons
+    radios_buttons_horizontal:
+      '#type': radios
+      '#title': radios_buttons_horizontal
+      '#options_display': buttons_horizontal
+      '#options_description_display': description
+      '#options':
+        one: 'One'
+        two: 'Two'
+        three: 'Three -- This is a description'
+    radios_buttons_vertical:
+      '#type': radios
+      '#title': radios_buttons_vertical
+      '#options': yes_no
+      '#options_display': buttons_vertical
     radios_buttons_inline:
       '#type': radios
       '#title': radios_buttons_inline
@@ -209,7 +223,7 @@ elements: |
           '#disabled': true
         three:
           '#disabled': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -221,7 +235,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -251,6 +265,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -276,11 +295,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_range.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_range.yml
index 1ade023b06..189ba100fc 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_range.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_range.yml
@@ -70,7 +70,7 @@ elements: |
     '#output': right
     '#output__field_prefix': $
     '#output__field_suffix': '.00'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -82,7 +82,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -112,6 +112,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -137,11 +142,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml
index d08724ff0b..6225993d0d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_rating.yml
@@ -33,7 +33,7 @@ elements: |
       '#type': webform_rating
       '#title': rating_required
       '#required': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -45,7 +45,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -75,6 +75,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -100,11 +105,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_readonly.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_readonly.yml
index ab791a4bdf..b4c6ba5bf7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_readonly.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_readonly.yml
@@ -23,7 +23,7 @@ elements: |
     '#type': textarea
     '#title': textarea
     '#readonly': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -35,7 +35,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -65,6 +65,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -90,11 +95,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_same.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_same.yml
index 06657a66d4..f897bfdc77 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_same.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_same.yml
@@ -88,7 +88,7 @@ elements: |
       '#title': textfield_multiple_destination
       '#multiple': true
       '#required': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -100,7 +100,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -130,6 +130,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -155,11 +160,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_scale.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_scale.yml
index 85af024b5a..de70f856e8 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_scale.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_scale.yml
@@ -55,6 +55,7 @@ elements: |
     '#scale_type': flexbox
     '#min_text': '1 = disagree'
     '#max_text': 'agree = 5'
+
 css: ''
 javascript: ''
 settings:
@@ -66,7 +67,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -96,6 +97,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -121,11 +127,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_section.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_section.yml
index e9f5c2f7c6..101a1ab793 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_section.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_section.yml
@@ -34,7 +34,7 @@ elements: |
     '#title_tag': h5
     '#title_attributes':
       style: 'color: red'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -46,7 +46,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -76,6 +76,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -101,11 +106,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_select.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_select.yml
index 738df31bcf..e518543c86 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_select.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_select.yml
@@ -69,7 +69,7 @@ elements: |
         five: Five
       '#attributes':
         'data-webform-select-options-disabled': 'one,two,four,five'
-  
+
   select_select2_examples:
     '#type': details
     '#title': 'Select select2'
@@ -372,7 +372,7 @@ elements: |
         three: Three
         four: Four
         five: Five
-  
+
 css: ''
 javascript: ''
 settings:
@@ -384,7 +384,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -414,6 +414,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -439,11 +444,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml
index e5d5e33be4..0f25116026 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_signature.yml
@@ -41,7 +41,7 @@ elements: |
     '#type': webform_signature
     '#title': signature_readonly
     '#readonly': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -53,7 +53,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -83,6 +83,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -108,11 +113,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml
index f9395f2922..b81266ae62 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_states.yml
@@ -123,7 +123,7 @@ elements: |
         custom_selector:
           value:
             pattern: '[a-z0-9]+'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -135,7 +135,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -165,6 +165,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -190,11 +195,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views.yml
index 5da2206a91..132be2365f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views.yml
@@ -46,7 +46,7 @@ elements: |
             - entity.webform.results_submissions
           node_routes:
             - entity.node.webform.results_submissions
-  
+
 css: ''
 javascript: ''
 settings:
@@ -58,7 +58,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -88,6 +88,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -113,11 +118,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views_r.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views_r.yml
index e34bd29a49..c763774bcb 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views_r.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submission_views_r.yml
@@ -40,7 +40,7 @@ elements: |
           - entity.webform.results_submissions
         node_routes:
           - entity.node.webform.results_submissions
-  
+
 css: ''
 javascript: ''
 settings:
@@ -52,7 +52,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -82,6 +82,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -107,11 +112,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submitted_value.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submitted_value.yml
index b53622701a..15f306b9ce 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submitted_value.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_submitted_value.yml
@@ -54,7 +54,7 @@ elements: |
       - one
       - two
       - three
-  
+
 css: ''
 javascript: ''
 settings:
@@ -66,7 +66,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -96,6 +96,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -121,11 +126,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml
index 76e9c2e9f8..d5ddbbcc23 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table.yml
@@ -204,7 +204,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -234,6 +234,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -259,11 +264,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table_select_sort.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table_select_sort.yml
index b887370332..85a7b3b1f5 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table_select_sort.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_table_select_sort.yml
@@ -156,7 +156,7 @@ elements: |
       '#default_value':
         five: five
         three: three
-  
+
 css: ''
 javascript: ''
 settings:
@@ -168,7 +168,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -198,6 +198,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -223,11 +228,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml
index 47624c63cf..8c54c9d5ae 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_telephone.yml
@@ -44,7 +44,7 @@ elements: |
     '#international': true
     '#international_preferred_countries':
       - ZW
-  
+
 css: ''
 javascript: ''
 settings:
@@ -56,7 +56,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -86,6 +86,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -111,11 +116,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml
index 965e21c2e9..11457fc922 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_term_reference.yml
@@ -96,7 +96,7 @@ elements: |
         '#breadcrumb_delimiter': ' » '
         '#format': breadcrumb
         '#format_items': ul
-  
+
 css: ''
 javascript: ''
 settings:
@@ -108,7 +108,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -138,6 +138,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -163,11 +168,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_terms_of_service.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_terms_of_service.yml
index b3d64ca506..83158c7b08 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_terms_of_service.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_terms_of_service.yml
@@ -33,7 +33,7 @@ elements: |
     '#terms_type': slideout
     '#terms_title': terms_of_service_slideout
     '#terms_content': 'These are the terms of service.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -45,7 +45,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -75,6 +75,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -100,11 +105,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml
index 0e0fc680d8..8fd3301f0e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_text_format.yml
@@ -30,7 +30,7 @@ elements: |
     '#title': text_format_description_more
     '#description': 'This is a description'
     '#more': 'This is more'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -42,7 +42,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -72,6 +72,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -97,11 +102,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml
index b31b60c28a..5cbc8639de 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_time.yml
@@ -67,7 +67,7 @@ elements: |
     '#title': time_timepicker_placeholder
     '#timepicker': true
     '#placeholder': '{time}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -79,7 +79,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -109,6 +109,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -134,11 +139,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_title_display.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_title_display.yml
index 758550fb1d..fd4dac49c1 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_title_display.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_title_display.yml
@@ -1513,7 +1513,7 @@ elements: |
       '#title_display': none
     machine_name_hr:
       '#type': webform_horizontal_rule
-  
+
 css: ''
 javascript: ''
 settings:
@@ -1525,7 +1525,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -1555,6 +1555,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -1580,11 +1585,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml
index 9aad9bce61..147d374729 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_users_roles.yml
@@ -32,7 +32,7 @@ elements: |
     '#include_anonymous': false
     '#default_value':
       authenticated: authenticated
-  
+
 css: ''
 javascript: ''
 settings:
@@ -44,7 +44,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -74,6 +74,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -99,11 +104,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml
index 94a78c800f..e5600a2367 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_minlength.yml
@@ -26,7 +26,7 @@ elements: |
     '#minlength': 5
     '#required': true
     '#default_value': value
-  
+
 css: ''
 javascript: ''
 settings:
@@ -38,7 +38,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -68,6 +68,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -93,11 +98,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml
index 528ac6b031..673149498d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_multiple.yml
@@ -78,7 +78,7 @@ elements: |
       '#title': webform_element_multiple_managed_file_two
       '#select2': true
       '#multiple': 2
-  
+
 css: ''
 javascript: ''
 settings:
@@ -90,7 +90,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -120,6 +120,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -145,11 +150,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_pattern.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_pattern.yml
index 3c2f967a58..317e4185cf 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_pattern.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_pattern.yml
@@ -37,7 +37,7 @@ elements: |
     '#title': pattern_unicode
     '#pattern': \u2E8F
     '#description': 'Enter unicode CJK characters ''⺏'''
-  
+
 css: ''
 javascript: ''
 settings:
@@ -49,7 +49,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -79,6 +79,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -104,11 +109,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml
index 3a1e4ebef3..e453f37c8a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_required.yml
@@ -34,7 +34,7 @@ elements: |
       three: Three
     '#required': true
     '#required_error': 'This is a custom required message'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -46,7 +46,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -76,6 +76,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -101,11 +106,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml
index 819c7f001e..a316747cdd 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_validate_unique.yml
@@ -55,7 +55,7 @@ elements: |
     '#options':
       1: one
       2: two
-  
+
 css: ''
 javascript: ''
 settings:
@@ -67,7 +67,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -97,6 +97,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -122,11 +127,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_view.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_view.yml
index f616111063..7fe1bd1405 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_view.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_element_view.yml
@@ -24,7 +24,7 @@ elements: |
     '#display_id': default
     '#arguments':
       - '[webform:id]'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -36,7 +36,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -66,6 +66,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -91,11 +96,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements.yml
index a6fb8d7037..22399c6633 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements.yml
@@ -510,7 +510,7 @@ elements: |
     table:
       '#type': table
       '#title': Table
-  
+
 css: ''
 javascript: ''
 settings:
@@ -522,7 +522,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -552,6 +552,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -577,11 +582,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements_composite.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements_composite.yml
index 62267a4c7b..bd466ac56a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements_composite.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_example_elements_composite.yml
@@ -170,7 +170,7 @@ elements: |
       '#type': text_format
       '#title': 'Text format'
       '#description': '<b>Known Issues:</b><br /><a href="https://www.drupal.org/node/997826">Issue #997826: #states doesn''t work correctly with type text_format</a><br /><a href="https://www.drupal.org/node/2625128">Issue #2625128: Text format selection stays visible when using editor and a hidden webform state</a><br /><a href="https://www.drupal.org/node/1954968">Issue #1954968: Required CKEditor fields always fail HTML5 validation</a>'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -182,7 +182,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -212,6 +212,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -237,11 +242,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_entity_reference.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_entity_reference.yml
index b95d66c02a..8a35448d6a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_entity_reference.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_entity_reference.yml
@@ -33,7 +33,7 @@ elements: |
     '#selection_handler': 'default:user'
     '#selection_settings':
       include_anonymous: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -45,7 +45,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -75,6 +75,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -100,11 +105,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_options.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_options.yml
index 2012df513b..7633a29dc1 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_options.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_exporter_options.yml
@@ -43,7 +43,7 @@ elements: |
       one: One
       two: Two
       three: Three
-  
+
 css: ''
 javascript: ''
 settings:
@@ -55,7 +55,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -85,6 +85,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -110,11 +115,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_access_denied.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_access_denied.yml
index cb6f252c6f..c57974f68d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_access_denied.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_access_denied.yml
@@ -18,7 +18,7 @@ elements: |
   textfield:
     '#type': textfield
     '#title': textfield
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: 'Please login to access <b>[webform:title]</b>.'
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml
index 88aa731c62..d7ceca8262 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_api.yml
@@ -118,7 +118,7 @@ elements: |
     '#options':
       1: Administrator
       0: Anonymous
-  
+
 css: ''
 javascript: ''
 settings:
@@ -130,7 +130,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -160,6 +160,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -185,11 +190,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_archived.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_archived.yml
index b93e69fca8..11a3644db0 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_archived.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_archived.yml
@@ -17,7 +17,7 @@ category: 'Test: Webform'
 elements: |
   description:
     '#markup': 'This webform is archived.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -29,7 +29,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -59,6 +59,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -84,11 +89,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml
index 947ef7fe5d..ec562b350c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_assets.yml
@@ -18,21 +18,21 @@ elements: |
   test:
     '#type': textfield
     '#title': 'Text field'
-  
+
 css: |
   .webform-submission-form {
     background-color: #cccccc;
     display: none;
     padding: 20px;
   }
-  
+
 javascript: |
   (function ($) {
     $(function() {
       $('.webform-submission-form').fadeIn(3000);
     });
   })(jQuery);
-  
+
 settings:
   ajax: false
   ajax_scroll_top: form
@@ -42,7 +42,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -72,6 +72,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -97,11 +102,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofill.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofill.yml
index 307868e129..7a0111961f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofill.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofill.yml
@@ -21,7 +21,7 @@ elements: |
   textfield_excluded:
     '#type': textfield
     '#title': textfield_excluded
-  
+
 css: ''
 javascript: ''
 settings:
@@ -33,7 +33,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -63,6 +63,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -89,11 +94,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml
index ebd67d3c8f..5e178b82b8 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_autofocus.yml
@@ -18,7 +18,7 @@ elements: |
   test:
     '#type': textfield
     '#title': 'First input'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml
index 996ca2f1af..42e2d0d15f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_closed.yml
@@ -17,7 +17,7 @@ category: 'Test: Webform'
 elements: |
   description:
     '#markup': 'This message should not be displayed'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -29,7 +29,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -59,6 +59,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -84,11 +89,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml
index d6f52df03e..5f08dac5c8 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_confidential.yml
@@ -18,7 +18,7 @@ elements: |
   name:
     '#type': textfield
     '#title': Name
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml
index 5d0af7947e..94f0333d80 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_details_toggle.yml
@@ -25,7 +25,7 @@ elements: |
     '#title': 'Details 02'
     details_02:
       '#markup': 'Detail 02 Markup'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -37,7 +37,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -67,6 +67,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -92,11 +97,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml
index a642b2dcd9..6013e95fab 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_autocomplete.yml
@@ -20,7 +20,7 @@ elements: |
   test:
     '#type': email
     '#title': 'Test autocompletion is disabled.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -32,7 +32,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -62,6 +62,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml
index 9a59ffc122..4cc2e610db 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_back.yml
@@ -345,7 +345,7 @@ elements: |
     element_100:
       '#type': textfield
       '#title': 'Element #100'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -357,7 +357,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -387,6 +387,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -412,11 +417,17 @@ settings:
   wizard_progress_percentage: true
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_inline_errors.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_inline_errors.yml
index 97a0383d8f..7ba3a3a28e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_inline_errors.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_disable_inline_errors.yml
@@ -19,7 +19,7 @@ elements: |
     '#type': textfield
     '#title': textfield
     '#required': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -31,7 +31,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -61,6 +61,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -86,11 +91,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml
index 661fc1efa8..886125db37 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_anonymous.yml
@@ -22,7 +22,7 @@ elements: |
   comment:
     '#type': textarea
     '#title': Comment
-  
+
 css: ''
 javascript: ''
 settings:
@@ -34,7 +34,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -64,6 +64,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -89,11 +94,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml
index ec6048aeba..ee8299814a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_authenticated.yml
@@ -22,7 +22,7 @@ elements: |
   comment:
     '#type': textarea
     '#title': Comment
-  
+
 css: ''
 javascript: ''
 settings:
@@ -34,7 +34,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -64,6 +64,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -89,11 +94,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml
index d107c26361..2fa04891e9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_draft_multiple.yml
@@ -22,7 +22,7 @@ elements: |
   comment:
     '#type': textarea
     '#title': Comment
-  
+
 css: ''
 javascript: ''
 settings:
@@ -34,7 +34,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -64,6 +64,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -89,11 +94,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_inline_errors.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_inline_errors.yml
index e3c8b3c02a..f6f9a2927a 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_inline_errors.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_inline_errors.yml
@@ -126,7 +126,7 @@ elements: |
         1: 'Option 1'
         2: 'Option 2'
         3: 'Option 3'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -138,7 +138,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -168,6 +168,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -193,11 +198,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml
index 0e44d2ed8f..6ab358430c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit.yml
@@ -38,7 +38,7 @@ elements: |
   name:
     '#type': textfield
     '#title': Name
-  
+
 css: ''
 javascript: ''
 settings:
@@ -50,7 +50,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -80,6 +80,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -105,11 +110,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_total_unique.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_total_unique.yml
index b1be12a96b..6ecc87f7d7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_total_unique.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_total_unique.yml
@@ -18,7 +18,7 @@ elements: |
   name:
     '#type': textfield
     '#title': Name
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: both
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_user_unique.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_user_unique.yml
index 4cbe583045..ccb7c38811 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_user_unique.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_user_unique.yml
@@ -18,7 +18,7 @@ elements: |
   name:
     '#type': textfield
     '#title': Name
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: both
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_wait.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_wait.yml
index f1c9ce45be..9949341eec 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_wait.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_limit_wait.yml
@@ -18,7 +18,7 @@ elements: |
   name:
     '#type': textfield
     '#title': Name
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -87,11 +92,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -123,7 +134,7 @@ settings:
   limit_total_message: |
     webform_submission:interval:webform:wait =&gt; [webform_submission:interval:webform:wait]<br />
     webform_submission:interval:webform:source_entity:wait =&gt; [webform_submission:interval:webform:source_entity:wait]
-    
+
   limit_total_unique: false
   limit_user: 1
   limit_user_interval: 15
@@ -131,7 +142,7 @@ settings:
     <pre>
     webform_submission:interval:user:wait =&gt; [webform_submission:interval:user:wait]
     webform_submission:interval:user:source_entity:wait =&gt; [webform_submission:interval:user:source_entity:wait]</pre>
-    
+
   limit_user_unique: false
   entity_limit_total: 2
   entity_limit_total_interval: 30
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml
index 0be20c564f..d9e8e3c833 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_100.yml
@@ -315,7 +315,7 @@ elements: |
   element_100:
     '#type': textfield
     '#title': 'Element #100'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -327,7 +327,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -357,6 +357,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -382,11 +387,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml
index d94dc396e7..c665db0d8c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_200.yml
@@ -615,7 +615,7 @@ elements: |
   element_200:
     '#type': textfield
     '#title': 'Element #200'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -627,7 +627,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -657,6 +657,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -682,11 +687,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml
index 112d68e54f..47cb7f339d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_long_300.yml
@@ -915,7 +915,7 @@ elements: |
   element_300:
     '#type': textfield
     '#title': 'Element #300'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -927,7 +927,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -957,6 +957,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -982,11 +987,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml
index cd74ce573a..3ea0741922 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_novalidate.yml
@@ -22,7 +22,7 @@ elements: |
     '#title': 'Test required element with a custom error message.'
     '#required': true
     '#required_error': 'A custom error message'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -34,7 +34,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -64,6 +64,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -89,11 +94,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml
index 697e9d6b02..fa89f0c785 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_opening.yml
@@ -17,7 +17,7 @@ category: 'Test: Webform'
 elements: |
   description:
     '#markup': 'This message should not be displayed'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -29,7 +29,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -59,6 +59,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -84,11 +89,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml
index 04709cc7ab..a1dadd5702 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_prepopulate.yml
@@ -38,7 +38,7 @@ elements: |
         type: _none
   prepopulate_name:
     '#markup': '<a href="?source_entity_type=user&source_entity_id=1&name=John+Smith&colors[]=red&colors[]=white&users[]=1">Prepopulate elements and source entity using query string parameter ?source_entity_type=user&source_entity_id=1&name=John+Smith&colors[]=red&colors[]=white&users[]=1</a>'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -50,7 +50,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -80,6 +80,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -105,11 +110,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml
index 08ac6de031..aceabb2d9c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_preview.yml
@@ -51,13 +51,13 @@ elements: |
       '#format_attributes':
         class:
           - format-attributes-class
-  
+
 css: |
   .format-attributes-class {
     border: 1px dashed #ccc;
     padding: 10px;
   }
-  
+
 javascript: ''
 settings:
   ajax: false
@@ -68,7 +68,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -98,6 +98,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -123,11 +128,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml
index 86ffdf8dbb..4d6cba24d4 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_properties.yml
@@ -30,7 +30,7 @@ elements: |
   q:
     '#type': search
     '#title': 'Search Google'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -42,7 +42,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -72,6 +72,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -97,11 +102,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_remote_addr.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_remote_addr.yml
index 9f1c52239f..6673bffb90 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_remote_addr.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_remote_addr.yml
@@ -18,7 +18,7 @@ elements: |
   name:
     '#type': textfield
     '#title': Name
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_required.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_required.yml
index 3f88d7b248..ff832b65e2 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_required.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_required.yml
@@ -19,7 +19,7 @@ elements: |
     '#type': textfield
     '#title': textfield
     '#required': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -31,7 +31,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -61,6 +61,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -86,11 +91,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_reset.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_reset.yml
index 72076d2ee8..c58271b2c3 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_reset.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_reset.yml
@@ -19,7 +19,7 @@ elements: |
     '#type': textfield
     '#title': 'Text field'
     '#required': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -31,7 +31,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -61,6 +61,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -86,11 +91,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml
index 88c2af129a..947838f84b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_results_disabled.yml
@@ -17,7 +17,7 @@ category: 'Test: Form'
 elements: |
   description:
     '#markup': 'This webform will not save any submissions.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -29,7 +29,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -59,6 +59,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -84,11 +89,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_back.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_back.yml
index a78766c33c..2c52e4d186 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_back.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_back.yml
@@ -29,7 +29,7 @@ elements: |
       '#title': 'Element 2'
       '#type': textfield
       '#default_value': '{element_2}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -41,7 +41,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -71,6 +71,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -96,11 +101,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml
index b753d0dc25..fb03eaf8ea 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_once.yml
@@ -26,7 +26,7 @@ elements: |
   wizard_3:
     '#type': webform_wizard_page
     '#title': 'Wizard page #3'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -38,7 +38,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: true
   form_exception_message: ''
@@ -68,6 +68,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -93,11 +98,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml
index 000b56effb..94d05ca814 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_submit_text.yml
@@ -19,7 +19,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Custom submit text'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -31,7 +31,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -61,6 +61,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -86,11 +91,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml
index 42c4dbcf9d..cd5767c6c9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_template.yml
@@ -17,7 +17,7 @@ category: 'Test: Webform'
 elements: |
   description:
     '#markup': 'This webform is a template'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -29,7 +29,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -59,6 +59,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -84,11 +89,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml
index abcff8c6bd..e89a0bfc7f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved.yml
@@ -23,7 +23,7 @@ elements: |
   text_format:
     '#type': text_format
     '#title': text_format
-  
+
 css: ''
 javascript: ''
 settings:
@@ -35,7 +35,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -65,6 +65,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -90,11 +95,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved_wizard.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved_wizard.yml
index 19e66c3a08..ea0119ecc9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved_wizard.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_unsaved_wizard.yml
@@ -27,7 +27,7 @@ elements: |
     testfield_1:
       '#type': textfield
       '#title': textfield_2
-  
+
 css: ''
 javascript: ''
 settings:
@@ -39,7 +39,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -69,6 +69,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -94,11 +99,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml
index 4f53db218c..e5cf4e9670 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_validate.yml
@@ -18,7 +18,7 @@ elements: |
   custom:
     '#title': 'Custom Field'
     '#type': textfield
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_access.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_access.yml
index 1e32bc1e2c..7ddfbcf036 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_access.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_access.yml
@@ -56,7 +56,7 @@ elements: |
       '#type': textfield
       '#title': textfield_private
       '#default_value': '{textfield_private}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -68,7 +68,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -98,6 +98,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -123,11 +128,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml
index d4382750b3..3e91a545fc 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_advanced.yml
@@ -60,7 +60,7 @@ elements: |
       '#type': textarea
       '#required': true
       '#default_value': 'Here is some feedback'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -72,7 +72,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -102,6 +102,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -127,11 +132,17 @@ settings:
   wizard_progress_percentage: true
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml
index 465894474d..3feb044d13 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_basic.yml
@@ -29,7 +29,7 @@ elements: |
       '#title': 'Element 2'
       '#type': textfield
       '#default_value': '{element_2}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -41,7 +41,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -71,6 +71,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -96,11 +101,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_conditional.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_conditional.yml
index 8805f128bf..001dbe124c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_conditional.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_conditional.yml
@@ -98,7 +98,7 @@ elements: |
           unchecked: true
     page_5_markup:
       '#markup': 'This is page 5.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -110,7 +110,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -140,6 +140,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -165,11 +170,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml
index e5c607932f..feafdf17af 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_custom.yml
@@ -61,7 +61,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': Apply
-  
+
 css: ''
 javascript: ''
 settings:
@@ -73,7 +73,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -103,6 +103,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -128,11 +133,17 @@ settings:
   wizard_progress_percentage: true
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_links.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_links.yml
index 766262bcc0..f62d8fd759 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_links.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_links.yml
@@ -29,7 +29,7 @@ elements: |
       '#title': 'Element 2'
       '#type': textfield
       '#default_value': '{element_2}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -41,7 +41,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -71,6 +71,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -96,11 +101,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: true
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: true
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml
index abfdafc9f2..f0d24f1f82 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_100.yml
@@ -345,7 +345,7 @@ elements: |
     element_100:
       '#type': textfield
       '#title': 'Element #100'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -357,7 +357,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -387,6 +387,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -412,11 +417,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml
index 391c3fd499..fe2f3378b9 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_200.yml
@@ -675,7 +675,7 @@ elements: |
     element_200:
       '#type': textfield
       '#title': 'Element #200'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -687,7 +687,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -717,6 +717,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -742,11 +747,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml
index 66de28b231..aac4834401 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_long_300.yml
@@ -1005,7 +1005,7 @@ elements: |
     element_300:
       '#type': textfield
       '#title': 'Element #300'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -1017,7 +1017,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -1047,6 +1047,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -1072,11 +1077,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate.yml
index de89788e48..6142aed2a4 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate.yml
@@ -58,7 +58,7 @@ elements: |
   wizard_3:
     '#type': webform_wizard_page
     '#title': 'Wizard page #3'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -70,7 +70,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -100,6 +100,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -125,11 +130,17 @@ settings:
   wizard_progress_percentage: true
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate_comp.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate_comp.yml
index 743cb0bba7..a496868e0f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate_comp.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_form_wizard_validate_comp.yml
@@ -106,7 +106,7 @@ elements: |
   wizard_3:
     '#type': webform_wizard_page
     '#title': 'Wizard page #3'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -118,7 +118,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -148,6 +148,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -173,11 +178,17 @@ settings:
   wizard_progress_percentage: true
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_action.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_action.yml
index 51b5a80454..99a2b75c7c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_action.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_action.yml
@@ -47,7 +47,7 @@ elements: |
       '#attributes':
         readonly: readonly
         style: 'background-color: #eee'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -59,7 +59,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -89,6 +89,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -114,11 +119,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
@@ -234,7 +245,7 @@ handlers:
       data: |
         notes_add: ''
         notes_last: '[webform_submission:values:notes_add]'
-        
+
       message: 'Submission notes have been updated.'
       message_type: status
       debug: true
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml
index fb45ed8451..858fb5f315 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email.yml
@@ -40,7 +40,7 @@ elements: |
     '#type': textarea
     '#required': true
     '#default_value': '{message}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -52,7 +52,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -82,6 +82,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -107,11 +112,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml
index dae3b67462..2d6da39c18 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_advanced.yml
@@ -55,7 +55,7 @@ elements: |
     '#title': Notes
     '#private': true
     '#default_value': 'These notes are private.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -67,7 +67,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -97,6 +97,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -122,11 +127,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -247,7 +258,7 @@ handlers:
         [webform_submission:values]
         <hr />
         <p style="color:yellow"><em>Custom styled HTML markup</em></p>
-        
+
       excluded_elements: {  }
       ignore_access: true
       exclude_empty: true
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml
index cf507a48dd..74a2203414 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_mapping.yml
@@ -30,7 +30,7 @@ elements: |
     '#title': radios_other
     '#options': gender
     '#description': 'Check and enter ''Other'' to trigger an email.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -42,7 +42,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -72,6 +72,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -97,11 +102,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml
index 366251dcec..a3986b7422 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_roles.yml
@@ -22,7 +22,7 @@ elements: |
       authenticated: 'Authenticated (authenticated)'
       administrator: 'Administrator (administrator)'
       other: Other
-  
+
 css: ''
 javascript: ''
 settings:
@@ -34,7 +34,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -64,6 +64,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -89,11 +94,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml
index f664d37daa..38133f85c2 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_states.yml
@@ -17,7 +17,7 @@ category: 'Test: Handler'
 elements: |
   message:
     '#markup': 'Click ''Save Draft'' and ''Submit'' to send emails triggered by submissions  state.'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -29,7 +29,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -59,6 +59,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -84,11 +89,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_twig.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_twig.yml
index 0d16257dd6..0ff5d6839b 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_twig.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_email_twig.yml
@@ -40,7 +40,7 @@ elements: |
     '#type': textarea
     '#required': true
     '#default_value': '{message}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -52,7 +52,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -82,6 +82,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -107,11 +112,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -228,7 +239,7 @@ handlers:
       body: |
         <p>Submitted values are:</p>
         {{ webform_token('[webform_submission:values]', webform_submission) }}
-        
+
       excluded_elements: {  }
       ignore_access: false
       exclude_empty: true
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_settings.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_settings.yml
index 602c4dffec..467eebda3c 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_settings.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_handler_settings.yml
@@ -60,7 +60,7 @@ elements: |
       '#type': textfield
       '#title': 'Draft loaded message'
       '#default_value': '{Custom draft loaded message}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -72,7 +72,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -102,6 +102,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -127,11 +132,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml
index 2262992ff0..71453f7d90 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_libraries_optional.yml
@@ -7,7 +7,7 @@ dependencies:
 open: null
 close: null
 weight: 0
-uid: 1
+uid: 0
 template: false
 archive: false
 id: test_libraries_optional
@@ -84,7 +84,7 @@ elements: |
     signature:
       '#type': webform_signature
       '#title': Signature
-  
+
 css: ''
 javascript: ''
 settings:
@@ -96,7 +96,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -126,6 +126,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -151,11 +156,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_rendering.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_rendering.yml
index 5acc8e59ab..54aea7af46 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_rendering.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_rendering.yml
@@ -49,7 +49,7 @@ elements: |
     '#default_value':
       value: '<p><em>{default_value}</em></p>'
       format: basic_html
-  
+
 css: ''
 javascript: ''
 settings:
@@ -61,7 +61,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -91,6 +91,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: '[webform_submission:values:submission_label]'
   submission_log: false
   submission_views: {  }
@@ -116,11 +121,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states.yml
index b61408a499..eaee5050e2 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states.yml
@@ -2553,7 +2553,7 @@ elements: |
         disabled:
           ':input[name="disabled_trigger"]':
             checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -2565,7 +2565,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -2595,6 +2595,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -2620,11 +2625,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_autocomplete.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_autocomplete.yml
index 0611f8e95f..30f885aecd 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_autocomplete.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_autocomplete.yml
@@ -159,7 +159,7 @@ elements: |
       kitten_3:
         text: 'Cute Kitten 3'
         src: 'http://placekitten.com/130/200'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -171,7 +171,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -201,6 +201,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -226,11 +231,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_crosspage.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_crosspage.yml
index 1e0f5d4c7f..c648db7fe8 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_crosspage.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_crosspage.yml
@@ -45,7 +45,7 @@ elements: |
             checked: true
           ':input[name="trigger_2"]':
             checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -57,7 +57,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -87,6 +87,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -112,11 +117,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_disabled.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_disabled.yml
index 8ada98d889..552a6dfd97 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_disabled.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_disabled.yml
@@ -59,7 +59,7 @@ elements: |
       disabled:
         ':input[name="disabled"]':
           checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -71,7 +71,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: both
   form_submit_once: false
   form_exception_message: ''
@@ -101,6 +101,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -126,11 +131,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_clear.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_clear.yml
index 5083518a0a..3109d55af5 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_clear.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_clear.yml
@@ -102,7 +102,7 @@ elements: |
       '#type': textfield
       '#title': dependent_details_textfield
       '#default_value': '{dependent_details_textfield}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -114,7 +114,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -144,6 +144,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -169,11 +174,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_comp.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_comp.yml
index 7f6fd5c003..a194cbeda5 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_comp.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_comp.yml
@@ -76,7 +76,7 @@ elements: |
       '#first__title': webform_name_nested_first
       '#last__required': true
       '#last__title': webform_name_nested_last
-  
+
 css: ''
 javascript: ''
 settings:
@@ -88,7 +88,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -118,6 +118,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -143,11 +148,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_containers.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_containers.yml
index 3358b287ec..4756f2da38 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_containers.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_containers.yml
@@ -73,7 +73,7 @@ elements: |
             checked: true
           ':input[name="visible_slide_textfield"]':
             filled: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -85,7 +85,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -115,6 +115,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -140,11 +145,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_custom.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_custom.yml
index 66ead27d86..c6589afb64 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_custom.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_custom.yml
@@ -105,7 +105,7 @@ elements: |
       visible-slide:
         ':input[name="trigger_visible_slide"]':
           checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -117,7 +117,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -147,6 +147,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -172,11 +177,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_hidden.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_hidden.yml
index 538c88419e..c5ccec37c5 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_hidden.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_hidden.yml
@@ -138,7 +138,7 @@ elements: |
         invisible:
           ':input[name="trigger_checkbox"]':
             checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -150,7 +150,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -180,6 +180,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -205,11 +210,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_likert.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_likert.yml
index e0de159a69..e6262208f6 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_likert.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_likert.yml
@@ -33,7 +33,7 @@ elements: |
       visible:
         ':input[name="trigger_likert"]':
           checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -45,7 +45,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -75,6 +75,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -100,11 +105,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_multiple.yml
index 628dcb0770..68d19ad111 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_multiple.yml
@@ -27,7 +27,7 @@ elements: |
       required:
         ':input[name="trigger_required"]':
           checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -39,7 +39,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -69,6 +69,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -94,11 +99,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_nested.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_nested.yml
index 783370399f..50f3e74e67 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_nested.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_nested.yml
@@ -58,7 +58,7 @@ elements: |
                 checked: true
               ':input[name="b"]':
                 checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -70,7 +70,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -100,6 +100,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -125,11 +130,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_preview.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_preview.yml
index d304483686..75e3df6a1e 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_preview.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_preview.yml
@@ -52,7 +52,7 @@ elements: |
       '#type': textfield
       '#title': nested_textfield
       '#default_value': '{value}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -64,7 +64,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -94,6 +94,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -119,11 +124,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 2
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_required.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_required.yml
index c787555757..4301b52fc3 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_required.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_required.yml
@@ -333,7 +333,7 @@ elements: |
         visible:
           ':input[name="currency_trigger"]':
             checked: true
-  
+
   address_trigger_details:
     '#type': details
     '#title': address_trigger
@@ -447,7 +447,7 @@ elements: |
         required:
           ':input[name="composite_sub_elements_required_trigger"]':
             value: b
-  
+
 css: ''
 javascript: ''
 settings:
@@ -459,7 +459,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -489,6 +489,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -514,11 +519,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_save.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_save.yml
index 9cbbffe99d..ade2fd6458 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_save.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_save.yml
@@ -70,7 +70,7 @@ elements: |
       '#type': textfield
       '#title': dependent_details_textfield
       '#default_value': '{dependent_details_textfield}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -82,7 +82,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -112,6 +112,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -137,11 +142,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_wizard.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_wizard.yml
index 6a069da3d7..13fcdfb7d1 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_wizard.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_server_wizard.yml
@@ -220,7 +220,7 @@ elements: |
         collapsed:
           ':input[name="page_01_trigger_checkbox"]':
             checked: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -232,7 +232,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -262,6 +262,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -287,11 +292,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_triggers.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_triggers.yml
index cf02119e3c..af22d61e9f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_triggers.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_states_triggers.yml
@@ -130,7 +130,7 @@ elements: |
         visible:
           'details[data-webform-key="collapsed_trigger"]':
             collapsed: true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -142,7 +142,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -172,6 +172,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -197,11 +202,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml
index ccd10b07ae..640d62b40f 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_label.yml
@@ -7,7 +7,7 @@ dependencies:
 open: null
 close: null
 weight: 0
-uid: 1
+uid: 0
 template: false
 archive: false
 id: test_submission_label
@@ -19,7 +19,7 @@ elements: |
     '#type': textfield
     '#title': Name
     '#required': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -31,7 +31,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -61,6 +61,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: 'Submitted by [webform_submission:values:name]'
   submission_log: false
   submission_views: {  }
@@ -86,11 +91,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml
index a504fc8b8e..8e86ece1fa 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_log.yml
@@ -18,7 +18,7 @@ elements: |
   value:
     '#type': textfield
     '#title': 'Enter a value'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: true
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_views.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_views.yml
index 1bace4a296..395cf23433 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_views.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_submission_views.yml
@@ -7,7 +7,7 @@ dependencies:
 open: null
 close: null
 weight: 0
-uid: 1
+uid: 0
 template: false
 archive: false
 id: test_submission_views
@@ -18,7 +18,7 @@ elements: |
   textfield:
     '#type': textfield
     '#title': textfield
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views:
@@ -115,11 +120,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token.yml
index 09a9db5f90..9197481e28 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token.yml
@@ -34,7 +34,7 @@ elements: |
       Close long: [webform:close:long]
       Element title: [webform:element:webform_tokens:title]
       Element description: [webform:element:webform_tokens:description]
-  
+
   webform_submission_tokens:
     '#type': webform_codemirror
     '#mode': text
@@ -67,7 +67,7 @@ elements: |
       URL: [webform_submission:url]
       URL Edit Webform: [webform_submission:url:edit-form]
       UUID: [webform_submission:uuid]
-  
+
   webform_submission_source_entity_tokens:
     '#type': webform_codemirror
     '#mode': text
@@ -96,7 +96,7 @@ elements: |
       Summary: [webform_submission:source-entity:summary]
       Title: [webform_submission:source-entity:title]
       URL: [webform_submission:source-entity:url]
-  
+
   webform_submission_node_tokens:
     '#type': webform_codemirror
     '#mode': text
@@ -125,7 +125,7 @@ elements: |
       Summary: [webform_submission:node:summary]
       Title: [webform_submission:node:title]
       URL: [webform_submission:node:url]
-  
+
 css: ''
 javascript: ''
 settings:
@@ -137,7 +137,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -167,6 +167,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -192,11 +197,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml
index 49a5e28963..d34fb79fa5 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_submission_value.yml
@@ -153,7 +153,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -183,6 +183,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -208,11 +213,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_view_update.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_view_update.yml
index 1d6ded0ca7..a230a1d41d 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_view_update.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_token_view_update.yml
@@ -18,7 +18,7 @@ elements: |
   textfield:
     '#type': textfield
     '#title': textfield
-  
+
 css: ''
 javascript: ''
 settings:
@@ -30,7 +30,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -60,6 +60,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -85,11 +90,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -110,7 +121,7 @@ settings:
   confirmation_message: |
     <p>You can view your submission via <a href="[webform_submission:view-url]">[webform_submission:view-url:relative]</a></p>
     <p>You can update your submission via <a href="[webform_submission:update-url]">[webform_submission:update-url:relative]</a></p>
-    
+
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -209,7 +220,7 @@ handlers:
       body: |
         <a href="[webform_submission:view-url]">[webform_submission:view-url]</a><br/>
         <a href="[webform_submission:update-url]">[webform_submission:update-url]</a>
-        
+
       excluded_elements: {  }
       ignore_access: false
       exclude_empty: true
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_multiple.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_multiple.yml
index ab13bdd906..03d2f73ec7 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_multiple.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_multiple.yml
@@ -33,7 +33,7 @@ elements: |
     '#wrapper_attributes':
       style: 'display: inline-block; margin: 0; padding: 0 20px; font-size: 100px; '
     '#markup': '{0}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -45,7 +45,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -75,6 +75,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -100,11 +105,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -220,7 +231,7 @@ variants:
       elements: |
         letter_markup:
           '#markup': '[A]'
-        
+
       handlers: {  }
       debug: false
   b:
@@ -236,7 +247,7 @@ variants:
       elements: |
         letter_markup:
           '#markup': '[B]'
-        
+
       handlers: {  }
       debug: false
   1:
@@ -252,7 +263,7 @@ variants:
       elements: |
         number_markup:
           '#markup': '[1]'
-        
+
       handlers: {  }
       debug: false
   2:
@@ -268,7 +279,7 @@ variants:
       elements: |
         number_markup:
           '#markup': '[2]'
-        
+
       handlers: {  }
       debug: false
   3:
@@ -284,6 +295,6 @@ variants:
       elements: |
         number_markup:
           '#markup': '[3]'
-        
+
       handlers: {  }
       debug: false
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_override.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_override.yml
index 70f5497ea9..462a23a140 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_override.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_override.yml
@@ -23,7 +23,7 @@ elements: |
   textfield:
     '#type': textfield
     '#title': textfield
-  
+
 css: ''
 javascript: ''
 settings:
@@ -35,7 +35,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -65,6 +65,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -90,11 +95,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -224,7 +235,7 @@ variants:
       elements: |
         textfield:
           '#placeholder': 'This is a placeholder'
-        
+
       handlers: {  }
       debug: true
   handlers:
@@ -257,3 +268,19 @@ variants:
       elements: ''
       handlers: {  }
       debug: true
+  custom_form_properties:
+    id: override
+    label: Elements
+    notes: 'Alters custom form properties.'
+    variant_id: elements
+    element_key: variant
+    status: true
+    weight: 0
+    settings:
+      settings: {  }
+      elements: |
+        '#method': get
+        '#action': 'https://drupal.org'
+
+      handlers: {  }
+      debug: true
diff --git a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_randomize.yml b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_randomize.yml
index e65e1cf4cf..c328272c72 100644
--- a/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_randomize.yml
+++ b/web/modules/webform/tests/modules/webform_test/config/install/webform.webform.test_variant_randomize.yml
@@ -25,7 +25,7 @@ elements: |
     '#attributes':
       style: 'display: inline-block; margin: 0; padding: 0 20px; font-size: 100px;'
     '#markup': '{X}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -37,7 +37,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -67,6 +67,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -92,11 +97,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -212,7 +223,7 @@ variants:
       elements: |
         letter_markup:
           '#markup': '[A]'
-        
+
       handlers: {  }
       debug: false
   b:
@@ -228,6 +239,6 @@ variants:
       elements: |
         letter_markup:
           '#markup': '[B]'
-        
+
       handlers: {  }
       debug: false
diff --git a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_cards_long.inc b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_cards_long.inc
new file mode 100644
index 0000000000..7da932d21f
--- /dev/null
+++ b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_cards_long.inc
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file
+ * Generate long webform card elements.
+ */
+
+use Drupal\webform\WebformInterface;
+
+/**
+ * Generate long webform card elements.
+ *
+ * @param \Drupal\webform\WebformInterface $webform
+ *   A webform object.
+ *
+ * @return array
+ *   An array containing long webform elements.
+ */
+function webform_test_test_cards_long(WebformInterface $webform) {
+  $length = (int) str_replace('test_cards_long_', '', $webform->id());
+  $elements = [];
+  for ($i = 1; $i <= $length; $i++) {
+    $elements["card_$i"] = [
+      '#type' => 'webform_card',
+      '#title' => (string) t('Card #@index', ['@index' => $i]),
+    ];
+    $elements["card_$i"]["element_$i"] = [
+      '#type' => 'textfield',
+      '#title' => (string) t('Element #@index', ['@index' => $i]),
+    ];
+  }
+  return $elements;
+}
diff --git a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_element_title_display.inc b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_element_title_display.inc
index af70378107..211ebeb495 100644
--- a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_element_title_display.inc
+++ b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_element_title_display.inc
@@ -20,6 +20,9 @@ function webform_test_test_element_title_display() {
     'language_select',
     'webform_composite',
     'webform_section',
+    'webform_card',
+    'webform_table',
+    'webform_table_row',
     'value',
     'webform_attachment_token',
     'webform_attachment_twig',
diff --git a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_example_elements.inc b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_example_elements.inc
index 60b141368b..ef243b8c00 100644
--- a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_example_elements.inc
+++ b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_example_elements.inc
@@ -54,7 +54,7 @@ function webform_test_test_example_elements() {
           $multiple_element = $element;
           $multiple_element['#title'] = $element['#title'] . ' ' . $property;
           $multiple_element["#$property"] = TRUE;
-          if ($property == 'multiple' && $webform_element->hasProperty('select2')) {
+          if ($property === 'multiple' && $webform_element->hasProperty('select2')) {
             $multiple_element['#select2'] = TRUE;
           }
           $data[$category_id][$element_type . '_' . $property] = $multiple_element;
diff --git a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_form_states.inc b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_form_states.inc
index eb86179d37..ec33cadeb7 100644
--- a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_form_states.inc
+++ b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_form_states.inc
@@ -116,7 +116,7 @@ function _webform_test_states($type, array $default_properties = []) {
     // Set default container content.
     if ($webform_element->isContainer($element)) {
       // Containers can't be disabled.
-      if ($type == 'disabled') {
+      if ($type === 'disabled') {
         continue;
       }
     }
diff --git a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_form_wizard_long.inc b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_form_wizard_long.inc
index 3f8ae698e1..10784aa7a5 100644
--- a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_form_wizard_long.inc
+++ b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_form_wizard_long.inc
@@ -2,13 +2,13 @@
 
 /**
  * @file
- * Generate long webform elements.
+ * Generate long webform wizards.
  */
 
 use Drupal\webform\WebformInterface;
 
 /**
- * Generate long webform elements.
+ * Generate long webform wizard page elements.
  *
  * @param \Drupal\webform\WebformInterface $webform
  *   A webform object.
diff --git a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_options.inc b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_options.inc
index 7614a96667..35ba8da744 100644
--- a/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_options.inc
+++ b/web/modules/webform/tests/modules/webform_test/includes/webform_test.test_options.inc
@@ -50,7 +50,7 @@ function webform_test_test_options() {
   $webform_options = WebformOptions::loadMultiple();
   ksort($webform_options);
   foreach ($webform_options as $id => $webform_option) {
-    if ($id == 'test_translation') {
+    if ($id === 'test_translation') {
       continue;
     }
 
@@ -77,7 +77,7 @@ function webform_test_test_options() {
       elseif (preg_match('/(time_zones|yes_no|days|size)/', $id)) {
         $group = 'general_options';
       }
-      elseif ($id == 'test') {
+      elseif ($id === 'test') {
         $group = 'test_options';
       }
       else {
diff --git a/web/modules/webform/tests/modules/webform_test/webform_test.info.yml b/web/modules/webform/tests/modules/webform_test/webform_test.info.yml
index 8d81f8c9fb..6e188a75bc 100644
--- a/web/modules/webform/tests/modules/webform_test/webform_test.info.yml
+++ b/web/modules/webform/tests/modules/webform_test/webform_test.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module tests'
+name: 'Webform test'
 type: module
-description: 'Support module for webform that provides working examples for all supported features.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test/webform_test.module b/web/modules/webform/tests/modules/webform_test/webform_test.module
index 6f07b6e8e4..4f0e4a53ac 100644
--- a/web/modules/webform/tests/modules/webform_test/webform_test.module
+++ b/web/modules/webform/tests/modules/webform_test/webform_test.module
@@ -18,12 +18,12 @@
  * @return array
  *   An element.
  */
-function webform_test_ignored_element_callback($arg = NULL) {
+function webform_test_ignored_element_callback($element = NULL) {
   // Display error message when this callback is executed.
-  if (is_array($arg) && isset($arg['#title'])) {
-    $message = t('Callback not ignored for @title', ['@title' => $arg['#title']]);
+  if (is_array($element) && isset($element['#title'])) {
+    $message = t('Callback not ignored for @title', ['@title' => $element['#title']]);
     \Drupal::messenger()->addError($message);
-    return $arg;
+    return $element;
   }
   else {
     $message = t('Callback not ignored');
@@ -89,7 +89,7 @@ function webform_test_webform_load(array $entities) {
  *   include file.
  */
 function _webform_test_load_include($id) {
-  if (preg_match('/^(test_form_(?:wizard_)?long)_\d+$/', $id, $match)) {
+  if (preg_match('/^(test_form_(?:wizard_)?long|test_cards_long)_\d+$/', $id, $match)) {
     $id = $match[1];
   }
 
diff --git a/web/modules/webform/tests/modules/webform_test_ajax/src/Plugin/Block/WebformTestAjaxBlock.php b/web/modules/webform/tests/modules/webform_test_ajax/src/Plugin/Block/WebformTestAjaxBlock.php
index a2a8ba6194..bdb6505d8b 100644
--- a/web/modules/webform/tests/modules/webform_test_ajax/src/Plugin/Block/WebformTestAjaxBlock.php
+++ b/web/modules/webform/tests/modules/webform_test_ajax/src/Plugin/Block/WebformTestAjaxBlock.php
@@ -6,6 +6,7 @@
 use Drupal\Core\Block\BlockBase;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Routing\RedirectDestinationInterface;
+use Drupal\Core\Url;
 use Drupal\webform\Entity\Webform;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
@@ -64,7 +65,7 @@ public function build() {
 
     $ajax_links = [];
     foreach ($webforms as $webform_id => $webform) {
-      if (strpos($webform_id, 'test_ajax') !== 0 && $webform_id != 'test_form_wizard_long_100') {
+      if (strpos($webform_id, 'test_ajax') !== 0 && $webform_id !== 'test_form_wizard_long_100') {
         continue;
       }
 
@@ -108,6 +109,13 @@ public function build() {
           'class' => ['webform-dialog', 'webform-dialog-normal'],
         ],
       ],
+      'javascript' => [
+        'title' => "Drupal.webformOpenDialog('" . $webform->toUrl('canonical')->toString() . "', 'webform-dialog-normal'); return false;",
+        'url' => Url::fromRoute('<none>'),
+        'attributes' => [
+          'onclick' => "Drupal.webformOpenDialog('" . $webform->toUrl('canonical')->toString() . "', 'webform-dialog-normal'); return false;",
+        ],
+      ],
     ];
 
     $webform_style_guide = Webform::load('example_style_guide');
@@ -128,7 +136,7 @@ public function build() {
         ],
       ],
     ];
-    return [
+    $build = [
       'ajax' => [
         '#prefix' => '<h3>' . $this->t('Ajax links') . '</h3>',
         '#theme' => 'links',
@@ -144,8 +152,10 @@ public function build() {
         '#theme' => 'links',
         '#links' => $dialog_links,
       ],
-      '#attached' => ['library' => ['core/drupal.ajax']],
     ];
+    $build['#attached']['library'][] = 'webform/webform.dialog';
+    $build['#attached']['drupalSettings']['webform']['dialog']['options'] = \Drupal::config('webform.settings')->get('settings.dialog_options');
+    return $build;
   }
 
   /**
diff --git a/web/modules/webform/tests/modules/webform_test_ajax/webform_test_ajax.info.yml b/web/modules/webform/tests/modules/webform_test_ajax/webform_test_ajax.info.yml
index ab43da72b1..cda4272d92 100644
--- a/web/modules/webform/tests/modules/webform_test_ajax/webform_test_ajax.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_ajax/webform_test_ajax.info.yml
@@ -1,13 +1,13 @@
-name: 'Webform module Ajax tests'
+name: 'Webform Ajax test'
 type: module
-description: 'Support module for Webform module Ajax testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform Ajax testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:block'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_alter_hooks/webform_test_alter_hooks.info.yml b/web/modules/webform/tests/modules/webform_test_alter_hooks/webform_test_alter_hooks.info.yml
index cde4c23139..68e15b3c16 100644
--- a/web/modules/webform/tests/modules/webform_test_alter_hooks/webform_test_alter_hooks.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_alter_hooks/webform_test_alter_hooks.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module alter hooks tests'
+name: 'Webform Alter Hooks test'
 type: module
-description: 'Support module for webform that tests form and element alter hooks.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform form and element alter hooks testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_block_context/webform_test_block_context.info.yml b/web/modules/webform/tests/modules/webform_test_block_context/webform_test_block_context.info.yml
index f9af6a2030..42df2e152f 100644
--- a/web/modules/webform/tests/modules/webform_test_block_context/webform_test_block_context.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_block_context/webform_test_block_context.info.yml
@@ -1,13 +1,13 @@
-name: 'Webform module block context tests'
+name: 'Webform Block Context test'
 type: module
-description: 'Support module for Webform module block context testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform block context testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:block'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_block_custom/webform_test_block_custom.info.yml b/web/modules/webform/tests/modules/webform_test_block_custom/webform_test_block_custom.info.yml
index 7a3ed9d2a0..9d499785bd 100644
--- a/web/modules/webform/tests/modules/webform_test_block_custom/webform_test_block_custom.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_block_custom/webform_test_block_custom.info.yml
@@ -1,14 +1,14 @@
-name: 'Webform module block custom tests'
+name: 'Webform Block Custom test'
 type: module
-description: 'Support module for Webform module block custom testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform block custom testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:block'
   - 'drupal:block_content'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_block_submission_limit/webform_test_block_submission_limit.info.yml b/web/modules/webform/tests/modules/webform_test_block_submission_limit/webform_test_block_submission_limit.info.yml
index 4957cd1a15..06517d7fb9 100644
--- a/web/modules/webform/tests/modules/webform_test_block_submission_limit/webform_test_block_submission_limit.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_block_submission_limit/webform_test_block_submission_limit.info.yml
@@ -1,13 +1,13 @@
-name: 'Webform module block submission limit tests'
+name: 'Webform Block Submission Liimit test'
 type: module
-description: 'Support module for Webform module block submission limit testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform block submission limit testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:block'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_config_performance/webform_test_config_performance.info.yml b/web/modules/webform/tests/modules/webform_test_config_performance/webform_test_config_performance.info.yml
index e72024a6a5..0bb77e50ec 100644
--- a/web/modules/webform/tests/modules/webform_test_config_performance/webform_test_config_performance.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_config_performance/webform_test_config_performance.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module config performance tests'
+name: 'Webform Config Performance test'
 type: module
-description: 'Test webform config performance by generating a 1000 webforms containing 100 elements.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform config performance testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_comp_file_plugin.yml b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_comp_file_plugin.yml
index b11b36c12b..54c27bc435 100644
--- a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_comp_file_plugin.yml
+++ b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_comp_file_plugin.yml
@@ -27,7 +27,7 @@ elements: |
     '#title': webform_test_composite_file_multiple_header
     '#multiple': true
     '#multiple__header': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -39,7 +39,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -69,6 +69,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -94,11 +99,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_plugin.yml b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_plugin.yml
index cddb9824df..7f3a4963f2 100644
--- a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_plugin.yml
+++ b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_composite_plugin.yml
@@ -27,7 +27,7 @@ elements: |
     '#title': webform_test_composite_multiple_header
     '#multiple': true
     '#multiple__header': true
-  
+
 css: ''
 javascript: ''
 settings:
@@ -39,7 +39,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -69,6 +69,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -94,11 +99,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml
index 89ce23ce38..f61a9236eb 100644
--- a/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml
+++ b/web/modules/webform/tests/modules/webform_test_element/config/install/webform.webform.test_element_plugin.yml
@@ -18,12 +18,12 @@ elements: |
   description:
     '#markup': |
       <p>This webform includes a #test elememt which will trigger all methods associated with a WebformElement plugin.</p>
-      
+
   test:
     '#type': webform_test_element
     '#title': 'This is a test element'
     '#default_value': '{default_value}'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -35,7 +35,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -65,6 +65,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -90,11 +95,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test_element/src/Plugin/WebformElement/WebformTestElement.php b/web/modules/webform/tests/modules/webform_test_element/src/Plugin/WebformElement/WebformTestElement.php
index 982149b726..8ebc358917 100644
--- a/web/modules/webform/tests/modules/webform_test_element/src/Plugin/WebformElement/WebformTestElement.php
+++ b/web/modules/webform/tests/modules/webform_test_element/src/Plugin/WebformElement/WebformTestElement.php
@@ -121,7 +121,7 @@ public function postSave(array &$element, WebformSubmissionInterface $webform_su
    *   Additional parameter passed to the invoked method name.
    */
   protected function displayMessage($method_name, $context1 = NULL) {
-    if (PHP_SAPI != 'cli') {
+    if (PHP_SAPI !== 'cli') {
       $t_args = ['@class_name' => get_class($this), '@method_name' => $method_name, '@context1' => $context1];
       $this->messenger()->addStatus($this->t('Invoked: @class_name:@method_name @context1', $t_args));
     }
diff --git a/web/modules/webform/tests/modules/webform_test_element/webform_test_element.info.yml b/web/modules/webform/tests/modules/webform_test_element/webform_test_element.info.yml
index a934bedb2c..d579311da5 100644
--- a/web/modules/webform/tests/modules/webform_test_element/webform_test_element.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_element/webform_test_element.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module element tests'
+name: 'Webform Element test'
 type: module
-description: 'Support module for webform that provides element plugin tests.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform element plugin testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_element_input_masks/webform_test_element_input_masks.info.yml b/web/modules/webform/tests/modules/webform_test_element_input_masks/webform_test_element_input_masks.info.yml
index 7f01080ceb..efc88f5185 100644
--- a/web/modules/webform/tests/modules/webform_test_element_input_masks/webform_test_element_input_masks.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_element_input_masks/webform_test_element_input_masks.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module element input masks tests'
+name: 'Webform Element Input Masks test'
 type: module
-description: 'Support module for webform that provides element input masks hooks.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform input mask testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_entity_reference/config/install/webform.webform.test_element_entity_reference_vs.yml b/web/modules/webform/tests/modules/webform_test_entity_reference/config/install/webform.webform.test_element_entity_reference_vs.yml
index ff8db53ad5..0ce115d315 100644
--- a/web/modules/webform/tests/modules/webform_test_entity_reference/config/install/webform.webform.test_element_entity_reference_vs.yml
+++ b/web/modules/webform/tests/modules/webform_test_entity_reference/config/install/webform.webform.test_element_entity_reference_vs.yml
@@ -65,17 +65,17 @@ elements: |
     '#wrapper_attributes':
       class:
         - webform-entity-reference-options
-  
+
 css: |
   /* Autocomplete */
-  
+
   .ui-autocomplete {
     display: flex;
     flex-wrap: wrap !important;
     align-self: flex-start !important;
     max-width: 540px !important;
   }
-  
+
   .ui-autocomplete .ui-menu-item-wrapper {
     display: block !important;
     border: 1px solid #ccc !important;
@@ -84,57 +84,57 @@ css: |
     margin: 10px 0 0 10px !important;
     padding: 10px !important;
   }
-  
+
   .ui-autocomplete .ui-menu-item-wrapper.ui-state-active {
     background-color: blue !important;
   }
-  
+
   .ui-autocomplete .views-field views-field-field-image {
     display: block;
     margin: 0 0 5px 0;
   }
-  
+
   /* Checkboex and radios */
-  
+
   .webform-entity-reference-options .fieldset-wrapper > div {
     display: flex;
     flex-wrap: wrap;
     align-self: flex-start;
   }
-  
+
   .webform-entity-reference-options .form-item {
     position: relative;
   }
-  
+
   .webform-entity-reference-options .form-item input {
     position: absolute;
     top: 20px;
-    left: 20px; 
+    left: 20px;
   }
-  
+
   .webform-entity-reference-options .form-item label {
     display: block;
     border: 1px solid #ccc;
     background-color: #eee;
     width: 100px;
-    margin: 0 10px 10px 0;  
-    padding: 10px;  
+    margin: 0 10px 10px 0;
+    padding: 10px;
   }
-  
+
   .webform-entity-reference-options .form-item input:checked + label {
     display: block;
     border: 1px solid #ccc;
     background-color: #ffc;
     width: 100px;
-    margin: 0 10px 10px 0;  
-    padding: 10px;  
+    margin: 0 10px 10px 0;
+    padding: 10px;
   }
-  
+
   .webform-entity-reference-options label.option img {
     display: block;
-    margin: 0 0 5px 0;  
+    margin: 0 0 5px 0;
   }
-  
+
 javascript: ''
 settings:
   ajax: false
@@ -145,7 +145,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -175,6 +175,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -200,11 +205,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 1
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test_entity_reference/webform_test_entity_reference_views.info.yml b/web/modules/webform/tests/modules/webform_test_entity_reference/webform_test_entity_reference_views.info.yml
index 9536ff38a4..805fd597b1 100644
--- a/web/modules/webform/tests/modules/webform_test_entity_reference/webform_test_entity_reference_views.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_entity_reference/webform_test_entity_reference_views.info.yml
@@ -1,15 +1,15 @@
-name: 'Webform module entity reference tests'
+name: 'Webform Entity Reference Views test'
 type: module
-description: 'Support module for Webform module entity reference testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform entity reference testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:node'
   - 'drupal:user'
   - 'drupal:views'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_exporter/webform_test_exporter.info.yml b/web/modules/webform/tests/modules/webform_test_exporter/webform_test_exporter.info.yml
index 3ae75e2b43..b8c1c10af9 100644
--- a/web/modules/webform/tests/modules/webform_test_exporter/webform_test_exporter.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_exporter/webform_test_exporter.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module exporter tests'
+name: 'Webform Exporter test'
 type: module
-description: 'Support module for webform that provides exporter plugin tests.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform exporter plugin testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_conditions.yml b/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_conditions.yml
index d4570f068e..d8cd5ed403 100644
--- a/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_conditions.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_conditions.yml
@@ -23,7 +23,7 @@ elements: |
   trigger_b:
     '#type': checkbox
     '#title': trigger_b
-  
+
 css: ''
 javascript: ''
 settings:
@@ -35,7 +35,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -65,6 +65,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -90,11 +95,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml b/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml
index 5b2f2d6e3c..3e791e3598 100644
--- a/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler/config/install/webform.webform.test_handler_test.yml
@@ -21,7 +21,7 @@ elements: |
     '#type': textfield
     '#title': 'Empty element'
     '#description': 'Entering any value will throw an error'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -33,7 +33,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -63,6 +63,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -88,11 +93,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test_handler/src/Plugin/WebformHandler/TestWebformHandler.php b/web/modules/webform/tests/modules/webform_test_handler/src/Plugin/WebformHandler/TestWebformHandler.php
index 1d1eaa7c50..68152f7a92 100644
--- a/web/modules/webform/tests/modules/webform_test_handler/src/Plugin/WebformHandler/TestWebformHandler.php
+++ b/web/modules/webform/tests/modules/webform_test_handler/src/Plugin/WebformHandler/TestWebformHandler.php
@@ -250,7 +250,7 @@ public function deleteElement($key, array $element) {
    *   Additional parameter passed to the invoked method name.
    */
   protected function displayMessage($method_name, $context1 = NULL) {
-    if (PHP_SAPI != 'cli') {
+    if (PHP_SAPI !== 'cli') {
       $t_args = [
         '@id' => $this->getHandlerId(),
         '@class_name' => get_class($this),
diff --git a/web/modules/webform/tests/modules/webform_test_handler/webform_test_handler.info.yml b/web/modules/webform/tests/modules/webform_test_handler/webform_test_handler.info.yml
index b41de8343c..46f8bd120c 100644
--- a/web/modules/webform/tests/modules/webform_test_handler/webform_test_handler.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler/webform_test_handler.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module handler tests'
+name: 'Webform Handler test'
 type: module
-description: 'Support module for webform that provides handler plugin tests.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform handler plugin testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_handler_invoke_alter/webform_test_handler_invoke_alter.info.yml b/web/modules/webform/tests/modules/webform_test_handler_invoke_alter/webform_test_handler_invoke_alter.info.yml
index a1844d5148..e60902c262 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_invoke_alter/webform_test_handler_invoke_alter.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_invoke_alter/webform_test_handler_invoke_alter.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module handler invoke alter tests'
+name: 'Webform Handler Invoke test'
 type: module
-description: 'Support module for webform that provides handler invoke alter tests.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform handler invoke alter testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_get.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_get.yml
index 9f056e3657..bcced891f6 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_get.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_get.yml
@@ -37,7 +37,7 @@ elements: |
     '#title': 'Confirmation number'
     '#type': value
     '#value': '[webform:handler:remote_post:completed:confirmation_number]'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -49,7 +49,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -79,6 +79,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -104,11 +109,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -128,7 +139,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-    
+
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -237,37 +248,37 @@ handlers:
         confirmation_number: confirmation_number
       custom_data: |
         custom_data: true
-        
+
       custom_options: |
         headers:
           custom_header: 'true'
-        
+
       cast: false
       debug: true
       completed_url: 'http://webform-test-handler-remote-post/completed'
       completed_custom_data: |
         custom_completed: true
-        
+
       updated_url: 'http://webform-test-handler-remote-post/updated'
       updated_custom_data: |
         custom_updated: true
-        
+
       deleted_url: 'http://webform-test-handler-remote-post/deleted'
       deleted_custom_data: |
         custom_deleted: true
-        
+
       draft_created_url: 'http://webform-test-handler-remote-post/draft_created'
       draft_created_custom_data: |
         custom_draft_created: true
-        
+
       draft_updated_url: 'http://webform-test-handler-remote-post/draft_updated'
       draft_updated_custom_data: |
         custom_draft_updated: true
-        
+
       converted_url: 'http://webform-test-handler-remote-post/converted'
       converted_custom_data: |
         custom_converted: true
-        
+
       message: ''
       messages: {  }
       error_url: ''
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml
index c7a8abc4e7..48d3e34d41 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post.yml
@@ -20,8 +20,10 @@ elements: |
     '#type': select
     '#options':
       200: '200 OK'
+      201: '201 Completed'
       401: '401 Unauthorized'
       404: '404 Not Found'
+      405: '405 Method Not Allowed'
       500: '500 Internal Server Error'
     '#default_value': 200
   first_name:
@@ -38,7 +40,7 @@ elements: |
     '#title': 'Confirmation number'
     '#type': value
     '#value': '[webform:handler:remote_post:completed:confirmation_number]'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -50,7 +52,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -80,6 +82,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -105,11 +112,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -129,7 +142,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-    
+
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -238,43 +251,47 @@ handlers:
         confirmation_number: confirmation_number
       custom_data: |
         custom_data: true
-        
+
       custom_options: |
         headers:
           'Accept-Language': '[webform_submission:langcode]'
           custom_header: 'true'
-        
+
       cast: false
       debug: true
       completed_url: 'http://webform-test-handler-remote-post/completed'
       completed_custom_data: |
         custom_completed: true
-        
+
       updated_url: 'http://webform-test-handler-remote-post/updated'
       updated_custom_data: |
         custom_updated: true
-        
+
       deleted_url: 'http://webform-test-handler-remote-post/deleted'
       deleted_custom_data: |
         custom_deleted: true
-        
+
       draft_created_url: 'http://webform-test-handler-remote-post/draft_created'
       draft_created_custom_data: |
         custom_draft_created: true
-        
+
       draft_updated_url: 'http://webform-test-handler-remote-post/draft_updated'
       draft_updated_custom_data: |
         custom_draft_updated: true
-        
+
       converted_url: 'http://webform-test-handler-remote-post/converted'
       converted_custom_data: |
         custom_converted: true
-        
+
       message: ''
       messages:
         - code: 401
           message: 'This is a message token <strong>[webform:handler:remote_post:message]</strong>'
         - code: 404
           message: 'This is a custom 404 not found message.'
+        - code: 405
+          message: 'This is a array token <strong>[webform:handler:remote_post:options][webform:handler:remote_post:options:clear]</strong>'
+        - code: 200
+          message: 'This is a custom 200 success message.'
       error_url: ''
 variants: {  }
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_cast.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_cast.yml
index 34b6db3dde..9e091e5c3d 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_cast.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_cast.yml
@@ -38,7 +38,7 @@ elements: |
       number:
         '#type': number
         '#title': number
-  
+
 css: ''
 javascript: ''
 settings:
@@ -50,7 +50,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -80,6 +80,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -107,11 +112,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -131,7 +142,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-    
+
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -237,7 +248,11 @@ handlers:
         locked: locked
         sticky: sticky
         notes: notes
-      custom_data: ''
+      custom_data: |
+        boolean_true: '(boolean) true'
+        integer: '(integer) 100'
+        float: '(float) 100.01'
+
       custom_options: ''
       debug: true
       completed_url: 'http://webform-test-handler-remote-post/completed'
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_file.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_file.yml
index b289ee6c0b..a6171f46ff 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_file.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_post_file.yml
@@ -26,7 +26,7 @@ elements: |
     '#required': true
     '#multiple': true
     '#file_extensions': txt
-  
+
 css: ''
 javascript: ''
 settings:
@@ -38,7 +38,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -68,6 +68,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -93,11 +98,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -117,7 +128,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-    
+
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_put.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_put.yml
index 9db3992afd..e229d7c9b8 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_put.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/config/install/webform.webform.test_handler_remote_put.yml
@@ -37,7 +37,7 @@ elements: |
     '#title': 'Confirmation number'
     '#type': value
     '#value': '[webform:handler:remote_post:completed:confirmation_number]'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -49,7 +49,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -79,6 +79,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -104,11 +109,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
@@ -128,7 +139,7 @@ settings:
   confirmation_title: ''
   confirmation_message: |
     <p>Your confirmation number is [webform_submission:values:confirmation_number].</p>
-    
+
   confirmation_url: ''
   confirmation_attributes: {  }
   confirmation_back: true
@@ -237,37 +248,37 @@ handlers:
         confirmation_number: confirmation_number
       custom_data: |
         custom_data: true
-        
+
       custom_options: |
         headers:
           custom_header: 'true'
-        
+
       cast: false
       debug: true
       completed_url: 'http://webform-test-handler-remote-post/completed'
       completed_custom_data: |
         custom_completed: true
-        
+
       updated_url: 'http://webform-test-handler-remote-post/updated'
       updated_custom_data: |
         custom_updated: true
-        
+
       deleted_url: 'http://webform-test-handler-remote-post/deleted'
       deleted_custom_data: |
         custom_deleted: true
-        
+
       draft_created_url: 'http://webform-test-handler-remote-post/draft_created'
       draft_created_custom_data: |
         custom_draft_created: true
-        
+
       draft_updated_url: 'http://webform-test-handler-remote-post/draft_updated'
       draft_updated_custom_data: |
         custom_draft_updated: true
-        
+
       converted_url: 'http://webform-test-handler-remote-post/converted'
       converted_custom_data: |
         custom_converted: true
-        
+
       message: ''
       messages: {  }
       error_url: ''
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/src/WebformTestHandlerRemotePostClient.php b/web/modules/webform/tests/modules/webform_test_handler_remote_post/src/WebformTestHandlerRemotePostClient.php
index ace37b4ec8..b0f79ab698 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/src/WebformTestHandlerRemotePostClient.php
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/src/WebformTestHandlerRemotePostClient.php
@@ -21,7 +21,7 @@ public function request($method, $uri = '', array $options = []) {
       return parent::request($method, $uri, $options);
     }
 
-    if ($method == 'get') {
+    if ($method === 'get') {
       parse_str(parse_url($uri, PHP_URL_QUERY), $params);
     }
     else {
@@ -37,6 +37,10 @@ public function request($method, $uri = '', array $options = []) {
       case 404:
         return new Response(404, [], 'File not found');
 
+      // 405 Method Not Allowed.
+      case 405:
+        return new Response(405, [], 'Method Not Allowed');
+
       // 401 Unauthorized.
       case 401:
         $status = 401;
@@ -61,6 +65,18 @@ public function request($method, $uri = '', array $options = []) {
         ];
         return new Response($status, $headers, Json::encode($json));
 
+      case 201:
+        $status = 201;
+        $headers = ['Content-Type' => ['application/json']];
+        $json = [
+          'method' => $method,
+          'status' => 'success',
+          'message' => (string) new FormattableMarkup('Process @type request.', ['@type' => $operation]),
+          'options' => $options,
+          'confirmation_number' => $random->name(20, TRUE),
+        ];
+        return new Response($status, $headers, Json::encode($json));
+
       // 200 OK.
       case 200:
       default:
diff --git a/web/modules/webform/tests/modules/webform_test_handler_remote_post/webform_test_handler_remote_post.info.yml b/web/modules/webform/tests/modules/webform_test_handler_remote_post/webform_test_handler_remote_post.info.yml
index b652138254..e25e8ee746 100644
--- a/web/modules/webform/tests/modules/webform_test_handler_remote_post/webform_test_handler_remote_post.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_handler_remote_post/webform_test_handler_remote_post.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module remote post tests'
+name: 'Webform Remote Post test'
 type: module
-description: 'Support module for Webform module remote post testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform remote post testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.info.yml b/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.info.yml
index 611f5fe06d..f817da315d 100644
--- a/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module markup tests'
+name: 'Webform Markup test'
 type: module
-description: 'Support module for markup tests.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform markup testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.module b/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.module
index 0838c16c5f..8e7aa7be10 100644
--- a/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.module
+++ b/web/modules/webform/tests/modules/webform_test_markup/webform_test_markup.module
@@ -6,7 +6,7 @@
  */
 
 /**
- * Prepares variables for Webform HTML Editor markup templates.
+ * Implements hook_preprocess_webform_html_editor_markup() for Webform HTML Editor markup templates.
  *
  * @see webform.webform.test_element_markup.yml
  */
diff --git a/web/modules/webform/tests/modules/webform_test_message_custom/webform_test_message_custom.info.yml b/web/modules/webform/tests/modules/webform_test_message_custom/webform_test_message_custom.info.yml
index c1a8f29182..9a74fddabf 100644
--- a/web/modules/webform/tests/modules/webform_test_message_custom/webform_test_message_custom.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_message_custom/webform_test_message_custom.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module custom message tests'
+name: 'Webform Custom Messag test'
 type: module
-description: 'Support module for Webform module custom message testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform custom message testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml b/web/modules/webform/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml
index 2778609050..4e287a7c7b 100644
--- a/web/modules/webform/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml
+++ b/web/modules/webform/tests/modules/webform_test_options/config/install/webform.webform.test_options.yml
@@ -219,7 +219,7 @@ elements: |
       '#options': range
       '#min': a
       '#max': z
-  
+
 css: ''
 javascript: ''
 settings:
@@ -231,7 +231,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -261,6 +261,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -286,11 +291,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test_options/webform_test_options.info.yml b/web/modules/webform/tests/modules/webform_test_options/webform_test_options.info.yml
index 486e1dc880..468721f67c 100644
--- a/web/modules/webform/tests/modules/webform_test_options/webform_test_options.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_options/webform_test_options.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module options tests'
+name: 'Webform Options test'
 type: module
-description: 'Support module for webform that provides options tests.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform options testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_options/webform_test_options.module b/web/modules/webform/tests/modules/webform_test_options/webform_test_options.module
index e175f64102..dfeb09392b 100644
--- a/web/modules/webform/tests/modules/webform_test_options/webform_test_options.module
+++ b/web/modules/webform/tests/modules/webform_test_options/webform_test_options.module
@@ -6,7 +6,7 @@
  */
 
 /**
- * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter().
+ * Implements hook_webform_options_WEBFORM_OPTIONS_ID_alter() for webform options test.
  */
 function webform_test_options_webform_options_test_alter(array &$options, array &$element) {
   $options += [
diff --git a/web/modules/webform/tests/modules/webform_test_paragraphs/webform_test_paragraphs.info.yml b/web/modules/webform/tests/modules/webform_test_paragraphs/webform_test_paragraphs.info.yml
index dc47813720..775273166b 100644
--- a/web/modules/webform/tests/modules/webform_test_paragraphs/webform_test_paragraphs.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_paragraphs/webform_test_paragraphs.info.yml
@@ -1,13 +1,13 @@
-name: 'Webform module Paragraphs module tests'
+name: 'Webform Paragraphs test'
 type: module
-description: 'Support module for Webform module Paragraphs module testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform paragraphs integration testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'paragraphs:paragraphs'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_rest/webform_test_rest.info.yml b/web/modules/webform/tests/modules/webform_test_rest/webform_test_rest.info.yml
index bd96fc404a..7bed75d798 100644
--- a/web/modules/webform/tests/modules/webform_test_rest/webform_test_rest.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_rest/webform_test_rest.info.yml
@@ -1,15 +1,15 @@
-name: 'Webform module REST API tests'
+name: 'Webform REST API test'
 type: module
-description: 'Support module for Webform module REST API testing.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform REST API testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:hal'
   - 'drupal:rest'
   - 'drupal:serialization'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_submissions/config/install/webform.webform.test_submissions.yml b/web/modules/webform/tests/modules/webform_test_submissions/config/install/webform.webform.test_submissions.yml
index 565a611fd1..994d3f1215 100644
--- a/web/modules/webform/tests/modules/webform_test_submissions/config/install/webform.webform.test_submissions.yml
+++ b/web/modules/webform/tests/modules/webform_test_submissions/config/install/webform.webform.test_submissions.yml
@@ -36,7 +36,7 @@ elements: |
     '#selection_handler': 'default:node'
     '#selection_settings':
       target_bundles:
-        page: page
+        webform_test_submissions: webform_test_submissions
   colors:
     '#type': checkboxes
     '#title': 'Flag colors'
@@ -58,7 +58,7 @@ elements: |
   address:
     '#type': webform_address
     '#title': Address
-  
+
 css: ''
 javascript: ''
 settings:
@@ -70,7 +70,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -100,6 +100,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -125,11 +130,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test_submissions/webform_test_submissions.info.yml b/web/modules/webform/tests/modules/webform_test_submissions/webform_test_submissions.info.yml
index b34f22aaad..196ff4f0bd 100644
--- a/web/modules/webform/tests/modules/webform_test_submissions/webform_test_submissions.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_submissions/webform_test_submissions.info.yml
@@ -1,13 +1,13 @@
-name: 'Webform module submissions tests'
+name: 'Webform Submissions test'
 type: module
-description: 'Support module for webform that provides a webform with submission tests.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform submission testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:node'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_third_party_settings/webform_test_third_party_settings.info.yml b/web/modules/webform/tests/modules/webform_test_third_party_settings/webform_test_third_party_settings.info.yml
index 9713f68d0d..b8c6e91ac2 100644
--- a/web/modules/webform/tests/modules/webform_test_third_party_settings/webform_test_third_party_settings.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_third_party_settings/webform_test_third_party_settings.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module third party settings tests'
+name: 'Webform Third Party Settings test'
 type: module
-description: 'Support module for Webform module that provides example of third party settings.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform third party settings testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml b/web/modules/webform/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml
index 437943f925..cb9537cca1 100644
--- a/web/modules/webform/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml
+++ b/web/modules/webform/tests/modules/webform_test_translation/config/install/webform.webform.test_translation.yml
@@ -62,7 +62,7 @@ elements: |
     '#type': webform_actions
     '#title': 'Submit button(s)'
     '#submit__label': 'Send message'
-  
+
 css: ''
 javascript: ''
 settings:
@@ -74,7 +74,7 @@ settings:
   page: true
   page_submit_path: ''
   page_confirm_path: ''
-  page_admin_theme: false
+  page_theme_name: ''
   form_title: source_entity_webform
   form_submit_once: false
   form_exception_message: ''
@@ -104,6 +104,11 @@ settings:
   form_access_denied_message: ''
   form_access_denied_attributes: {  }
   form_file_limit: ''
+  share: false
+  share_node: false
+  share_theme_name: ''
+  share_title: true
+  share_page_body_attributes: {  }
   submission_label: ''
   submission_log: false
   submission_views: {  }
@@ -129,11 +134,17 @@ settings:
   wizard_progress_percentage: false
   wizard_progress_link: false
   wizard_progress_states: false
+  wizard_auto_forward: true
   wizard_start_label: ''
   wizard_preview_link: false
   wizard_confirmation: true
   wizard_confirmation_label: ''
   wizard_track: ''
+  wizard_prev_button_label: ''
+  wizard_next_button_label: ''
+  wizard_toggle: false
+  wizard_toggle_show_label: ''
+  wizard_toggle_hide_label: ''
   preview: 0
   preview_label: ''
   preview_title: ''
diff --git a/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.info.yml b/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.info.yml
index 02b845d9c2..5b3f63935f 100644
--- a/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.info.yml
@@ -1,15 +1,15 @@
-name: 'Webform module translation tests'
+name: 'Webform Translation test'
 type: module
-description: 'Support module for Webform module translation testing that provides working examples for translating webforms.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform translation testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:config_translation'
   - 'drupal:language'
   - 'drupal:locale'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.install b/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.install
index a1ba31c7bf..dc3f42fb5a 100644
--- a/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.install
+++ b/web/modules/webform/tests/modules/webform_test_translation/webform_test_translation.install
@@ -4,7 +4,7 @@
  * @file
  * Install, update and uninstall functions for the Webform test translation module.
  *
- * drush php-eval 'module_load_include('install', 'webform_test_translation');webform_test_translation_install()'; drush cr;
+ * drush php-eval 'module_load_include('install', 'webform_test_translation'); webform_test_translation_install()'; drush cr;
  */
 
 use Drupal\Core\Serialization\Yaml;
diff --git a/web/modules/webform/tests/modules/webform_test_translation_lingotek/webform_test_translation_lingotek.info.yml b/web/modules/webform/tests/modules/webform_test_translation_lingotek/webform_test_translation_lingotek.info.yml
index e8d1a0673d..3f0613b655 100644
--- a/web/modules/webform/tests/modules/webform_test_translation_lingotek/webform_test_translation_lingotek.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_translation_lingotek/webform_test_translation_lingotek.info.yml
@@ -1,8 +1,8 @@
-name: 'Webform module translation lingotek tests'
+name: 'Webform Translation Lingotek test'
 type: module
-description: 'Support module for Webform module translatation using Lingotek.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform Lingotek integration testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:config_translation'
   - 'drupal:language'
@@ -10,7 +10,7 @@ dependencies:
   - 'lingotek:lingotek'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_validate/webform_test_validate.info.yml b/web/modules/webform/tests/modules/webform_test_validate/webform_test_validate.info.yml
index d00670625b..514dbc79d7 100644
--- a/web/modules/webform/tests/modules/webform_test_validate/webform_test_validate.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_validate/webform_test_validate.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module validate tests'
+name: 'Webform Validate test'
 type: module
-description: 'Support module for webform that provides form validate hooks for form validate tests.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform validate testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_variant/webform_test_variant.info.yml b/web/modules/webform/tests/modules/webform_test_variant/webform_test_variant.info.yml
index d18d2abcdb..719a4ec99b 100644
--- a/web/modules/webform/tests/modules/webform_test_variant/webform_test_variant.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_variant/webform_test_variant.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module variant tests'
+name: 'Webform Variant test'
 type: module
-description: 'Support module for webform that provides variant plugin tests.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform variant plugin testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_views/webform_test_views.info.yml b/web/modules/webform/tests/modules/webform_test_views/webform_test_views.info.yml
index f441f72086..a64713aea5 100644
--- a/web/modules/webform/tests/modules/webform_test_views/webform_test_views.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_views/webform_test_views.info.yml
@@ -1,15 +1,15 @@
-name: 'Webform module Views tests'
+name: 'Webform Views test'
 type: module
-description: 'Support module for Webform that provides working examples for Views integration.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform views integration testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'drupal:node'
   - 'drupal:user'
   - 'drupal:views'
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/modules/webform_test_wizard_custom/webform_test_wizard_custom.info.yml b/web/modules/webform/tests/modules/webform_test_wizard_custom/webform_test_wizard_custom.info.yml
index 0dd680d880..de9678e5ff 100644
--- a/web/modules/webform/tests/modules/webform_test_wizard_custom/webform_test_wizard_custom.info.yml
+++ b/web/modules/webform/tests/modules/webform_test_wizard_custom/webform_test_wizard_custom.info.yml
@@ -1,12 +1,12 @@
-name: 'Webform module wizard custom tests'
+name: 'Webform Wizard Custom test'
 type: module
-description: 'Support module for webform that provides form alter hook for wizard custom tests.'
-package: Testing
-core_version_requirement: ^8.7.7 || ^9
+description: 'Support module for webform for wizard customization testing.'
+package: 'Webform Testing'
+core_version_requirement: ^8.8
 dependencies:
   - 'webform:webform'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityJsonApiTest.php b/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityJsonApiTest.php
index 83c5183c2e..e774599a8a 100644
--- a/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityJsonApiTest.php
+++ b/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityJsonApiTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform entity JSON API access.
  *
- * @group Webform
+ * @group webform
  */
 class WebformAccessEntityJsonApiTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityPermissionsTest.php b/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityPermissionsTest.php
index 26ddb746ff..ad502edbc7 100644
--- a/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityPermissionsTest.php
+++ b/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityPermissionsTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform entity permissions.
  *
- * @group Webform
+ * @group webform
  */
 class WebformAccessEntityPermissionsTest extends WebformBrowserTestBase {
 
@@ -42,14 +42,14 @@ public function testAccessControlHandler() {
     $this->drupalLogin($own_account);
 
     // Check create own webform.
-    $this->drupalPostForm('/admin/structure/webform/add', ['id' => 'test_own', 'title' => 'test_own'], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/add', ['id' => 'test_own', 'title' => 'test_own'], 'Save');
 
     // Check webform submission overview contains own webform.
     $this->drupalGet('/admin/structure/webform');
     $this->assertRaw('test_own');
 
     // Add test element to own webform.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_own', ['elements' => "test:\n  '#markup': 'test'"], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_own', ['elements' => "test:\n  '#markup': 'test'"], 'Save');
 
     // Check duplicate own webform.
     $this->drupalGet('/admin/structure/webform/manage/test_own/duplicate');
diff --git a/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityRestTest.php b/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityRestTest.php
index 4d03479e8a..a5527bf991 100644
--- a/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityRestTest.php
+++ b/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityRestTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform entity REST access.
  *
- * @group Webform
+ * @group webform
  */
 class WebformAccessEntityRestTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityRulesTest.php b/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityRulesTest.php
index 717045cac1..933f886bc2 100644
--- a/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityRulesTest.php
+++ b/web/modules/webform/tests/src/Functional/Access/WebformAccessEntityRulesTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform entity access rules.
  *
- * @group Webform
+ * @group webform
  */
 class WebformAccessEntityRulesTest extends WebformBrowserTestBase {
 
@@ -275,7 +275,7 @@ public function testAccessRules() {
       $path = str_replace('{webform_submission}', $sid, $path);
 
       $this->drupalGet($path);
-      $this->assertResponse($status_code, new FormattableMarkup('Webform @status_code access via own access rules.', ['@status_code' => ($status_code == 403 ? 'denies' : 'allows')]));
+      $this->assertResponse($status_code, new FormattableMarkup('Webform @status_code access via own access rules.', ['@status_code' => ($status_code === 403 ? 'denies' : 'allows')]));
     }
 
     // Enable submission user duplicate.
diff --git a/web/modules/webform/tests/src/Functional/Access/WebformAccessSubmissionPermissionsTest.php b/web/modules/webform/tests/src/Functional/Access/WebformAccessSubmissionPermissionsTest.php
index 6334ddc6b4..017e153223 100644
--- a/web/modules/webform/tests/src/Functional/Access/WebformAccessSubmissionPermissionsTest.php
+++ b/web/modules/webform/tests/src/Functional/Access/WebformAccessSubmissionPermissionsTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform submission permissions.
  *
- * @group Webform
+ * @group webform
  */
 class WebformAccessSubmissionPermissionsTest extends WebformBrowserTestBase {
 
@@ -233,7 +233,6 @@ public function testPermissions() {
     // Check user can the submissions when they are the webform owner.
     $this->drupalGet("admin/structure/webform/manage/{$webform_id}/submission/{$sid_4}");
     $this->assertResponse(200);
-
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Block/WebformBlockContextTest.php b/web/modules/webform/tests/src/Functional/Block/WebformBlockContextTest.php
index 6f2a1c9ae9..4e9d71babe 100644
--- a/web/modules/webform/tests/src/Functional/Block/WebformBlockContextTest.php
+++ b/web/modules/webform/tests/src/Functional/Block/WebformBlockContextTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform block context.
  *
- * @group Webform
+ * @group webform
  */
 class WebformBlockContextTest extends WebformBrowserTestBase {
 
@@ -22,7 +22,7 @@ class WebformBlockContextTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Manually install blocks.
diff --git a/web/modules/webform/tests/src/Functional/Block/WebformBlockTest.php b/web/modules/webform/tests/src/Functional/Block/WebformBlockTest.php
index a827daa32b..699ca4bb0b 100644
--- a/web/modules/webform/tests/src/Functional/Block/WebformBlockTest.php
+++ b/web/modules/webform/tests/src/Functional/Block/WebformBlockTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform block.
  *
- * @group Webform
+ * @group webform
  */
 class WebformBlockTest extends WebformBrowserTestBase {
 
@@ -48,20 +48,20 @@ public function testBlock() {
     // Check confirmation inline webform.
     $block->getPlugin()->setConfigurationValue('webform_id', 'test_confirmation_inline');
     $block->save();
-    $this->drupalPostForm('/<front>', [], t('Submit'));
+    $this->drupalPostForm('/<front>', [], 'Submit');
     $this->assertRaw('This is a custom inline confirmation message.');
 
     // Check confirmation message webform displayed on front page.
     $block->getPlugin()->setConfigurationValue('webform_id', 'test_confirmation_message');
     $block->save();
-    $this->drupalPostForm('/<front>', [], t('Submit'));
+    $this->drupalPostForm('/<front>', [], 'Submit');
     $this->assertRaw('This is a <b>custom</b> confirmation message.');
     $this->assertUrl('/user/login');
 
     // Check confirmation message webform display on webform URL.
     $block->getPlugin()->setConfigurationValue('redirect', TRUE);
     $block->save();
-    $this->drupalPostForm('/<front>', [], t('Submit'));
+    $this->drupalPostForm('/<front>', [], 'Submit');
     $this->assertRaw('This is a <b>custom</b> confirmation message.');
     $this->assertUrl('webform/test_confirmation_message');
 
diff --git a/web/modules/webform/tests/src/Functional/Composite/WebformCompositeCustomFileTest.php b/web/modules/webform/tests/src/Functional/Composite/WebformCompositeCustomFileTest.php
index 80f7ff5ecf..53e4ce5cb9 100644
--- a/web/modules/webform/tests/src/Functional/Composite/WebformCompositeCustomFileTest.php
+++ b/web/modules/webform/tests/src/Functional/Composite/WebformCompositeCustomFileTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for custom composite element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformCompositeCustomFileTest extends WebformElementManagedFileTestBase {
 
@@ -37,13 +37,19 @@ public function testCustom() {
       'files[webform_custom_composite_file_items_0__item__managed_file]' => \Drupal::service('file_system')->realpath($first_file->uri),
     ];
     $sid = $this->postSubmission($webform, $edit);
+
     $webform_submission = WebformSubmission::load($sid);
 
     $fid = $this->getLastFileId();
+    /** @var \Drupal\file\FileInterface $file */
     $file = File::load($fid);
 
+    // Check the composite file is attached to the email.
+    $this->assertRaw('<label>Attachments</label>');
+    $this->assertRaw('<strong><a href="' . file_create_url($file->getFileUri()) . '">' . $file->getFileName() . '</a></strong> (text/plain) - 1 KB');
+
     // Check file permanent.
-    $this->assert($file->isPermanent(), 'Test file is permanent');
+    $this->assertTrue($file->isPermanent());
 
     // Check file upload.
     $element_data = $webform_submission->getElementData('webform_custom_composite_file');
@@ -56,7 +62,7 @@ public function testCustom() {
     $this->assertEqual($file->getFileUri(), 'private://webform/test_composite_custom_file/' . $sid . '/' . $first_file->filename);
 
     // Check that test file exists.
-    $this->assert(file_exists($file->getFileUri()), 'File exists');
+    $this->assertFileExists($file->getFileUri());
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Composite/WebformCompositeCustomTest.php b/web/modules/webform/tests/src/Functional/Composite/WebformCompositeCustomTest.php
index 4af0aa2d2b..c41885ac65 100644
--- a/web/modules/webform/tests/src/Functional/Composite/WebformCompositeCustomTest.php
+++ b/web/modules/webform/tests/src/Functional/Composite/WebformCompositeCustomTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for custom composite element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformCompositeCustomTest extends WebformBrowserTestBase {
 
@@ -42,7 +42,7 @@ public function testCustom() {
     /* Processing */
 
     // Check contact composite value.
-    $this->drupalPostForm('/webform/test_composite_custom', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_composite_custom', [], 'Submit');
     $this->assertRaw("webform_custom_composite_basic:
   - first_name: John
     last_name: Smith
diff --git a/web/modules/webform/tests/src/Functional/Composite/WebformCompositeFormatTest.php b/web/modules/webform/tests/src/Functional/Composite/WebformCompositeFormatTest.php
index 277e699f16..72c822fba0 100644
--- a/web/modules/webform/tests/src/Functional/Composite/WebformCompositeFormatTest.php
+++ b/web/modules/webform/tests/src/Functional/Composite/WebformCompositeFormatTest.php
@@ -11,7 +11,7 @@
 /**
  * Tests for webform submission webform element custom #format support.
  *
- * @group Webform
+ * @group webform
  */
 class WebformCompositeFormatTest extends WebformBrowserTestBase {
 
@@ -63,7 +63,7 @@ public function testFormat() {
       'Link (Value)' => '<a href="http://example.com">Loremipsum</a>',
     ];
     foreach ($elements as $label => $value) {
-      $this->assertContains('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', ['@label' => $label, '@value' => $value]));
+      $this->assertStringContainsString('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', ['@label' => $label, '@value' => $value]));
     }
 
     // Check composite elements formatted as text.
@@ -133,7 +133,7 @@ public function testFormat() {
 Language code: en',
     ];
     foreach ($elements as $value) {
-      $this->assertContains($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
+      $this->assertStringContainsString($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
     }
 
     /**************************************************************************/
@@ -160,7 +160,7 @@ public function testFormat() {
       'Basic address (Table)' => '<table width="100%" cellspacing="0" cellpadding="5" border="1" class="responsive-enabled" data-striping="1"><thead><tr><th bgcolor="#eee">Address</th><th bgcolor="#eee">Address 2</th><th bgcolor="#eee">City/Town</th><th bgcolor="#eee">State/Province</th><th bgcolor="#eee">ZIP/Postal Code</th><th bgcolor="#eee">Country</th></tr></thead><tbody><tr class="odd"><td>10 Main Street</td><td>10 Main Street</td><td>Springfield</td><td>Alabama</td><td>11111</td><td>Afghanistan</td></tr><tr class="even"><td>10 Main Street</td><td>10 Main Street</td><td>Springfield</td><td>Alabama</td><td>11111</td><td>Afghanistan</td></tr><tr class="odd"><td>10 Main Street</td><td>10 Main Street</td><td>Springfield</td><td>Alabama</td><td>11111</td><td>Afghanistan</td></tr></tbody></table>',
     ];
     foreach ($elements as $label => $value) {
-      $this->assertContains('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', ['@label' => $label, '@value' => $value]));
+      $this->assertStringContainsString('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', ['@label' => $label, '@value' => $value]));
     }
 
     // Check composite elements formatted as text.
@@ -209,7 +209,7 @@ public function testFormat() {
 Afghanistan',
     ];
     foreach ($elements as $value) {
-      $this->assertContains($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
+      $this->assertStringContainsString($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
     }
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Composite/WebformCompositePluginFileTest.php b/web/modules/webform/tests/src/Functional/Composite/WebformCompositePluginFileTest.php
index 6ce77b4729..2533f5a7c0 100644
--- a/web/modules/webform/tests/src/Functional/Composite/WebformCompositePluginFileTest.php
+++ b/web/modules/webform/tests/src/Functional/Composite/WebformCompositePluginFileTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for composite plugin file upload.
  *
- * @group Webform
+ * @group webform
  */
 class WebformCompositePluginFileTest extends WebformElementManagedFileTestBase {
 
@@ -53,7 +53,7 @@ public function testPlugin() {
     $file = File::load($fid);
 
     // Check file permanent.
-    $this->assert($file->isPermanent(), 'Test file is permanent');
+    $this->assertTrue($file->isPermanent());
 
     // Check file upload.
     $element_data = $webform_submission->getElementData('webform_test_composite_file');
@@ -66,7 +66,7 @@ public function testPlugin() {
     $this->assertEqual($file->getFileUri(), 'private://webform/test_element_comp_file_plugin/' . $sid . '/' . $first_file->filename);
 
     // Check that test file exists.
-    $this->assert(file_exists($file->getFileUri()), 'File exists');
+    $this->assertFileExists($file->getFileUri());
 
     /**************************************************************************/
     // Multiple composite with file upload.
@@ -84,7 +84,7 @@ public function testPlugin() {
     $file = File::load($fid);
 
     // Check file permanent.
-    $this->assert($file->isPermanent(), 'Test file is permanent');
+    $this->assertTrue($file->isPermanent());
 
     // Check file upload.
     $element_data = $webform_submission->getElementData('webform_test_composite_file_multiple_header');
@@ -97,7 +97,7 @@ public function testPlugin() {
     $this->assertEqual($file->getFileUri(), 'private://webform/test_element_comp_file_plugin/' . $sid . '/' . $second_file->filename);
 
     // Check that test file exists.
-    $this->assert(file_exists($file->getFileUri()), 'File exists');
+    $this->assertFileExists($file->getFileUri());
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Composite/WebformCompositePluginTest.php b/web/modules/webform/tests/src/Functional/Composite/WebformCompositePluginTest.php
index d79c72e5be..5e1e8abb8f 100644
--- a/web/modules/webform/tests/src/Functional/Composite/WebformCompositePluginTest.php
+++ b/web/modules/webform/tests/src/Functional/Composite/WebformCompositePluginTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for composite plugin.
  *
- * @group Webform
+ * @group webform
  */
 class WebformCompositePluginTest extends WebformBrowserTestBase {
 
@@ -63,7 +63,7 @@ public function testPlugin() {
       'webform_test_composite[nested_select]' => 'Monday',
       'webform_test_composite[nested_radios]' => 'Monday',
     ];
-    $this->drupalPostForm('/webform/test_element_composite_plugin', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_composite_plugin', $edit, 'Submit');
     $this->assertRaw("webform_test_composite:
   textfield: '{textfield}'
   email: email@email.com
diff --git a/web/modules/webform/tests/src/Functional/Composite/WebformCompositeTest.php b/web/modules/webform/tests/src/Functional/Composite/WebformCompositeTest.php
index 053eba9f2c..d0ecf70352 100644
--- a/web/modules/webform/tests/src/Functional/Composite/WebformCompositeTest.php
+++ b/web/modules/webform/tests/src/Functional/Composite/WebformCompositeTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for composite elements.
  *
- * @group Webform
+ * @group webform
  */
 class WebformCompositeTest extends WebformBrowserTestBase {
 
@@ -59,7 +59,7 @@ public function testComposite() {
     /* Processing */
 
     // Check contact composite value.
-    $this->drupalPostForm('/webform/test_composite', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_composite', [], 'Submit');
     $this->assertRaw("contact_basic:
   name: 'John Smith'
   company: Acme
@@ -76,7 +76,7 @@ public function testComposite() {
     $edit = [
       'contact_basic[name]' => '',
     ];
-    $this->drupalPostForm('/webform/test_composite', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_composite', $edit, 'Submit');
     $this->assertRaw('Name field is required.');
 
     /* Custom options */
@@ -93,7 +93,7 @@ public function testComposite() {
     $this->assertRaw('<em>Custom options can only be updated via the <a href="' . base_path() . 'admin/structure/webform/manage/test_composite/source">YAML source</a>.</em>');
 
     // Save composite element with custom options.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_composite/element/address_custom_options/edit', [], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_composite/element/address_custom_options/edit', [], 'Save');
 
     // Check editing custom options are not removed.
     $this->drupalGet('/webform/test_composite');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementAccessTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementAccessTest.php
index a22eca851d..a761172505 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementAccessTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementAccessTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform element access.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementAccessTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementActionsTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementActionsTest.php
index ab1bbf464b..52666aa83d 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementActionsTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementActionsTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform actions element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementActionsTest extends WebformElementBrowserTestBase {
 
@@ -42,14 +42,14 @@ public function testActions() {
     $this->assertNoRaw('id="edit-actions-wizard-prev-wizard-prev"');
 
     // Move to next page.
-    $this->drupalPostForm(NULL, [], t('Next Page >'));
+    $this->drupalPostForm(NULL, [], 'Next >');
 
     // Check no wizard next.
     $this->assertNoRaw('id="edit-actions-wizard-next-wizard-next"');
     $this->assertRaw('id="edit-actions-wizard-prev-wizard-prev"');
 
     // Move to preview.
-    $this->drupalPostForm(NULL, [], t('Preview'));
+    $this->drupalPostForm(NULL, [], 'Preview');
 
     // Check submit button.
     $this->assertRaw('id="edit-actions-submit-submit"');
@@ -58,7 +58,7 @@ public function testActions() {
     $this->assertRaw('id="edit-actions-reset-reset"');
 
     // Submit form.
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm(NULL, [], 'Submit');
     $sid = $this->getLastSubmissionId($webform);
 
     // Check no actions.
@@ -67,7 +67,7 @@ public function testActions() {
     // Check custom update action.
     $this->drupalLogin($this->rootUser);
     $this->drupalGet("/admin/structure/webform/manage/test_element_actions/submission/$sid/edit");
-    $this->drupalPostForm(NULL, [], t('Next Page >'));
+    $this->drupalPostForm(NULL, [], 'Next >');
     $this->assertRaw('<input class="webform-button--submit custom-update button button--primary js-form-submit form-submit" style="font-weight: bold" data-custom-update data-drupal-selector="edit-actions-custom-submit" type="submit" id="edit-actions-custom-submit" name="op" value="{Custom update}" />');
 
     /**************************************************************************/
@@ -83,28 +83,28 @@ public function testActions() {
     // Check draft button.
     $this->assertRaw('<input formnovalidate="formnovalidate" class="webform-button--draft draft_button_attributes button js-form-submit form-submit" style="color: blue" data-drupal-selector="edit-actions-draft" type="submit" id="edit-actions-draft" name="op" value="Save Draft" />');
     // Check next button.
-    $this->assertRaw('<input class="webform-button--next wizard_next_button_attributes button js-form-submit form-submit" style="color: yellow" data-drupal-selector="edit-actions-wizard-next" type="submit" id="edit-actions-wizard-next" name="op" value="Next Page &gt;" />');
+    $this->assertRaw('<input class="webform-button--next wizard_next_button_attributes button js-form-submit form-submit" style="color: yellow" data-drupal-selector="edit-actions-wizard-next" type="submit" id="edit-actions-wizard-next" name="op" value="Next &gt;" />');
 
-    $this->drupalPostForm('/webform/test_element_actions_buttons', [], t('Next Page >'));
+    $this->drupalPostForm('/webform/test_element_actions_buttons', [], 'Next >');
 
     // Check previous button.
-    $this->assertRaw('<input formnovalidate="formnovalidate" class="webform-button--previous wizard_prev_button_attributes button js-form-submit form-submit" style="color: yellow" data-drupal-selector="edit-actions-wizard-prev" type="submit" id="edit-actions-wizard-prev" name="op" value="&lt; Previous Page" />');
+    $this->assertRaw('<input formnovalidate="formnovalidate" class="webform-button--previous wizard_prev_button_attributes button js-form-submit form-submit" style="color: yellow" data-drupal-selector="edit-actions-wizard-prev" type="submit" id="edit-actions-wizard-prev" name="op" value="&lt; Previous" />');
     // Check preview button.
     $this->assertRaw('<input class="webform-button--preview preview_next_button_attributes button js-form-submit form-submit" style="color: orange" data-drupal-selector="edit-actions-preview-next" type="submit" id="edit-actions-preview-next" name="op" value="Preview" />');
 
-    $this->drupalPostForm(NULL, [], t('Preview'));
+    $this->drupalPostForm(NULL, [], 'Preview');
 
     // Check previous button.
     $this->assertRaw('<input formnovalidate="formnovalidate" class="webform-button--previous preview_prev_button_attributes button js-form-submit form-submit" style="color: orange" data-drupal-selector="edit-actions-preview-prev" type="submit" id="edit-actions-preview-prev" name="op" value="&lt; Previous" />');
     // Check submit button.
     $this->assertRaw('<input class="webform-button--submit form_submit_attributes button button--primary js-form-submit form-submit" style="color: green" data-drupal-selector="edit-actions-submit" type="submit" id="edit-actions-submit" name="op" value="Submit" />');
 
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm(NULL, [], 'Submit');
     $sid = $this->getLastSubmissionId($webform);
 
     // Check update button.
     $this->drupalGet("/admin/structure/webform/manage/test_element_actions_buttons/submission/$sid/edit");
-    $this->drupalPostForm(NULL, [], t('Next Page >'));
+    $this->drupalPostForm(NULL, [], 'Next >');
     $this->assertRaw('<input class="webform-button--submit form_update_attributes button button--primary js-form-submit form-submit" style="color: purple" data-drupal-selector="edit-actions-submit" type="submit" id="edit-actions-submit" name="op" value="Save" />');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementAddressTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementAddressTest.php
index 6407a51669..5f0ad8a71c 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementAddressTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementAddressTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform address element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementAddressTest extends WebformElementBrowserTestBase {
 
@@ -47,7 +47,12 @@ public function testAddress() {
     // Check advanced fieldset, legend, help, and description.
     $this->assertRaw('<fieldset data-drupal-selector="edit-address-advanced" aria-describedby="edit-address-advanced--wrapper--description" id="edit-address-advanced--wrapper" class="address--wrapper fieldgroup form-composite webform-composite-visible-title webform-element-help-container--title webform-element-help-container--title-after js-webform-type-address webform-type-address js-form-item form-item js-form-wrapper form-wrapper">');
     $this->assertRaw('<span class="fieldset-legend">address_advanced<span class="webform-element-help" role="tooltip" tabindex="0" data-webform-help="&lt;div class=&quot;webform-element-help--title&quot;&gt;address_advanced&lt;/div&gt;&lt;div class=&quot;webform-element-help--content&quot;&gt;This is help text&lt;/div&gt;"><span aria-hidden="true">?</span></span>');
-    $this->assertRaw('<div class="description"><div id="edit-address-advanced--wrapper--description" class="webform-element-description">This is a description</div>');
+    if (floatval(\Drupal::VERSION) >= 9) {
+      $this->assertRaw('<div class="description"><div id="edit-address-advanced--wrapper--description" data-drupal-field-elements="description" class="webform-element-description">This is a description</div>');
+    }
+    else {
+      $this->assertRaw('<div class="description"><div id="edit-address-advanced--wrapper--description" class="webform-element-description">This is a description</div>');
+    }
 
     /**************************************************************************/
     // Processing.
@@ -144,7 +149,7 @@ public function testAddress() {
     $composite_elements = $element['#webform_composite_elements'];
     $diff_composite_elements = array_diff_key($composite_elements, $schema['columns']);
     $this->debug($diff_composite_elements);
-    $this->assert(empty($diff_composite_elements));
+    $this->assertEmpty($diff_composite_elements);
 
     // Check composite elements maxlength against address schema.
     foreach ($schema['columns'] as $column_name => $column) {
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementAllowsTagsTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementAllowsTagsTest.php
index 0346ed35f1..0468ec1bc1 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementAllowsTagsTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementAllowsTagsTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for element allowed tags.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementAllowsTagsTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementAttributesTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementAttributesTest.php
index 355b84a770..c72d5f1ce4 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementAttributesTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementAttributesTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform element attributes.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementAttributesTest extends WebformElementBrowserTestBase {
 
@@ -21,7 +21,7 @@ class WebformElementAttributesTest extends WebformElementBrowserTestBase {
    */
   public function testAttributes() {
     // Check default value handling.
-    $this->drupalPostForm('/webform/test_element_attributes', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_attributes', [], 'Submit');
     $this->assertRaw("webform_element_attributes:
   class:
     - one
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementAutocompleteTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementAutocompleteTest.php
index c2ad5ac100..802940100a 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementAutocompleteTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementAutocompleteTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform autocomplete element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementAutocompleteTest extends WebformElementBrowserTestBase {
 
@@ -45,13 +45,7 @@ public function testAutocomplete() {
 
     // Check #autocomplete_items just one character.
     $this->drupalGet('/webform/test_element_autocomplete/autocomplete/autocomplete_items', ['query' => ['q' => 'U']]);
-    // @todo Remove once Drupal 8.8.x is only supported.
-    if (floatval(\Drupal::VERSION) >= 8.8) {
-      $this->assertRaw('[{"value":"Anguilla","label":"Anguilla"},{"value":"Antigua \u0026 Barbuda","label":"Antigua \u0026 Barbuda"},{"value":"Aruba","label":"Aruba"},{"value":"Australia","label":"Australia"},{"value":"Austria","label":"Austria"}]');
-    }
-    else {
-      $this->assertRaw('[{"value":"Anguilla","label":"Anguilla"},{"value":"Antigua and Barbuda","label":"Antigua and Barbuda"},{"value":"Aruba","label":"Aruba"},{"value":"Australia","label":"Australia"},{"value":"Austria","label":"Austria"}]');
-    }
+    $this->assertRaw('[{"value":"Anguilla","label":"Anguilla"},{"value":"Antigua \u0026 Barbuda","label":"Antigua \u0026 Barbuda"},{"value":"Aruba","label":"Aruba"},{"value":"Australia","label":"Australia"},{"value":"Austria","label":"Austria"}]');
 
     /* Test #autocomplete_existing element property */
 
@@ -65,7 +59,7 @@ public function testAutocomplete() {
     $this->assertRaw('[]');
 
     // Add #autocomplete_existing values to the submission table.
-    $this->drupalPostForm('/webform/test_element_autocomplete', ['autocomplete_existing' => 'abcdefg'], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_autocomplete', ['autocomplete_existing' => 'abcdefg'], 'Submit');
 
     // Check #autocomplete_existing enabled now that there is submission.
     $this->drupalGet('/webform/test_element_autocomplete');
@@ -85,7 +79,7 @@ public function testAutocomplete() {
     /* Test #autocomplete_existing and #autocomplete_items element property */
 
     // Add #autocomplete_body values to the submission table.
-    $this->drupalPostForm('/webform/test_element_autocomplete', ['autocomplete_both' => 'Existing Item'], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_autocomplete', ['autocomplete_both' => 'Existing Item'], 'Submit');
 
     // Check #autocomplete_both match.
     $this->drupalGet('/webform/test_element_autocomplete/autocomplete/autocomplete_both', ['query' => ['q' => 'Item']]);
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementCaptchaTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementCaptchaTest.php
index 7c91274fff..4f32411bf4 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementCaptchaTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementCaptchaTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for CAPTCHA element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementCaptchaTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxTest.php
index c34112c2d4..13f69dd056 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform checkbox element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementCheckboxTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxValueTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxValueTest.php
index 16b8937d7d..2f437342d4 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxValueTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxValueTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform checkbox value element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementCheckboxValueTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxesTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxesTest.php
index 75319d1a0d..1b5ca0d4c7 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxesTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementCheckboxesTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform checkboxes element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementCheckboxesTest extends WebformElementBrowserTestBase {
 
@@ -31,6 +31,12 @@ public function testCheckboxes() {
     $this->assertRaw('<input data-drupal-selector="edit-checkboxes-buttons-yes" class="visually-hidden form-checkbox" type="checkbox" id="edit-checkboxes-buttons-yes" name="checkboxes_buttons[Yes]" value="Yes" />');
     $this->assertRaw('<label class="webform-options-display-buttons-label option" for="edit-checkboxes-buttons-yes">Yes</label>');
 
+    // Check checkboxes displayed as buttons_horizontal.
+    $this->assertRaw('<div id="edit-checkboxes-buttons-horizontal" class="js-webform-checkboxes webform-options-display-buttons webform-options-display-buttons-horizontal form-checkboxes"><div class="webform-options-display-buttons-wrapper">');
+
+    // Check checkboxes displayed as buttons_vertical.
+    $this->assertRaw('<div id="edit-checkboxes-buttons-vertical" class="js-webform-checkboxes webform-options-display-buttons webform-options-display-buttons-vertical form-checkboxes"><div class="webform-options-display-buttons-wrapper">');
+
     // Check checkboxes displayed as buttons with description.
     $this->assertRaw('<label class="webform-options-display-buttons-label option" for="edit-checkboxes-buttons-description-one"><div class="webform-options-display-buttons-title">One</div><div class="webform-options-display-buttons-description description">This is a description</div></label>');
 
@@ -51,7 +57,7 @@ public function testCheckboxes() {
       'checkboxes_required_conditions[Yes]' => TRUE,
       'checkboxes_other_required_conditions[checkboxes][Yes]' => TRUE,
     ];
-    $this->postSubmission($webform, $edit, t('Preview'));
+    $this->postSubmission($webform, $edit, 'Preview');
     $this->assertNoRaw('<label>checkbox_exclude_empty</label>');
 
     // Uncheck #exclude_empty.
@@ -63,7 +69,7 @@ public function testCheckboxes() {
       'checkboxes_required_conditions[Yes]' => TRUE,
       'checkboxes_other_required_conditions[checkboxes][Yes]' => TRUE,
     ];
-    $this->postSubmission($webform, $edit, t('Preview'));
+    $this->postSubmission($webform, $edit, 'Preview');
     $this->assertRaw('<label>checkbox_exclude_empty</label>');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementCodeMirrorTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementCodeMirrorTest.php
index f8c8a2e085..8f94112442 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementCodeMirrorTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementCodeMirrorTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform CodeMirror element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementCodeMirrorTest extends WebformElementBrowserTestBase {
 
@@ -45,7 +45,7 @@ public function testCodeMirror() {
     $this->assertRaw('<textarea data-drupal-selector="edit-yaml-basic" class="js-webform-codemirror webform-codemirror yaml form-textarea resize-vertical" data-webform-codemirror-mode="text/x-yaml" id="edit-yaml-basic" name="yaml_basic" rows="5" cols="60">test: hello</textarea>');
 
     // Check default value decoding.
-    $this->drupalPostForm('/webform/test_element_codemirror', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_codemirror', [], 'Submit');
     $this->assertRaw("yaml_basic: 'test: hello'
 yaml_array:
   one: One
@@ -58,14 +58,14 @@ public function testCodeMirror() {
     $edit = [
       'yaml_basic' => "'not: valid",
     ];
-    $this->drupalPostForm('/webform/test_element_codemirror', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_codemirror', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">yaml_basic</em> is not valid.');
 
     // Check valid YAML.
     $edit = [
       'yaml_basic' => 'is: valid',
     ];
-    $this->drupalPostForm('/webform/test_element_codemirror', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_codemirror', $edit, 'Submit');
     $this->assertNoRaw('<em class="placeholder">yaml_basic</em> is not valid.');
 
     /**************************************************************************/
@@ -81,7 +81,7 @@ public function testCodeMirror() {
     $edit = [
       'html_basic' => "<b>bold</bold>",
     ];
-    $this->drupalPostForm('/webform/test_element_codemirror', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_codemirror', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">html_basic</em> is not valid.');
     $this->assertRaw('expected &#039;&gt;&#039;');
 
@@ -89,7 +89,7 @@ public function testCodeMirror() {
     $edit = [
       'html_basic' => '<b>bold</b>',
     ];
-    $this->drupalPostForm('/webform/test_element_codemirror', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_codemirror', $edit, 'Submit');
     $this->assertNoRaw('<em class="placeholder">html_basic</em> is not valid.');
     $this->assertNoRaw('expected &#039;&gt;&#039;');
 
@@ -119,14 +119,14 @@ public function testCodeMirror() {
     $edit = [
       'twig_basic' => 'Can edit Twig template.',
     ];
-    $this->drupalPostForm('/webform/test_element_codemirror', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_codemirror', $edit, 'Submit');
     $this->assertRaw('Can edit Twig template.');
 
     // Check invalid Twig syntax.
     $edit = [
       'twig_basic' => "{{ value ",
     ];
-    $this->drupalPostForm('/webform/test_element_codemirror', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_codemirror', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">twig_basic</em> is not valid.');
     $this->assertRaw('Unclosed &quot;variable&quot; in');
   }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementCompositeTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementCompositeTest.php
index c8dd74fc07..9f70012a18 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementCompositeTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementCompositeTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for composite element (builder).
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementCompositeTest extends WebformElementBrowserTestBase {
 
@@ -131,7 +131,12 @@ public function testComposite() {
 
     // Check radios 'aria-describedby' with wrapper description.
     $this->assertRaw('<input data-drupal-selector="edit-radios-wrapper-fieldset-description-one" aria-describedby="edit-radios-wrapper-fieldset-description--wrapper--description" type="radio" id="edit-radios-wrapper-fieldset-description-one" name="radios_wrapper_fieldset_description" value="One" class="form-radio" />');
-    $this->assertRaw('<div class="description"><div id="edit-radios-wrapper-fieldset-description--wrapper--description" class="webform-element-description">This is a description</div>');
+    if (floatval(\Drupal::VERSION) >= 9) {
+      $this->assertRaw('<div class="description"><div id="edit-radios-wrapper-fieldset-description--wrapper--description" data-drupal-field-elements="description" class="webform-element-description">This is a description</div>');
+    }
+    else {
+      $this->assertRaw('<div class="description"><div id="edit-radios-wrapper-fieldset-description--wrapper--description" class="webform-element-description">This is a description</div>');
+    }
 
     // Check wrapper with #states.
     $this->assertRaw('<fieldset data-drupal-selector="edit-states-fieldset" class="js-webform-states-hidden radios--wrapper fieldgroup form-composite webform-composite-visible-title js-webform-type-radios webform-type-radios js-form-item form-item js-form-wrapper form-wrapper" id="edit-states-fieldset--wrapper" data-drupal-states="{&quot;visible&quot;:{&quot;.webform-submission-test-element-composite-wrapper-add-form :input[name=\u0022states_checkbox\u0022]&quot;:{&quot;checked&quot;:true}}}">');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementComputedTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementComputedTest.php
index 4f8ac7c576..cc3cbe2996 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementComputedTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementComputedTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for computed elements.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementComputedTest extends WebformElementBrowserTestBase {
 
@@ -33,7 +33,7 @@ class WebformElementComputedTest extends WebformElementBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create filters.
@@ -55,7 +55,7 @@ public function testComputedElement() {
     $this->assertRaw('<b class="webform_computed_token_auto">simple string:</b> This is a string<br />');
 
     // Get computed token preview.
-    $this->drupalPostForm('/webform/test_element_computed_token', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_element_computed_token', [], 'Preview');
 
     // Check token auto detection.
     $this->assertRaw('<b class="webform_computed_token_auto">simple string:</b> This is a string<br />');
@@ -94,7 +94,7 @@ public function testComputedElement() {
       ->condition('name', ['webform_computed_token_auto', 'webform_computed_token_html', 'webform_computed_token_text'], 'IN')
       ->execute()
       ->fetchAll();
-    $this->assert(empty($result));
+    $this->assertEmpty($result);
 
     /* Twig */
 
@@ -111,7 +111,7 @@ public function testComputedElement() {
     $this->assertFieldByName('webform_computed_twig_spaceless', '<em>This is spaceless</em><br/>');
 
     // Get computed Twig preview.
-    $this->drupalPostForm('/webform/test_element_computed_twig', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_element_computed_twig', [], 'Preview');
 
     // Check Twig auto detection.
     $this->assertRaw('<b class="webform_computed_twig_auto">number:</b> 2 * 2 = 4<br />');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementCounterTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementCounterTest.php
index 9bbd66851f..a63ecec082 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementCounterTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementCounterTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform (text) counter.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementCounterTest extends WebformElementBrowserTestBase {
 
@@ -38,7 +38,7 @@ public function testCounter() {
       'counter_words_min' => 'one two three',
       'counter_words_max' => 'one two three four five six seven eight nine ten eleven',
     ];
-    $this->drupalPostForm('/webform/test_element_counter', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_counter', $edit, 'Submit');
     $this->assertRaw('counter_characters_min (5) must be longer than <em class="placeholder">5</em> characters but is currently <em class="placeholder">3</em> characters long.');
     $this->assertRaw('counter_characters_max (10) cannot be longer than <em class="placeholder">10</em> characters but is currently <em class="placeholder">13</em> characters long.');
     $this->assertRaw('counter_words_min (5) must be longer than <em class="placeholder">5</em> words but is currently <em class="placeholder">3</em> words long.');
@@ -51,7 +51,7 @@ public function testCounter() {
       'counter_words_min' => 'one two three four five',
       'counter_words_max' => 'one two three four five six seven eight nine ten',
     ];
-    $this->drupalPostForm('/webform/test_element_counter', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_counter', $edit, 'Submit');
     $this->assertNoRaw('counter_characters_min (5) must be longer than <em class="placeholder">5</em> characters');
     $this->assertNoRaw('counter_characters_max (10) cannot be longer than <em class="placeholder">10</em> characters');
     $this->assertNoRaw('counter_words_min (5) must be longer than <em class="placeholder">5</em> words');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementDateListTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementDateListTest.php
index a679b80d85..59ac00b535 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementDateListTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementDateListTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform datelist element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementDateListTest extends WebformElementBrowserTestBase {
 
@@ -58,7 +58,7 @@ public function testDateListElement() {
 
     // Check 'datelist' and 'datetime' #default_value.
     $form = $webform->getSubmissionForm();
-    $this->assert($form['elements']['datelist_default']['#default_value'] instanceof DrupalDateTime, 'datelist_default #default_value instance of \Drupal\Core\Datetime\DrupalDateTime.');
+    $this->assertInstanceOf(DrupalDateTime::class, $form['elements']['datelist_default']['#default_value']);
 
     // Check datelist #date_date_max validation.
     $edit = [
@@ -66,7 +66,7 @@ public function testDateListElement() {
       'datelist_min_max[month]' => '8',
       'datelist_min_max[day]' => '18',
     ];
-    $this->drupalPostForm('/webform/test_element_datelist', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datelist', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">datelist_min_max</em> must be on or before <em class="placeholder">2009-12-31</em>.');
 
     // Check datelist #date_date_min validation.
@@ -75,7 +75,7 @@ public function testDateListElement() {
       'datelist_min_max[month]' => '8',
       'datelist_min_max[day]' => '18',
     ];
-    $this->drupalPostForm('/webform/test_element_datelist', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datelist', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">datelist_min_max</em> must be on or after <em class="placeholder">2009-01-01</em>.');
 
     // Check datelist #date_max validation.
@@ -85,7 +85,7 @@ public function testDateListElement() {
       'datelist_min_max_time[day]' => '31',
       'datelist_min_max_time[hour]' => '18',
     ];
-    $this->drupalPostForm('/webform/test_element_datelist', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datelist', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">datelist_min_max_time</em> must be on or before <em class="placeholder">2009-12-31 17:00:00</em>.');
 
     // Check datelist #date_min validation.
@@ -95,7 +95,7 @@ public function testDateListElement() {
       'datelist_min_max_time[day]' => '1',
       'datelist_min_max_time[hour]' => '8',
     ];
-    $this->drupalPostForm('/webform/test_element_datelist', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datelist', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">datelist_min_max_time</em> must be on or after <em class="placeholder">2009-01-01 09:00:00</em>.');
 
     // Check custom required error.
@@ -106,7 +106,7 @@ public function testDateListElement() {
       'datelist_required_error[hour]' => '',
       'datelist_required_error[minute]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_datelist', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datelist', $edit, 'Submit');
     $this->assertRaw('Custom required error');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementDateTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementDateTest.php
index d393c7ae96..41dc1cacf5 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementDateTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementDateTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform date element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementDateTest extends WebformElementBrowserTestBase {
 
@@ -46,21 +46,21 @@ public function testDateElement() {
 
     // Check 'datelist' and 'datetime' #default_value.
     $form = $webform->getSubmissionForm();
-    $this->assert(is_string($form['elements']['date_default']['#default_value']), 'date_default #default_value is a string.');
+    $this->assertIsString($form['elements']['date_default']['#default_value']);
 
     // Check date #max validation.
     $edit = ['date_min_max' => '2010-08-18'];
-    $this->drupalPostForm('/webform/test_element_date', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_date', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">date_min_max</em> must be on or before <em class="placeholder">2009-12-31</em>.');
 
     // Check date #min validation.
     $edit = ['date_min_max' => '2006-08-18'];
-    $this->drupalPostForm('/webform/test_element_date', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_date', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">date_min_max</em> must be on or after <em class="placeholder">2009-01-01</em>.');
 
     // Check date #date_days validation.
     $edit = ['date_datepicker_weekend' => '2010-08-18'];
-    $this->drupalPostForm('/webform/test_element_date', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_date', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">date_datepicker_weekend</em> must be a <em class="placeholder">Sunday or Saturday</em>.');
 
     // Check dynamic date.
@@ -76,7 +76,7 @@ public function testDateElement() {
     // Format date elements.
     /**************************************************************************/
 
-    $this->drupalPostForm('/webform/test_element_date', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_element_date', [], 'Preview');
 
     // Check date formats.
     $this->assertElementPreview('date_default', '2009-08-18');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementDateTimeTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementDateTimeTest.php
index 28410b626c..429334742c 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementDateTimeTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementDateTimeTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform datetime element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementDateTimeTest extends WebformElementBrowserTestBase {
 
@@ -45,10 +45,15 @@ public function testDateTime() {
 
     // Check datepicker and timepicker.
     $now_date = date('D, m/d/Y', strtotime('now'));
-    $this->assertRaw('<input data-drupal-selector="edit-datetime-datepicker-timepicker-date" title="Date (e.g. ' . $now_date . ')" type="text" min="Mon, 01/01/1900" max="Sat, 12/31/2050" data-drupal-date-format="D, m/d/Y" id="edit-datetime-datepicker-timepicker-date" name="datetime_datepicker_timepicker[date]" value="Tue, 08/18/2009" size="15" maxlength="128" class="form-text" />');
+    if (floatval(\Drupal::VERSION) >= 9) {
+      $this->assertRaw('<input data-drupal-selector="edit-datetime-datepicker-timepicker-date" title="Date (e.g. ' . $now_date . ')" type="text" min="Mon, 01/01/1900" max="Sat, 12/31/2050" data-drupal-date-format="D, m/d/Y" placeholder="YYYY-MM-DD" data-help="Enter the date using the format YYYY-MM-DD (e.g., ' . $now_date . ')." id="edit-datetime-datepicker-timepicker-date" name="datetime_datepicker_timepicker[date]" value="Tue, 08/18/2009" size="15" maxlength="128" class="form-text" />');
+    }
+    else {
+      $this->assertRaw('<input data-drupal-selector="edit-datetime-datepicker-timepicker-date" title="Date (e.g. ' . $now_date . ')" type="text" min="Mon, 01/01/1900" max="Sat, 12/31/2050" data-drupal-date-format="D, m/d/Y" id="edit-datetime-datepicker-timepicker-date" name="datetime_datepicker_timepicker[date]" value="Tue, 08/18/2009" size="15" maxlength="128" class="form-text" />');
+    }
     $this->assertRaw('<input data-drupal-selector="edit-datetime-datepicker-timepicker-time"');
     // Skip time which can change during the tests.
-    $this->assertRaw('type="text" step="1" data-webform-time-format="g:i A" id="edit-datetime-datepicker-timepicker-time" name="datetime_datepicker_timepicker[time]" value="4:00 PM" size="12" maxlength="12" class="form-time webform-time" />');
+    $this->assertRaw('id="edit-datetime-datepicker-timepicker-time" name="datetime_datepicker_timepicker[time]" value="4:00 PM" size="12" maxlength="12" class="form-time webform-time" />');
 
     // Check date/time placeholder attribute.
     $this->assertRaw(' type="text" data-drupal-date-format="Y-m-d" placeholder="{date}"');
@@ -62,37 +67,37 @@ public function testDateTime() {
 
     // Check 'datelist' and 'datetime' #default_value.
     $form = $webform->getSubmissionForm();
-    $this->assert($form['elements']['datetime_default']['#default_value'] instanceof DrupalDateTime, 'datetime_default #default_value instance of \Drupal\Core\Datetime\DrupalDateTime.');
+    $this->assertInstanceOf(DrupalDateTime::class, $form['elements']['datetime_default']['#default_value']);
 
     // Check datetime #date_date_max validation.
     $edit = ['datetime_min_max[date]' => '2010-08-18'];
-    $this->drupalPostForm('/webform/test_element_datetime', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datetime', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">datetime_min_max</em> must be on or before <em class="placeholder">2009-12-31</em>.');
 
     // Check datetime #date_date_min validation.
     $edit = ['datetime_min_max[date]' => '2006-08-18'];
-    $this->drupalPostForm('/webform/test_element_datetime', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datetime', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">datetime_min_max</em> must be on or after <em class="placeholder">2009-01-01</em>.');
 
     // Check datetime #date_max date validation.
     $edit = ['datetime_min_max_time[date]' => '2009-12-31', 'datetime_min_max_time[time]' => '19:00:00'];
-    $this->drupalPostForm('/webform/test_element_datetime', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datetime', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">datetime_min_max_time</em> must be on or before <em class="placeholder">2009-12-31 17:00:00</em>.');
 
     // Check datetime #date_min date validation.
     $edit = ['datetime_min_max_time[date]' => '2009-01-01', 'datetime_min_max_time[time]' => '08:00:00'];
-    $this->drupalPostForm('/webform/test_element_datetime', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datetime', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">datetime_min_max_time</em> must be on or after <em class="placeholder">2009-01-01 09:00:00</em>.');
 
     // Check datetime #date_max time validation.
     $edit = ['datetime_min_max_time[time]' => '01:00:00'];
-    $this->drupalPostForm('/webform/test_element_datetime', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datetime', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">datetime_min_max_time: Time</em> must be on or after <em class="placeholder">09:00:00</em>.');
     $this->assertRaw('<em class="placeholder">datetime_min_max_time</em> must be on or after <em class="placeholder">2009-01-01 09:00:00</em>.');
 
     // Check datetime #date_min time validation.
     $edit = ['datetime_min_max_time[time]' => '01:00:00'];
-    $this->drupalPostForm('/webform/test_element_datetime', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_datetime', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">datetime_min_max_time: Time</em> must be on or after <em class="placeholder">09:00:00</em>.');
     $this->assertRaw('<em class="placeholder">datetime_min_max_time</em> must be on or after <em class="placeholder">2009-01-01 09:00:00</em>.');
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementDetailsTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementDetailsTest.php
index 57c4fc6f56..90cc38a67f 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementDetailsTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementDetailsTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for details element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementDetailsTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementEmailConfirmTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementEmailConfirmTest.php
index f531550b82..ca27235198 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementEmailConfirmTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementEmailConfirmTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for email_confirm element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementEmailConfirmTest extends WebformElementBrowserTestBase {
 
@@ -52,14 +52,14 @@ public function testEmailConfirm() {
       'email_confirm_flexbox[mail_1]' => 'example01@example.com',
       'email_confirm_flexbox[mail_2]' => 'example02@example.com',
     ];
-    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, 'Submit');
     $this->assertRaw('The specified email addresses do not match.');
 
     $edit = [
       'email_confirm_flexbox[mail_1]' => 'example@example.com',
       'email_confirm_flexbox[mail_2]' => 'example@example.com',
     ];
-    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, 'Submit');
     $this->assertRaw("email_confirm_basic: ''
 email_confirm_advanced: ''
 email_confirm_pattern: ''
@@ -71,7 +71,7 @@ public function testEmailConfirm() {
       'email_confirm_advanced[mail_1]' => 'Not a valid email address',
       'email_confirm_advanced[mail_2]' => 'Not a valid email address, again',
     ];
-    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, 'Submit');
     $this->assertRaw('The email address <em class="placeholder">Not a valid email address</em> is not valid.');
     $this->assertRaw('The email address <em class="placeholder">Not a valid email address, again</em> is not valid.');
 
@@ -80,7 +80,7 @@ public function testEmailConfirm() {
       'email_confirm_advanced[mail_1]' => 'example01@example.com',
       'email_confirm_advanced[mail_2]' => 'example02@example.com',
     ];
-    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, 'Submit');
     $this->assertRaw('The specified email addresses do not match.');
 
     // Check email confirm matching email addresses.
@@ -88,7 +88,7 @@ public function testEmailConfirm() {
       'email_confirm_advanced[mail_1]' => 'example@example.com',
       'email_confirm_advanced[mail_2]' => 'example@example.com',
     ];
-    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, 'Submit');
     $this->assertNoRaw('<li class="messages__item">The specified email addresses do not match.</li>');
     $this->assertRaw('email_confirm_advanced: example@example.com');
 
@@ -97,7 +97,7 @@ public function testEmailConfirm() {
       'email_confirm_advanced[mail_1]' => '',
       'email_confirm_advanced[mail_2]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_email_confirm', $edit, 'Submit');
     $this->assertNoRaw('<li class="messages__item">Confirm Email field is required.</li>');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementEmailMultipleTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementEmailMultipleTest.php
index 0a79009eeb..ac00b5377a 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementEmailMultipleTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementEmailMultipleTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for email_multiple element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementEmailMultipleTest extends WebformElementBrowserTestBase {
 
@@ -30,28 +30,28 @@ public function testEmailMultiple() {
     $edit = [
       'email_multiple_basic' => 'example@example.com, Not a valid email address',
     ];
-    $this->drupalPostForm('/webform/test_element_email_multiple', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_email_multiple', $edit, 'Submit');
     $this->assertRaw('The email address <em class="placeholder">Not a valid email address</em> is not valid.');
 
     // Check email multiple invalid token email address.
     $edit = [
       'email_multiple_basic' => 'example@example.com, [token]',
     ];
-    $this->drupalPostForm('/webform/test_element_email_multiple', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_email_multiple', $edit, 'Submit');
     $this->assertRaw('The email address <em class="placeholder">[token]</em> is not valid.');
 
     // Check email multiple valid second email address.
     $edit = [
       'email_multiple_basic' => 'example@example.com, other@other.com',
     ];
-    $this->drupalPostForm('/webform/test_element_email_multiple', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_email_multiple', $edit, 'Submit');
     $this->assertRaw("email_multiple_basic: 'example@example.com, other@other.com'");
 
     // Check email multiple valid token email address (via #allow_tokens).
     $edit = [
       'email_multiple_advanced' => 'example@example.com, [token], [token1]@[token2].com',
     ];
-    $this->drupalPostForm('/webform/test_element_email_multiple', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_email_multiple', $edit, 'Submit');
     $this->assertRaw("email_multiple_advanced: 'example@example.com, [token], [token1]@[token2].com'");
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementEntityAutocompleteTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementEntityAutocompleteTest.php
index 06fa26ff5e..193e2c416e 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementEntityAutocompleteTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementEntityAutocompleteTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for entity automcomplete element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementEntityAutocompleteTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementEntityReferenceTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementEntityReferenceTest.php
index 5196257ec7..177d185d36 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementEntityReferenceTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementEntityReferenceTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for entity reference elements.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementEntityReferenceTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementExcludedColumnsTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementExcludedColumnsTest.php
index 593546f015..5a48194ed1 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementExcludedColumnsTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementExcludedColumnsTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for excluded columns element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementExcludedColumnsTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementExcludedElementsTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementExcludedElementsTest.php
index 7b19ccbb24..d36b4787c5 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementExcludedElementsTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementExcludedElementsTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for excluded elements element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementExcludedElementsTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementFieldsetTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementFieldsetTest.php
index 01dd7215c0..a40d24ed2c 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementFieldsetTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementFieldsetTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for fieldset element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementFieldsetTest extends WebformElementBrowserTestBase {
 
@@ -30,7 +30,12 @@ public function testFieldset() {
     $this->assertRaw('<span class="field-prefix">prefix</span>');
     $this->assertRaw('<span class="field-suffix">suffix</span>');
     $this->assertRaw('<div class="description">');
-    $this->assertRaw('<div id="edit-fieldset--description" class="webform-element-description">This is a description.</div>');
+    if (floatval(\Drupal::VERSION) >= 9) {
+      $this->assertRaw('<div id="edit-fieldset--description" data-drupal-field-elements="description" class="webform-element-description">This is a description.</div>');
+    }
+    else {
+      $this->assertRaw('<div id="edit-fieldset--description" class="webform-element-description">This is a description.</div>');
+    }
     $this->assertRaw('<div id="edit-fieldset--more" class="js-webform-element-more webform-element-more">');
 
     // Check fieldset title_display: invisible.
@@ -41,7 +46,12 @@ public function testFieldset() {
     $this->assertRaw('<span class="fieldset-legend"></span>');
 
     // Check fieldset description_display: before.
-    $this->assertRaw('<span class="field-prefix">prefix<div id="edit-fieldset-description-before--description" class="webform-element-description">This is a description before.</div>');
+    if (floatval(\Drupal::VERSION) >= 9) {
+      $this->assertRaw('<span class="field-prefix">prefix<div id="edit-fieldset-description-before--description" data-drupal-field-elements="description" class="webform-element-description">This is a description before.</div>');
+    }
+    else {
+      $this->assertRaw('<span class="field-prefix">prefix<div id="edit-fieldset-description-before--description" class="webform-element-description">This is a description before.</div>');
+    }
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementFormatCustomTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementFormatCustomTest.php
index e0f1b596a0..ed6594af64 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementFormatCustomTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementFormatCustomTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform submission webform element custom #format support.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementFormatCustomTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementFormatTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementFormatTest.php
index 580e2dd55c..fcea4e52f1 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementFormatTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementFormatTest.php
@@ -11,7 +11,7 @@
 /**
  * Tests for webform submission webform element custom #format support.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementFormatTest extends WebformElementBrowserTestBase {
 
@@ -79,11 +79,11 @@ public function testFormat() {
 //      'Entity autocomplete (Label (ID))' => 'admin (1)',
     ];
     foreach ($elements as $label => $value) {
-      $this->assertContains('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', ['@label' => $label, '@value' => $value]));
+      $this->assertStringContainsString('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', ['@label' => $label, '@value' => $value]));
     }
 
     // Check code format.
-    $this->assertContains('<pre class="js-webform-codemirror-runmode webform-codemirror-runmode" data-webform-codemirror-mode="text/x-yaml">message: \'Hello World\'</pre>', $body);
+    $this->assertStringContainsString('<pre class="js-webform-codemirror-runmode webform-codemirror-runmode" data-webform-codemirror-mode="text/x-yaml">message: \'Hello World\'</pre>', $body);
 
     // Check elements formatted as text.
     $body = $this->getMessageBody($submission, 'email_text');
@@ -110,7 +110,7 @@ public function testFormat() {
       'Time (Raw value): 09:00:00',
     ];
     foreach ($elements as $value) {
-      $this->assertContains($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
+      $this->assertStringContainsString($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
     }
 
     /**************************************************************************/
@@ -138,7 +138,7 @@ public function testFormat() {
       'File (URL)' => $this->getSubmissionFileUrl($submission, 'managed_file_url'),
     ];
     foreach ($elements as $label => $value) {
-      $this->assertContains('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', ['@label' => $label, '@value' => $value]));
+      $this->assertStringContainsString('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', ['@label' => $label, '@value' => $value]));
     }
 
     // Check managed file element formatted as text.
@@ -156,7 +156,7 @@ public function testFormat() {
       'File (File content (Base64))' => 'dGhpcyBpcyBhIHNhbXBsZSB0eHQgZmlsZQppdCBoYXMgdHdvIGxpbmVzCg==',
     ];
     foreach ($elements as $value) {
-      $this->assertContains($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
+      $this->assertStringContainsString($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
     }
 
     /**************************************************************************/
@@ -184,7 +184,7 @@ public function testFormat() {
       'Checkboxes (Checklist)' => '<span style="font-size: 1.4em; line-height: 1em">☑</span> One<br /><span style="font-size: 1.4em; line-height: 1em">☑</span> Two<br /><span style="font-size: 1.4em; line-height: 1em">☑</span> Three<br />',
     ];
     foreach ($elements as $label => $value) {
-      $this->assertContains('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', [
+      $this->assertStringContainsString('<b>' . $label . '</b><br />' . $value, $body, new FormattableMarkup('Found @label: @value', [
         '@label' => $label,
         '@value' => $value,
       ]));
@@ -221,7 +221,7 @@ public function testFormat() {
 ☑ Three',
     ];
     foreach ($elements as $value) {
-      $this->assertContains($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
+      $this->assertStringContainsString($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
     }
 
     /**************************************************************************/
@@ -245,7 +245,7 @@ public function testFormat() {
       'raw:' => '1, 2, 3',
     ];
     foreach ($elements as $label => $value) {
-      $this->assertContains('<h3>' . $label . '</h3>' . $value . '<hr />', $body, new FormattableMarkup('Found @label: @value', [
+      $this->assertStringContainsString('<h3>' . $label . '</h3>' . $value . '<hr />', $body, new FormattableMarkup('Found @label: @value', [
         '@label' => $label,
         '@value' => $value,
       ]));
@@ -263,7 +263,7 @@ public function testFormat() {
       "raw:\n1, 2, 3",
     ];
     foreach ($elements as $value) {
-      $this->assertContains($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
+      $this->assertStringContainsString($value, $body, new FormattableMarkup('Found @value', ['@value' => $value]));
     }
 
     // Check element default format item global setting.
@@ -271,14 +271,14 @@ public function testFormat() {
       ->set('format.checkboxes.item', 'raw')
       ->save();
     $body = $this->getMessageBody($webform_format_token_submission, 'email_text');
-    $this->assertContains("default:\n1, 2, 3", $body);
+    $this->assertStringContainsString("default:\n1, 2, 3", $body);
 
     // Check element default format items global setting.
     \Drupal::configFactory()->getEditable('webform.settings')
       ->set('format.checkboxes.items', 'and')
       ->save();
     $body = $this->getMessageBody($webform_format_token_submission, 'email_text');
-    $this->assertContains("default:\n1, 2, and 3", $body);
+    $this->assertStringContainsString("default:\n1, 2, and 3", $body);
   }
 
   /**
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementHelpTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementHelpTest.php
index 5fbb7e82a5..ac1622cacc 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementHelpTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementHelpTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for element help.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementHelpTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementHorizontalRuleTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementHorizontalRuleTest.php
index 9553782038..c3c4b45426 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementHorizontalRuleTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementHorizontalRuleTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for horizontal rule element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementHorizontalRuleTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementHtmlEditorTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementHtmlEditorTest.php
index ba6c61c068..a9c274812d 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementHtmlEditorTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementHtmlEditorTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform HTML editor element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementHtmlEditorTest extends WebformElementBrowserTestBase {
 
@@ -29,7 +29,7 @@ class WebformElementHtmlEditorTest extends WebformElementBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create filters.
@@ -71,7 +71,7 @@ public function testHtmlEditor() {
     $this->assertRaw('<textarea data-drupal-selector="edit-webform-html-editor-codemirror-value" class="js-webform-codemirror webform-codemirror html required form-textarea resize-vertical" required="required" aria-required="true" data-webform-codemirror-mode="text/html" id="edit-webform-html-editor-codemirror-value" name="webform_html_editor_codemirror[value]" rows="5" cols="60">Hello &lt;b&gt;World!!!&lt;/b&gt;</textarea>');
 
     // Disable HTML editor.
-    $this->drupalPostForm('/admin/structure/webform/config/elements', ['html_editor[disabled]' => TRUE], t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/elements', ['html_editor[disabled]' => TRUE], 'Save configuration');
 
     // Check that HTML editor is removed and replaced by CodeMirror HTML editor.
     $this->drupalGet('/webform/test_element_html_editor');
@@ -83,7 +83,7 @@ public function testHtmlEditor() {
       'html_editor[disabled]' => FALSE,
       'html_editor[element_format]' => 'basic_html',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config/elements', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/elements', $edit, 'Save configuration');
 
     // Check that Text format is disabled.
     $this->drupalGet('/webform/test_element_html_editor');
@@ -96,7 +96,7 @@ public function testHtmlEditor() {
     $edit = [
       'html_editor[element_format]' => '',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config/elements', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/elements', $edit, 'Save configuration');
 
     // Check that tidy removed <p> tags.
     $build = WebformHtmlEditor::checkMarkup('<p>Some text</p>');
@@ -109,7 +109,7 @@ public function testHtmlEditor() {
     $this->assertEqual(\Drupal::service('renderer')->renderPlain($build), '<p>Some text</p><p>More text</p>');
 
     // Disable HTML tidy.
-    $this->drupalPostForm('/admin/structure/webform/config/elements', ['html_editor[tidy]' => FALSE], t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/elements', ['html_editor[tidy]' => FALSE], 'Save configuration');
 
     // Check that tidy is disabled.
     $build = WebformHtmlEditor::checkMarkup('<p>Some text</p>');
@@ -122,7 +122,7 @@ public function testHtmlEditor() {
       'html_editor[element_format]' => '',
       'html_editor[mail_format]' => '',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config/elements', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/elements', $edit, 'Save configuration');
 
     // Check that HTML editor is used.
     $this->drupalGet('/admin/structure/webform/manage/contact/handlers/email_confirmation/edit');
@@ -132,20 +132,13 @@ public function testHtmlEditor() {
     $edit = [
       'html_editor[mail_format]' => 'basic_html',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config/elements', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/elements', $edit, 'Save configuration');
 
     // Check mail text format is used.
     $this->drupalGet('/admin/structure/webform/manage/contact/handlers/email_confirmation/edit');
     $this->assertNoRaw('<textarea data-drupal-selector="edit-settings-body-custom-html-value" class="js-html-editor form-textarea resize-vertical" id="edit-settings-body-custom-html-value" name="settings[body_custom_html][value]" rows="5" cols="60">');
     $this->assertRaw('<textarea data-drupal-selector="edit-settings-body-custom-html-value-value" id="edit-settings-body-custom-html-value-value" name="settings[body_custom_html][value][value]" rows="5" cols="60" class="form-textarea resize-vertical">');
-    // @todo Remove once Drupal 8.8.x is only supported.
-    if (floatval(\Drupal::VERSION) >= 8.8) {
-      $this->assertRaw('<div class="js-filter-wrapper filter-wrapper js-form-wrapper form-wrapper" data-drupal-selector="edit-settings-body-custom-html-value-format" id="edit-settings-body-custom-html-value-format">');
-    }
-    else {
-      $this->assertRaw('<div class="filter-wrapper js-form-wrapper form-wrapper" data-drupal-selector="edit-settings-body-custom-html-value-format" id="edit-settings-body-custom-html-value-format">');
-    }
-
+    $this->assertRaw('<div class="js-filter-wrapper filter-wrapper js-form-wrapper form-wrapper" data-drupal-selector="edit-settings-body-custom-html-value-format" id="edit-settings-body-custom-html-value-format">');
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementIgnoredPropertiesTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementIgnoredPropertiesTest.php
index 83a1813bea..a70afd80df 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementIgnoredPropertiesTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementIgnoredPropertiesTest.php
@@ -2,14 +2,13 @@
 
 namespace Drupal\Tests\webform\Functional\Element;
 
-use Drupal\Component\Render\FormattableMarkup;
 use Drupal\webform\Entity\Webform;
 use Drupal\webform\Utility\WebformElementHelper;
 
 /**
  * Tests for element ignored properties.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementIgnoredPropertiesTest extends WebformElementBrowserTestBase {
 
@@ -26,9 +25,9 @@ class WebformElementIgnoredPropertiesTest extends WebformElementBrowserTestBase
   public function testIgnoredProperties() {
     $webform_ignored_properties = Webform::load('test_element_ignored_properties');
     $elements = $webform_ignored_properties->getElementsInitialized();
-    $this->assert(isset($elements['textfield']));
+    $this->assertArrayHasKey('textfield', $elements);
     foreach (WebformElementHelper::$ignoredProperties as $ignored_property) {
-      $this->assert(!isset($elements['textfield'][$ignored_property]), new FormattableMarkup('@property ignored.', ['@property' => $ignored_property]));
+      $this->assertArrayNotHasKey($ignored_property, $elements['textfield']);
     }
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementImageResolutionTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementImageResolutionTest.php
index 55a0305f6f..f8d129c092 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementImageResolutionTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementImageResolutionTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform image resolution element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementImageResolutionTest extends WebformElementBrowserTestBase {
 
@@ -32,11 +32,11 @@ public function testImageResolution() {
     $this->assertRaw('{description}');
 
     // Check validation.
-    $this->drupalPostForm('/webform/test_element_image_resolution', ['webform_image_resolution[x]' => '100'], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_image_resolution', ['webform_image_resolution[x]' => '100'], 'Submit');
     $this->assertRaw('Both a height and width value must be specified in the webform_image_resolution field.');
 
     // Check processing.
-    $this->drupalPostForm('/webform/test_element_image_resolution', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_image_resolution', [], 'Submit');
     $this->assertRaw("webform_image_resolution: ''
 webform_image_resolution_advanced: 300x400");
   }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementInputMaskTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementInputMaskTest.php
index eb0cf061a4..274fe6e521 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementInputMaskTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementInputMaskTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for element input mask.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementInputMaskTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementLikertTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementLikertTest.php
index 24f05eaedb..fb1a6804f9 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementLikertTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementLikertTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for likert element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementLikertTest extends WebformElementBrowserTestBase {
 
@@ -50,7 +50,7 @@ public function testLikertElement() {
     $this->assertRaw('<label for="edit-likert-help-q1--2" class="option"><span class="webform-likert-label visually-hidden">Option 2<span class="webform-likert-help hidden"><span class="webform-element-help" role="tooltip" tabindex="0" data-webform-help="&lt;div class=&quot;webform-element-help--title&quot;&gt;Option 2&lt;/div&gt;&lt;div class=&quot;webform-element-help--content&quot;&gt;This is help text&lt;/div&gt;"><span aria-hidden="true">?</span></span>');
 
     // Check likert required.
-    $this->drupalPostForm('/webform/test_element_likert', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_likert', [], 'Submit');
     $this->assertRaw('Question 1 field is required.');
     $this->assertRaw('Question 2 field is required.');
     $this->assertRaw('Question 3 field is required.');
@@ -64,7 +64,7 @@ public function testLikertElement() {
       'likert_values[1]' => '1',
       'likert_values[2]' => 'N/A',
     ];
-    $this->drupalPostForm('/webform/test_element_likert', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_likert', $edit, 'Submit');
     $this->assertRaw("likert_default:
   q1: null
   q2: null
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementLocationPlacesTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementLocationPlacesTest.php
index 80671286dd..f417f507eb 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementLocationPlacesTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementLocationPlacesTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for location (Algolia) places element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementLocationPlacesTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileImageTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileImageTest.php
index 9d901664c2..7e0fa347a8 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileImageTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileImageTest.php
@@ -8,7 +8,7 @@
 /**
  * Test for webform element managed file image handling.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementManagedFileImageTest extends WebformElementManagedFileTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileLimitTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileLimitTest.php
index e73862348c..0d277220ba 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileLimitTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileLimitTest.php
@@ -7,7 +7,7 @@
 /**
  * Test for webform element managed file limit.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementManagedFileLimitTest extends WebformElementManagedFileTestBase {
 
@@ -86,8 +86,8 @@ public function testLimits() {
       'files[custom_composite_managed_files_items_0_managed_file]' => \Drupal::service('file_system')->realpath($file->uri),
       'files[custom_composite_managed_files_items_1_managed_file]' => \Drupal::service('file_system')->realpath($file->uri),
     ];
-    $this->drupalPostForm('/webform/test_element_managed_file_limit', [], t('Add'));
-    $this->drupalPostForm(NULL, $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_managed_file_limit', [], 'Add');
+    $this->drupalPostForm(NULL, $edit, 'Submit');
     $this->assertRaw('This form\'s file upload quota of <em class="placeholder">2 KB</em> has been exceeded. Please remove some files.');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePreviewTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePreviewTest.php
index 775123dfb2..d1c4e116e1 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePreviewTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePreviewTest.php
@@ -5,7 +5,7 @@
 /**
  * Test for webform element managed file preview.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementManagedFilePreviewTest extends WebformElementManagedFileTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePrivateTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePrivateTest.php
index c288932e0f..6c8b381956 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePrivateTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePrivateTest.php
@@ -10,7 +10,7 @@
 /**
  * Test for webform element managed file handling.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementManagedFilePrivateTest extends WebformElementManagedFileTestBase {
 
@@ -87,7 +87,7 @@ public function testPrivateFiles() {
     $edit = [
       'files[managed_file_single]' => \Drupal::service('file_system')->realpath($this->files[1]->uri),
     ];
-    $this->drupalPostForm('/webform/' . $webform->id(), $edit, t('Preview'));
+    $this->drupalPostForm('/webform/' . $webform->id(), $edit, 'Preview');
 
     $temp_file_uri = file_create_url('private://webform/test_element_managed_file/_sid_/' . basename($this->files[1]->uri));
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePublicTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePublicTest.php
index 0f6dbf3b6c..5b392a8912 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePublicTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFilePublicTest.php
@@ -7,7 +7,7 @@
  *
  * @see https://www.drupal.org/psa-2016-003
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementManagedFilePublicTest extends WebformElementBrowserTestBase {
 
@@ -28,7 +28,7 @@ class WebformElementManagedFilePublicTest extends WebformElementBrowserTestBase
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Set public file upload support for testing.
@@ -43,7 +43,7 @@ public function setUp() {
   public function testPublicUpload() {
     // Check status report private file system warning.
     $requirements = webform_requirements('runtime');
-    $this->assertEqual($requirements['webform_file_private']['value'], (string) t('Private file system is set.'));
+    $this->assertEqual($requirements['webform_file_private']['value'], (string) 'Private file system is set.');
 
     $this->drupalLogin($this->rootUser);
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTest.php
index ef1a39b026..0e61002217 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTest.php
@@ -9,7 +9,7 @@
 /**
  * Test for webform element managed file handling.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementManagedFileTest extends WebformElementManagedFileTestBase {
 
@@ -48,7 +48,7 @@ class WebformElementManagedFileTest extends WebformElementManagedFileTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     $this->webform = Webform::load('test_element_managed_file');
@@ -76,6 +76,9 @@ public function testFileUpload() {
     // Check single custom file upload button.
     $this->assertRaw('<label style="color: red" for="edit-managed-file-single-button-custom-upload-button--2" class="button button-action webform-file-button">{Custom label}</label>');
 
+    // Check comma delimited file extensions.
+    $this->assertRaw('Allowed types: txt, text.');
+
     /* Element processing */
 
     $this->checkFileUpload('single', $this->files[0], $this->files[1]);
@@ -98,7 +101,7 @@ public function testFileUpload() {
         \Drupal::service('file_system')->realpath($this->files[2]->uri),
       ],
     ];
-    $this->drupalPostForm('/webform/test_element_managed_file', $edit, t('Upload'));
+    $this->drupalPostForm('/webform/test_element_managed_file', $edit, 'Upload');
     $this->assertRaw('<em class="placeholder">managed_file_multiple_two</em> can only hold 2 values but there were 3 uploaded. The following files have been omitted as a result: <em class="placeholder">text-2.txt</em>.');
 
     // Check file input is removed.
@@ -120,7 +123,6 @@ public function testFileUpload() {
     $this->assertNoRaw('<div class="webform-managed-file-placeholder managed-file-placeholder js-form-wrapper form-wrapper" data-drupal-selector="edit-managed-file-single-placeholder-file-placeholder" id="edit-managed-file-single-placeholder-file-placeholder">This is the single file upload placeholder</div>');
     $this->assertNoRaw('<div class="webform-managed-file-placeholder managed-file-placeholder js-form-wrapper form-wrapper" data-drupal-selector="edit-managed-file-multiple-placeholder-file-placeholder" id="edit-managed-file-multiple-placeholder-file-placeholder">This is the multiple file upload placeholder</div>');
 
-
     $this->drupalLogout();
 
     /* Required error */
@@ -172,11 +174,11 @@ public function testFileRename() {
 
     /** @var \Drupal\file\FileInterface[] $multiple_file */
     $multiple_file = File::loadMultiple($submission->getElementData('file_multiple'));
-    $this->assertEqual(count($multiple_file), 2, 'Two files found in the multiple element.');
+    $this->assertCount(2, $multiple_file, 'Two files found in the multiple element.');
 
     $i = -1;
     foreach ($multiple_file as $file) {
-      $suffix = $i == -1 ? '' : '_' . $i;
+      $suffix = $i === -1 ? '' : '_' . $i;
       $this->assertEqual('file_multiple_' . $source_for_filename . $suffix . '.txt', $file->getFilename());
       $i++;
     }
@@ -298,7 +300,7 @@ public function testFileUploadWithDisabledResults() {
    */
   protected function checkFileUpload($type, $first_file, $second_file) {
     $key = 'managed_file_' . $type;
-    $parameter_name = ($type == 'multiple') ? "files[$key][]" : "files[$key]";
+    $parameter_name = ($type === 'multiple') ? "files[$key][]" : "files[$key]";
 
     $edit = [
       $parameter_name => \Drupal::service('file_system')->realpath($first_file->uri),
@@ -313,7 +315,7 @@ protected function checkFileUpload($type, $first_file, $second_file) {
     $file = File::load($fid);
 
     // Check that test file was uploaded to the current submission.
-    $second = ($type == 'multiple') ? [$fid] : $fid;
+    $second = ($type === 'multiple') ? [$fid] : $fid;
     $this->assertEqual($submission->getElementData($key), $second, 'Test file was upload to the current submission');
 
     // Check test file file usage.
@@ -323,27 +325,27 @@ protected function checkFileUpload($type, $first_file, $second_file) {
     $this->assertEqual($file->getFileUri(), 'private://webform/test_element_managed_file/' . $sid . '/' . $first_file->filename);
 
     // Check that test file exists.
-    $this->assert(file_exists($file->getFileUri()), 'File exists');
+    $this->assertFileExists($file->getFileUri());
 
     // Login admin user.
     $this->drupalLogin($this->adminSubmissionUser);
 
     // Check managed file formatting.
     $this->drupalGet('/admin/structure/webform/manage/test_element_managed_file/submission/' . $sid);
-    if ($type == 'multiple') {
+    if ($type === 'multiple') {
       $this->assertRaw('<label>managed_file_multiple</label>');
       $this->assertRaw('<div class="item-list">');
     }
     $this->assertRaw('<span class="file file--mime-text-plain file--text"> <a href="' . file_create_url($file->getFileUri()) . '" type="text/plain; length=' . $file->getSize() . '">' . $file->getFilename() . '</a></span>');
 
     // Remove the uploaded file.
-    if ($type == 'multiple') {
+    if ($type === 'multiple') {
       $edit = ['managed_file_multiple[file_' . $fid . '][selected]' => TRUE];
-      $submit = t('Remove selected');
+      $submit = 'Remove selected';
     }
     else {
       $edit = [];
-      $submit = t('Remove');
+      $submit = 'Remove';
     }
     $this->drupalPostForm('/admin/structure/webform/manage/test_element_managed_file/submission/' . $sid . '/edit', $edit, $submit);
 
@@ -351,10 +353,10 @@ protected function checkFileUpload($type, $first_file, $second_file) {
     $edit = [
       $parameter_name => \Drupal::service('file_system')->realpath($second_file->uri),
     ];
-    $this->drupalPostForm(NULL, $edit, t('Upload'));
+    $this->drupalPostForm(NULL, $edit, 'Upload');
 
     // Submit the new file.
-    $this->drupalPostForm(NULL, [], t('Save'));
+    $this->drupalPostForm(NULL, [], 'Save');
 
     /** @var \Drupal\file\FileInterface $test_file_0 */
     $new_fid = $this->getLastFileId();
@@ -364,11 +366,11 @@ protected function checkFileUpload($type, $first_file, $second_file) {
     $submission = WebformSubmission::load($sid);
 
     // Check that test new file was uploaded to the current submission.
-    $second = ($type == 'multiple') ? [$new_fid] : $new_fid;
+    $second = ($type === 'multiple') ? [$new_fid] : $new_fid;
     $this->assertEqual($submission->getElementData($key), $second, 'Test new file was upload to the current submission');
 
     // Check that test file was deleted from the disk and database.
-    $this->assert(!file_exists($file->getFileUri()), 'Test file deleted from disk');
+    $this->assertFileNotExists($file->getFileUri(), 'Test file deleted from disk');
     $this->assertEqual(0, \Drupal::database()->query('SELECT COUNT(fid) AS total FROM {file_managed} WHERE fid = :fid', [':fid' => $fid])->fetchField(), 'Test file 0 deleted from database');
     $this->assertEqual(0, \Drupal::database()->query('SELECT COUNT(fid) AS total FROM {file_usage} WHERE fid = :fid', [':fid' => $fid])->fetchField(), 'Test file 0 deleted from database');
 
@@ -376,17 +378,17 @@ protected function checkFileUpload($type, $first_file, $second_file) {
     $this->assertIdentical(['webform' => ['webform_submission' => [$sid => '1']]], $this->fileUsage->listUsage($new_file), 'The new file has 1 usage.');
 
     // Check that file directory was create.
-    $this->assertTrue(file_exists('private://webform/test_element_managed_file/' . $sid . '/'));
+    $this->assertFileExists('private://webform/test_element_managed_file/' . $sid . '/');
 
     // Delete the submission.
     $submission->delete();
 
     // Check that test file 1 was deleted from the disk and database.
-    $this->assert(!file_exists($new_file->getFileUri()), 'Test new file deleted from disk');
+    $this->assertFileNotExists($new_file->getFileUri(), 'Test new file deleted from disk');
     $this->assertEqual(0, \Drupal::database()->query('SELECT COUNT(fid) AS total FROM {file_managed} WHERE fid = :fid', [':fid' => $new_fid])->fetchField(), 'Test new file deleted from database');
 
     // Check that empty file directory was deleted.
-    $this->assertFalse(file_exists('private://webform/test_element_managed_file/' . $sid . '/'));
+    $this->assertFileNotExists('private://webform/test_element_managed_file/' . $sid . '/');
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTestBase.php b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTestBase.php
index a5e8e389aa..8c38498b0f 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTestBase.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementManagedFileTestBase.php
@@ -36,7 +36,7 @@ abstract class WebformElementManagedFileTestBase extends WebformElementBrowserTe
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     $this->fileUsage = $this->container->get('file.usage');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementMappingTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementMappingTest.php
index b3e983c695..912093760f 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementMappingTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementMappingTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for mapping element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementMappingTest extends WebformElementBrowserTestBase {
 
@@ -45,7 +45,7 @@ public function testMappingElement() {
     $this->assertRaw('<input data-drupal-selector="edit-webform-mapping-textfield-one" type="text" id="edit-webform-mapping-textfield-one" name="webform_mapping_textfield[one]" value="" size="10" maxlength="128" class="form-text" />');
 
     // Check required.
-    $this->drupalPostForm('/webform/test_element_mapping', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_mapping', [], 'Submit');
     $this->assertRaw('webform_mapping_required field is required.');
     $this->assertRaw('One field is required.');
     $this->assertRaw('Two field is required.');
@@ -86,13 +86,13 @@ public function testMappingElement() {
     ];
 
     // Check preview.
-    $this->drupalPostForm('/webform/test_element_mapping', $edit, t('Preview'));
+    $this->drupalPostForm('/webform/test_element_mapping', $edit, 'Preview');
 
     // Check that source description is not displayed.
     $this->assertRaw('<li>Two &rarr; Five</li>');
 
     // Check submitted values.
-    $this->drupalPostForm('/webform/test_element_mapping', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_mapping', $edit, 'Submit');
     $this->assertRaw("webform_mapping:
   one: four
   three: six
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementMarkupTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementMarkupTest.php
index 653cfc001f..8cf2dbe789 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementMarkupTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementMarkupTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for markup element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementMarkupTest extends WebformElementBrowserTestBase {
 
@@ -44,7 +44,7 @@ public function testMarkup() {
     $this->assertRaw('<p><em>Alter this markup.</em> <strong>This markup was altered.</strong></p>');
 
     // Check markup display on view.
-    $this->drupalPostForm('/webform/test_element_markup', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_element_markup', [], 'Preview');
     $this->assertNoRaw('<p>This is normal markup</p>');
     $this->assertNoRaw('<p>This is only displayed on the form view.</p>');
     $this->assertRaw('<p>This is only displayed on the submission view.</p>');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementMediaFileTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementMediaFileTest.php
index 8365d85b9b..913acf9e28 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementMediaFileTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementMediaFileTest.php
@@ -8,7 +8,7 @@
 /**
  * Test for webform element managed file handling.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementMediaFileTest extends WebformElementManagedFileTestBase {
 
@@ -51,7 +51,7 @@ public function testMediaFileUpload() {
 
     // Get test webform preview with test values.
     $this->drupalLogin($this->rootUser);
-    $this->drupalPostForm('/webform/test_element_media_file/test', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_element_media_file/test', [], 'Preview');
 
     // Check audio file preview.
     $this->assertRaw('<source src="' . $this->getAbsoluteUrl('/system/files/webform/test_element_media_file/_sid_/audio_file_mp3.mp3') . '" type="audio/mpeg">');
@@ -83,7 +83,7 @@ public function testMediaFileUpload() {
    */
   protected function checkFileUpload($type, $first_file, $second_file) {
     $key = 'managed_file_' . $type;
-    $parameter_name = ($type == 'multiple') ? "files[$key][]" : "files[$key]";
+    $parameter_name = ($type === 'multiple') ? "files[$key][]" : "files[$key]";
 
     $edit = [
       $parameter_name => \Drupal::service('file_system')->realpath($first_file->uri),
@@ -98,7 +98,7 @@ protected function checkFileUpload($type, $first_file, $second_file) {
     $file = File::load($fid);
 
     // Check that test file was uploaded to the current submission.
-    $second = ($type == 'multiple') ? [$fid] : $fid;
+    $second = ($type === 'multiple') ? [$fid] : $fid;
     $this->assertEqual($submission->getElementData($key), $second, 'Test file was upload to the current submission');
 
     // Check test file file usage.
@@ -108,27 +108,27 @@ protected function checkFileUpload($type, $first_file, $second_file) {
     $this->assertEqual($file->getFileUri(), 'private://webform/test_element_managed_file/' . $sid . '/' . $first_file->filename);
 
     // Check that test file exists.
-    $this->assert(file_exists($file->getFileUri()), 'File exists');
+    $this->assertFileExists($file->getFileUri());
 
     // Login admin user.
     $this->drupalLogin($this->adminSubmissionUser);
 
     // Check managed file formatting.
     $this->drupalGet('/admin/structure/webform/manage/test_element_managed_file/submission/' . $sid);
-    if ($type == 'multiple') {
+    if ($type === 'multiple') {
       $this->assertRaw('<label>managed_file_multiple</label>');
       $this->assertRaw('<div class="item-list">');
     }
     $this->assertRaw('<span class="file file--mime-text-plain file--text"> <a href="' . file_create_url($file->getFileUri()) . '" type="text/plain; length=' . $file->getSize() . '">' . $file->getFilename() . '</a></span>');
 
     // Remove the uploaded file.
-    if ($type == 'multiple') {
+    if ($type === 'multiple') {
       $edit = ['managed_file_multiple[file_' . $fid . '][selected]' => TRUE];
-      $submit = t('Remove selected');
+      $submit = 'Remove selected';
     }
     else {
       $edit = [];
-      $submit = t('Remove');
+      $submit = 'Remove';
     }
     $this->drupalPostForm('/admin/structure/webform/manage/test_element_managed_file/submission/' . $sid . '/edit', $edit, $submit);
 
@@ -136,10 +136,10 @@ protected function checkFileUpload($type, $first_file, $second_file) {
     $edit = [
       $parameter_name => \Drupal::service('file_system')->realpath($second_file->uri),
     ];
-    $this->drupalPostForm(NULL, $edit, t('Upload'));
+    $this->drupalPostForm(NULL, $edit, 'Upload');
 
     // Submit the new file.
-    $this->drupalPostForm(NULL, [], t('Save'));
+    $this->drupalPostForm(NULL, [], 'Save');
 
     /** @var \Drupal\file\Entity\File $test_file_0 */
     $new_fid = $this->getLastFileId();
@@ -149,11 +149,11 @@ protected function checkFileUpload($type, $first_file, $second_file) {
     $submission = WebformSubmission::load($sid);
 
     // Check that test new file was uploaded to the current submission.
-    $second = ($type == 'multiple') ? [$new_fid] : $new_fid;
+    $second = ($type === 'multiple') ? [$new_fid] : $new_fid;
     $this->assertEqual($submission->getElementData($key), $second, 'Test new file was upload to the current submission');
 
     // Check that test file was deleted from the disk and database.
-    $this->assert(!file_exists($file->getFileUri()), 'Test file deleted from disk');
+    $this->assertFileNotExists($file->getFileUri(), 'Test file deleted from disk');
     $this->assertEqual(0, \Drupal::database()->query('SELECT COUNT(fid) AS total FROM {file_managed} WHERE fid = :fid', [':fid' => $fid])->fetchField(), 'Test file 0 deleted from database');
     $this->assertEqual(0, \Drupal::database()->query('SELECT COUNT(fid) AS total FROM {file_usage} WHERE fid = :fid', [':fid' => $fid])->fetchField(), 'Test file 0 deleted from database');
 
@@ -164,7 +164,7 @@ protected function checkFileUpload($type, $first_file, $second_file) {
     $submission->delete();
 
     // Check that test file 1 was deleted from the disk and database.
-    $this->assert(!file_exists($new_file->getFileUri()), 'Test new file deleted from disk');
+    $this->assertFileNotExists($new_file->getFileUri(), 'Test new file deleted from disk');
     $this->assertEqual(0, \Drupal::database()->query('SELECT COUNT(fid) AS total FROM {file_managed} WHERE fid = :fid', [':fid' => $new_fid])->fetchField(), 'Test new file deleted from database');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementMessageTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementMessageTest.php
index 4ecba2586e..648adb8c94 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementMessageTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementMessageTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for message webform element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementMessageTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementMoreTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementMoreTest.php
index d8a314532c..d4c2f2eb47 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementMoreTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementMoreTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for element more.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementMoreTest extends WebformElementBrowserTestBase {
 
@@ -51,7 +51,12 @@ public function testMore() {
     $this->assertRaw('<div id="edit-more-datetime--more" class="js-webform-element-more webform-element-more">');
 
     // Check fieldset more.
-    $this->assertRaw('<div id="edit-more-fieldset--description" class="webform-element-description">{This is a description}</div>');
+    if (floatval(\Drupal::VERSION) >= 9) {
+      $this->assertRaw('<div id="edit-more-fieldset--description" data-drupal-field-elements="description" class="webform-element-description">{This is a description}</div>');
+    }
+    else {
+      $this->assertRaw('<div id="edit-more-fieldset--description" class="webform-element-description">{This is a description}</div>');
+    }
     $this->assertRaw('<div id="edit-more-fieldset--more" class="js-webform-element-more webform-element-more">');
 
     // Check details more.
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementMultiplePropertyTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementMultiplePropertyTest.php
index f3c964aa96..ba52e3f38c 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementMultiplePropertyTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementMultiplePropertyTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform element multiple property.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementMultiplePropertyTest extends WebformElementBrowserTestBase {
 
@@ -21,7 +21,7 @@ class WebformElementMultiplePropertyTest extends WebformElementBrowserTestBase {
    */
   public function testMultipleProperty() {
     // Check processing.
-    $this->drupalPostForm('/webform/test_element_multiple_property', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_multiple_property', [], 'Submit');
     $this->assertRaw('webform_element_multiple: false
 webform_element_multiple_true: true
 webform_element_multiple_false: false
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementMultipleTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementMultipleTest.php
index b70f3291a9..9d0261c108 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementMultipleTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementMultipleTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform element multiple.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementMultipleTest extends WebformElementBrowserTestBase {
 
@@ -30,7 +30,7 @@ public function testMultiple() {
     $webform = Webform::load('test_element_multiple');
 
     // Check processing for all elements.
-    $this->drupalPostForm('/webform/test_element_multiple', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_multiple', [], 'Submit');
     $this->assertRaw("webform_multiple_default:
   - One
   - Two
@@ -176,7 +176,7 @@ public function testMultiple() {
     $edit = [
       'webform_multiple_key[items][1][value]' => 'one',
     ];
-    $this->drupalPostForm('/webform/test_element_multiple', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_multiple', $edit, 'Submit');
     $this->assertRaw('The <em class="placeholder">Option value</em> \'one\' is already in use. It must be unique.');
 
     /**************************************************************************/
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementOptionsTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementOptionsTest.php
index 505bc175e6..d045f4e471 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementOptionsTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementOptionsTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform element options.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementOptionsTest extends WebformElementBrowserTestBase {
 
@@ -26,7 +26,7 @@ public function testElementOptions() {
     $this->assertRaw('<input data-drupal-selector="edit-webform-options-maxlength-options-items-0-text" type="text" id="edit-webform-options-maxlength-options-items-0-text" name="webform_options_maxlength[options][items][0][text]" value="One" size="60" maxlength="20" placeholder="Enter text…" class="form-text" />');
 
     // Check default value handling.
-    $this->drupalPostForm('/webform/test_element_options', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_options', [], 'Submit');
     $this->assertRaw("webform_options: {  }
 webform_options_default_value:
   one: One
@@ -50,7 +50,7 @@ public function testElementOptions() {
   three: Three");
 
     // Check default value handling.
-    $this->drupalPostForm('/webform/test_element_options', ['webform_element_options_custom[options]' => 'yes_no'], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_options', ['webform_element_options_custom[options]' => 'yes_no'], 'Submit');
     $this->assertRaw("webform_element_options_custom: yes_no");
 
     // Check unique option value validation.
@@ -58,7 +58,7 @@ public function testElementOptions() {
       'webform_options[options][items][0][value]' => 'test',
       'webform_options[options][items][1][value]' => 'test',
     ];
-    $this->drupalPostForm('/webform/test_element_options', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_options', $edit, 'Submit');
     $this->assertRaw('The <em class="placeholder">Option value</em> \'test\' is already in use. It must be unique.');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementOtherTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementOtherTest.php
index 8305dc39ae..e28b44572d 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementOtherTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementOtherTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform element other.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementOtherTest extends WebformElementBrowserTestBase {
 
@@ -37,10 +37,10 @@ public function testBuildingOtherElements() {
 
     // Check advanced select_other w/ custom label.
     $this->assertRaw('<span class="fieldset-legend js-form-required form-required">Select other advanced</span>');
-    $this->assertRaw('<select data-drupal-selector="edit-select-other-advanced-select" id="edit-select-other-advanced-select" name="select_other_advanced[select]" class="form-select required" required="required" aria-required="true">');
+    $this->assertRaw('<select data-webform-required-error="This is a custom required error message." data-drupal-selector="edit-select-other-advanced-select" id="edit-select-other-advanced-select" name="select_other_advanced[select]" class="form-select required" required="required" aria-required="true">');
     $this->assertRaw('<option value="_other_" selected="selected">Is there another option you wish to enter?</option>');
     $this->assertRaw('<label for="edit-select-other-advanced-other">Other</label>');
-    $this->assertRaw('<input data-counter-type="character" data-counter-minimum="4" data-counter-maximum="10" class="js-webform-counter webform-counter form-text" data-drupal-selector="edit-select-other-advanced-other" aria-describedby="edit-select-other-advanced-other--description" type="text" id="edit-select-other-advanced-other" name="select_other_advanced[other]" value="Four" size="20" maxlength="10" placeholder="What is this other option" />');
+    $this->assertRaw('<input data-webform-required-error="This is a custom required error message." data-counter-type="character" data-counter-minimum="4" data-counter-maximum="10" class="js-webform-counter webform-counter form-text" data-drupal-selector="edit-select-other-advanced-other" aria-describedby="edit-select-other-advanced-other--description" type="text" id="edit-select-other-advanced-other" name="select_other_advanced[other]" value="Four" size="20" maxlength="10" placeholder="What is this other option" />');
     $this->assertRaw('<div id="edit-select-other-advanced-other--description" class="webform-element-description">Other select description</div>');
 
     // Check multiple select_other.
@@ -108,7 +108,7 @@ public function testProcessingOtherElements() {
       'select_other_basic[select]' => '_other_',
       'select_other_basic[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('Select other basic field is required.');
 
     // Check select other is not required when not selected.
@@ -116,7 +116,7 @@ public function testProcessingOtherElements() {
       'select_other_basic[select]' => '',
       'select_other_basic[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertNoRaw('Select other basic field is required.');
 
     // Check select other required validation.
@@ -124,15 +124,25 @@ public function testProcessingOtherElements() {
       'select_other_advanced[select]' => '',
       'select_other_advanced[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
-    $this->assertRaw('Select other advanced field is required.');
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
+    $this->assertNoRaw('Select other advanced field is required.');
+    $this->assertRaw('This is a custom required error message.');
+
+    // Check select other custom required error.
+    $edit = [
+      'select_other_advanced[select]' => '_other_',
+      'select_other_advanced[other]' => '',
+    ];
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
+    $this->assertNoRaw('Select other advanced field is required.');
+    $this->assertRaw('This is a custom required error message.');
 
     // Check select other processing w/ other min/max character validation.
     $edit = [
       'select_other_advanced[select]' => '_other_',
       'select_other_advanced[other]' => 'X',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('Other must be longer than <em class="placeholder">4</em> characters but is currently <em class="placeholder">1</em> characters long.');
 
     // Check select other processing w/ other.
@@ -140,7 +150,7 @@ public function testProcessingOtherElements() {
       'select_other_advanced[select]' => '_other_',
       'select_other_advanced[other]' => 'Five',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('select_other_advanced: Five');
 
     // Check select other processing w/o other.
@@ -149,7 +159,7 @@ public function testProcessingOtherElements() {
       // This value is ignored, because 'select_other_advanced[select]' is not set to '_other_'.
       'select_other_advanced[other]' => 'Five',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('select_other_advanced: One');
     $this->assertNoRaw('select_other_advanced: Five');
 
@@ -157,14 +167,14 @@ public function testProcessingOtherElements() {
     $elements = $webform->getElementsDecoded();
     $elements['select_other']['select_other_advanced']['#default_value'] = NULL;
     $webform->setElements($elements)->save();
-    $this->drupalPostForm('/webform/test_element_other', [], t('Submit'));
-    $this->assertRaw('Select other advanced field is required.');
+    $this->drupalPostForm('/webform/test_element_other', [], 'Submit');
+    $this->assertRaw('This is a custom required error message.');
 
     // Check select other validation is skipped when #access is set to FALSE.
     $elements['select_other']['select_other_advanced']['#access'] = FALSE;
     $webform->setElements($elements)->save();
-    $this->drupalPostForm('/webform/test_element_other', [], t('Submit'));
-    $this->assertNoRaw('Select other advanced field is required.');
+    $this->drupalPostForm('/webform/test_element_other', [], 'Submit');
+    $this->assertNoRaw('This is a custom required error message.');
 
     /**************************************************************************/
     // radios_other
@@ -175,7 +185,7 @@ public function testProcessingOtherElements() {
       'radios_other_basic[radios]' => '_other_',
       'radios_other_basic[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('Radios other basic field is required.');
 
     // Check radios other not required when not checked.
@@ -183,7 +193,7 @@ public function testProcessingOtherElements() {
       'radios_other_basic[radios]' => 'One',
       'radios_other_basic[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertNoRaw('Radios other basic field is required.');
 
     // Check radios other required validation.
@@ -191,7 +201,7 @@ public function testProcessingOtherElements() {
       'radios_other_advanced[radios]' => '_other_',
       'radios_other_advanced[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('Radios other advanced field is required.');
 
     // Check radios other processing w/ other.
@@ -199,7 +209,7 @@ public function testProcessingOtherElements() {
       'radios_other_advanced[radios]' => '_other_',
       'radios_other_advanced[other]' => 'Five',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('radios_other_advanced: Five');
 
     // Check radios other processing w/o other.
@@ -208,7 +218,7 @@ public function testProcessingOtherElements() {
       // This value is ignored, because 'radios_other_advanced[radios]' is not set to '_other_'.
       'radios_other_advanced[other]' => 'Five',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('radios_other_advanced: One');
     $this->assertNoRaw('radios_other_advanced: Five');
 
@@ -221,7 +231,7 @@ public function testProcessingOtherElements() {
       'checkboxes_other_basic[checkboxes][_other_]' => TRUE,
       'checkboxes_other_basic[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('Checkboxes other basic field is required.');
 
     // Check checkboxes other not required when not checked.
@@ -229,7 +239,7 @@ public function testProcessingOtherElements() {
       'checkboxes_other_basic[checkboxes][_other_]' => FALSE,
       'checkboxes_other_basic[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertNoRaw('Checkboxes other basic field is required.');
 
     // Check checkboxes other required validation.
@@ -240,7 +250,7 @@ public function testProcessingOtherElements() {
       'checkboxes_other_advanced[checkboxes][_other_]' => TRUE,
       'checkboxes_other_advanced[other]' => '',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('Checkboxes other advanced field is required.');
 
     // Check checkboxes other processing w/ other.
@@ -251,7 +261,7 @@ public function testProcessingOtherElements() {
       'checkboxes_other_advanced[checkboxes][_other_]' => TRUE,
       'checkboxes_other_advanced[other]' => 'Five',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('checkboxes_other_advanced:
   - Five');
 
@@ -264,7 +274,7 @@ public function testProcessingOtherElements() {
       // This value is ignored, because 'radios_other_advanced[radios]' is not set to '_other_'.
       'checkboxes_other_advanced[other]' => 'Five',
     ];
-    $this->drupalPostForm('/webform/test_element_other', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_other', $edit, 'Submit');
     $this->assertRaw('checkboxes_other_advanced:
   - One');
     $this->assertNoRaw('checkboxes_other_advanced:
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementPluginDefinitionsTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementPluginDefinitionsTest.php
index 56c5d7d019..46e5cf4fbf 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementPluginDefinitionsTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementPluginDefinitionsTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform element definitions.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementPluginDefinitionsTest extends WebformElementBrowserTestBase {
 
@@ -24,7 +24,11 @@ class WebformElementPluginDefinitionsTest extends WebformElementBrowserTestBase
     'taxonomy',
     'webform',
     'webform_attachment',
-    'webform_entity_print_attachment',
+    'webform_cards',
+    // Issue #3110478: [Webform 8.x-6.x] Track the D9 readiness state of the
+    // Webform module's (optional) dependencies
+    // @see https://www.drupal.org/project/webform/issues/3110478
+    // 'webform_entity_print_attachment',
     'webform_image_select',
     'webform_location_geocomplete',
     'webform_options_custom',
@@ -45,10 +49,16 @@ public function testElementDefinitions() {
     // Comparing all element's expected and actual definitions ensures
     // that there are not unexpected changes to any element's definitions.
     $expected_definitions = $this->getExpectedElementDefinitions();
+
+    // Issue #3110478: [Webform 8.x-6.x] Track the D9 readiness state of the
+    // Webform module's (optional) dependencies
+    // @see https://www.drupal.org/project/webform/issues/3110478
+    unset($expected_definitions['webform_entity_print_attachment:pdf']);
+
     $actual_definitions = $this->getActualElementDefinitions();
     $this->htmlOutput('<pre>' . htmlentities(Yaml::encode($actual_definitions)) . '</pre>');
     foreach ($actual_definitions as $key => $actual_definition) {
-      if ($expected_definitions[$key] != $actual_definition) {
+      if ($expected_definitions[$key] !== $actual_definition) {
         $this->htmlOutput('<pre>' . Yaml::encode([$key => $actual_definition]) . '</pre>');
       }
       $this->assertEquals($expected_definitions[$key], $actual_definition, "Expected and actual '$key' element definitions match.");
@@ -638,7 +648,7 @@ class: Drupal\webform\Plugin\WebformElement\TableSelect
   dependencies: {  }
   default_key: ''
   category: 'Advanced elements'
-  description: "Provides a form element for entering a telephone number."
+  description: 'Provides a form element for entering a telephone number.'
   hidden: false
   multiline: false
   composite: false
@@ -907,6 +917,25 @@ class: Drupal\webform\Plugin\WebformElement\WebformAutocomplete
   container: false
   root: false
   multiple: true
+webform_card:
+  dependencies: {  }
+  default_key: ''
+  category: Cards
+  description: 'Provides an element for a fast clientside pagination.'
+  hidden: true
+  multiline: false
+  composite: false
+  states_wrapper: false
+  deprecated: false
+  deprecated_message: ''
+  id: webform_card
+  label: Card
+  class: Drupal\webform_cards\Plugin\WebformElement\WebformCard
+  provider: webform_cards
+  input: false
+  container: true
+  root: true
+  multiple: false
 webform_checkboxes_other:
   dependencies: {  }
   default_key: ''
@@ -1117,26 +1146,6 @@ class: Drupal\webform\Plugin\WebformElement\WebformEntityCheckboxes
   container: false
   root: false
   multiple: true
-'webform_entity_print_attachment:pdf':
-  dependencies: {  }
-  default_key: ''
-  category: 'File attachment elements'
-  description: 'Generates a PDF attachment.'
-  hidden: false
-  multiline: false
-  composite: false
-  states_wrapper: false
-  deprecated: false
-  deprecated_message: ''
-  id: webform_entity_print_attachment
-  label: 'Attachment PDF'
-  deriver: \Drupal\webform_entity_print_attachment\Plugin\Derivative\WebformEntityPrintAttachmentDeriver
-  class: Drupal\webform_entity_print_attachment\Plugin\WebformElement\WebformEntityPrintAttachment
-  provider: webform_entity_print_attachment
-  input: true
-  container: false
-  root: false
-  multiple: false
 webform_entity_radios:
   dependencies: {  }
   default_key: ''
@@ -1187,7 +1196,7 @@ class: Drupal\webform\Plugin\WebformElement\WebformEntitySelect
   deprecated: false
   deprecated_message: ''
   id: webform_flexbox
-  api: 'http://www.w3schools.com/css/css3_flexbox.asp'
+  api: 'https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox'
   label: 'Flexbox layout'
   class: Drupal\webform\Plugin\WebformElement\WebformFlexbox
   provider: webform
@@ -1521,6 +1530,25 @@ class: Drupal\webform\Plugin\WebformElement\WebformSame
   container: false
   root: false
   multiple: false
+webform_scale:
+  dependencies: {  }
+  default_key: ''
+  category: 'Advanced elements'
+  description: 'Provides a form element for input of a numeric scale.'
+  hidden: false
+  multiline: false
+  composite: false
+  states_wrapper: false
+  deprecated: false
+  deprecated_message: ''
+  id: webform_scale
+  label: Scale
+  class: Drupal\webform\Plugin\WebformElement\WebformScale
+  provider: webform
+  input: true
+  container: false
+  root: false
+  multiple: false
 webform_section:
   dependencies: {  }
   default_key: ''
@@ -1578,6 +1606,44 @@ class: Drupal\webform\Plugin\WebformElement\WebformSignature
   container: false
   root: false
   multiple: false
+webform_table:
+  dependencies: {  }
+  default_key: ''
+  category: Containers
+  description: 'Provides an element to render a table.'
+  hidden: false
+  multiline: false
+  composite: false
+  states_wrapper: false
+  deprecated: false
+  deprecated_message: ''
+  id: webform_table
+  label: Table
+  class: Drupal\webform\Plugin\WebformElement\WebformTable
+  provider: webform
+  input: false
+  container: true
+  root: false
+  multiple: false
+webform_table_row:
+  dependencies: {  }
+  default_key: ''
+  category: Containers
+  description: 'Provides an element to render a table row.'
+  hidden: true
+  multiline: false
+  composite: false
+  states_wrapper: false
+  deprecated: false
+  deprecated_message: ''
+  id: webform_table_row
+  label: 'Table row'
+  class: Drupal\webform\Plugin\WebformElement\WebformTableRow
+  provider: webform
+  input: false
+  container: true
+  root: false
+  multiple: false
 webform_table_sort:
   dependencies: {  }
   default_key: ''
@@ -1706,7 +1772,7 @@ class: Drupal\webform\Plugin\WebformElement\WebformTermsOfService
   deprecated: false
   deprecated_message: ''
   id: webform_time
-  api: 'http://www.w3schools.com/tags/tag_time.asp'
+  api: 'https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time'
   label: Time
   class: Drupal\webform\Plugin\WebformElement\WebformTime
   provider: webform
@@ -1796,7 +1862,7 @@ class: Drupal\webform\Plugin\WebformElement\WebformVideoFile
   default_key: ''
   category: Wizard
   description: 'Provides an element to display multiple form elements as a page in a multi-step form wizard.'
-  hidden: false
+  hidden: true
   multiline: false
   composite: false
   states_wrapper: false
@@ -1810,65 +1876,7 @@ class: Drupal\webform\Plugin\WebformElement\WebformWizardPage
   container: true
   root: true
   multiple: false
-webform_table:
-  dependencies: {  }
-  default_key: ''
-  category: Containers
-  description: 'Provides an element to render a table.'
-  hidden: false
-  multiline: false
-  composite: false
-  states_wrapper: false
-  deprecated: false
-  deprecated_message: ''
-  id: webform_table
-  label: Table
-  class: Drupal\webform\Plugin\WebformElement\WebformTable
-  provider: webform
-  input: false
-  container: true
-  root: false
-  multiple: false
-webform_table_row:
-  dependencies: {  }
-  default_key: ''
-  category: 'Containers'
-  description: 'Provides an element to render a table row.'
-  hidden: true
-  multiline: false
-  composite: false
-  states_wrapper: false
-  deprecated: false
-  deprecated_message: ''
-  id: webform_table_row
-  label: 'Table row'
-  class: Drupal\webform\Plugin\WebformElement\WebformTableRow
-  provider: webform
-  input: false
-  container: true
-  root: false
-  multiple: false
-webform_scale:
-  dependencies: {  }
-  default_key: ''
-  category: 'Advanced elements'
-  description: 'Provides a form element for input of a numeric scale.'
-  id: webform_scale
-  label: Scale
-  class: Drupal\webform\Plugin\WebformElement\WebformScale
-  provider: webform
-  input: true
-  container: false
-  root: false
-  multiple: false
-  hidden: false
-  multiline: false
-  composite: false
-  states_wrapper: false
-  deprecated: false
-  deprecated_message: ''
 YAML;
-
     return Yaml::decode($yaml);
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementPluginPropertiesTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementPluginPropertiesTest.php
index 64a6926167..35e4336efa 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementPluginPropertiesTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementPluginPropertiesTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform element properties.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementPluginPropertiesTest extends WebformElementBrowserTestBase {
 
@@ -24,7 +24,11 @@ class WebformElementPluginPropertiesTest extends WebformElementBrowserTestBase {
     'taxonomy',
     'webform',
     'webform_attachment',
-    'webform_entity_print_attachment',
+    'webform_cards',
+    // Issue #3110478: [Webform 8.x-6.x] Track the D9 readiness state of the
+    // Webform module's (optional) dependencies
+    // @see https://www.drupal.org/project/webform/issues/3110478
+    // 'webform_entity_print_attachment',
     'webform_image_select',
     'webform_location_geocomplete',
     'webform_options_custom',
@@ -46,10 +50,16 @@ public function testElementDefaultProperties() {
     // that there are not unexpected changes to any element's
     // default properties.
     $expected_elements = $this->getExpectedElementDefaultProperties();
+
+    // Issue #3110478: [Webform 8.x-6.x] Track the D9 readiness state of the
+    // Webform module's (optional) dependencies
+    // @see https://www.drupal.org/project/webform/issues/3110478
+    unset($expected_elements['webform_entity_print_attachment:pdf']);
+
     $actual_elements = $this->getActualElementDefaultProperties();
     $this->htmlOutput('<pre>' . htmlentities(Yaml::encode($actual_elements)) . '</pre>');
     foreach ($actual_elements as $element_key => $actual_element) {
-      if ($expected_elements[$element_key] != $actual_element) {
+      if ($expected_elements[$element_key] !== $actual_element) {
         $this->htmlOutput('<pre>' . Yaml::encode([$element_key => $actual_element]) . '</pre>');
       }
       $this->assertEquals($expected_elements[$element_key], $actual_element, "Expected and actual '$element_key' element properties match.");
@@ -134,7 +144,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -189,9 +200,9 @@ protected function getExpectedElementDefaultProperties() {
   more_title: ''
   prepopulate: false
   private: false
-  return_value: ''
   required: false
   required_error: ''
+  return_value: ''
   states: {  }
   states_clear: true
   title: ''
@@ -239,8 +250,14 @@ protected function getExpectedElementDefaultProperties() {
   multiple_error: ''
   options: {  }
   options__properties: {  }
+  options_all: false
+  options_all_text: 'All of the above'
+  options_all_value: all
   options_description_display: description
   options_display: one_column
+  options_none: false
+  options_none_text: 'None of the above'
+  options_none_value: none
   options_randomize: false
   prepopulate: false
   private: false
@@ -374,7 +391,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -463,7 +481,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -549,7 +568,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -642,8 +662,8 @@ protected function getExpectedElementDefaultProperties() {
   help_title: ''
   input_hide: false
   label_attributes: {  }
-  maxlength: ''
-  minlength: ''
+  maxlength: null
+  minlength: null
   more: ''
   more_title: ''
   multiple: false
@@ -654,7 +674,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -666,7 +687,7 @@ protected function getExpectedElementDefaultProperties() {
   readonly: false
   required: false
   required_error: ''
-  size: ''
+  size: null
   states: {  }
   states_clear: true
   title: ''
@@ -722,7 +743,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -1054,8 +1076,8 @@ protected function getExpectedElementDefaultProperties() {
   help_display: ''
   help_title: ''
   label_attributes: {  }
-  max: ''
-  min: ''
+  max: null
+  min: null
   more: ''
   more_title: ''
   multiple: false
@@ -1066,7 +1088,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -1079,7 +1102,7 @@ protected function getExpectedElementDefaultProperties() {
   size: ''
   states: {  }
   states_clear: true
-  step: ''
+  step: null
   title: ''
   title_display: ''
   unique: false
@@ -1256,8 +1279,8 @@ protected function getExpectedElementDefaultProperties() {
   help_display: ''
   help_title: ''
   label_attributes: {  }
-  maxlength: ''
-  minlength: ''
+  maxlength: null
+  minlength: null
   more: ''
   more_title: ''
   pattern: ''
@@ -1268,7 +1291,7 @@ protected function getExpectedElementDefaultProperties() {
   readonly: false
   required: false
   required_error: ''
-  size: ''
+  size: null
   states: {  }
   states_clear: true
   title: ''
@@ -1331,6 +1354,7 @@ protected function getExpectedElementDefaultProperties() {
   required_error: ''
   select2: false
   size: ''
+  sort_options: false
   states: {  }
   states_clear: true
   title: ''
@@ -1452,6 +1476,7 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
+  multiple__item_label: item
   multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
@@ -1532,9 +1557,9 @@ protected function getExpectedElementDefaultProperties() {
   admin_title: ''
   attributes: {  }
   autocomplete: 'on'
-  counter_maximum: ''
+  counter_maximum: null
   counter_maximum_message: ''
-  counter_minimum: ''
+  counter_minimum: null
   counter_minimum_message: ''
   counter_type: ''
   default_value: ''
@@ -1555,8 +1580,8 @@ protected function getExpectedElementDefaultProperties() {
   help_display: ''
   help_title: ''
   label_attributes: {  }
-  maxlength: ''
-  minlength: ''
+  maxlength: null
+  minlength: null
   more: ''
   more_title: ''
   multiple: false
@@ -1567,7 +1592,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -1579,8 +1605,8 @@ protected function getExpectedElementDefaultProperties() {
   readonly: false
   required: false
   required_error: ''
-  rows: ''
-  size: ''
+  rows: null
+  size: null
   states: {  }
   states_clear: true
   title: ''
@@ -1609,9 +1635,9 @@ protected function getExpectedElementDefaultProperties() {
   admin_title: ''
   attributes: {  }
   autocomplete: 'on'
-  counter_maximum: ''
+  counter_maximum: null
   counter_maximum_message: ''
-  counter_minimum: ''
+  counter_minimum: null
   counter_minimum_message: ''
   counter_type: ''
   default_value: ''
@@ -1634,8 +1660,8 @@ protected function getExpectedElementDefaultProperties() {
   input_hide: false
   input_mask: ''
   label_attributes: {  }
-  maxlength: ''
-  minlength: ''
+  maxlength: null
+  minlength: null
   more: ''
   more_title: ''
   multiple: false
@@ -1646,7 +1672,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -1658,7 +1685,7 @@ protected function getExpectedElementDefaultProperties() {
   readonly: false
   required: false
   required_error: ''
-  size: ''
+  size: null
   states: {  }
   states_clear: true
   title: ''
@@ -1706,8 +1733,8 @@ protected function getExpectedElementDefaultProperties() {
   help_title: ''
   input_hide: false
   label_attributes: {  }
-  maxlength: ''
-  minlength: ''
+  maxlength: null
+  minlength: null
   more: ''
   more_title: ''
   multiple: false
@@ -1718,7 +1745,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -1730,7 +1758,7 @@ protected function getExpectedElementDefaultProperties() {
   readonly: false
   required: false
   required_error: ''
-  size: ''
+  size: null
   states: {  }
   states_clear: true
   title: ''
@@ -1894,7 +1922,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__empty_items: 1
   multiple__header: false
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -2103,9 +2132,9 @@ protected function getExpectedElementDefaultProperties() {
   autocomplete_limit: 10
   autocomplete_match: 3
   autocomplete_match_operator: CONTAINS
-  counter_maximum: ''
+  counter_maximum: null
   counter_maximum_message: ''
-  counter_minimum: ''
+  counter_minimum: null
   counter_minimum_message: ''
   counter_type: ''
   default_value: ''
@@ -2128,8 +2157,8 @@ protected function getExpectedElementDefaultProperties() {
   input_hide: false
   input_mask: ''
   label_attributes: {  }
-  maxlength: ''
-  minlength: ''
+  maxlength: null
+  minlength: null
   more: ''
   more_title: ''
   multiple: false
@@ -2140,7 +2169,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -2152,7 +2182,7 @@ protected function getExpectedElementDefaultProperties() {
   readonly: false
   required: false
   required_error: ''
-  size: ''
+  size: null
   states: {  }
   states_clear: true
   title: ''
@@ -2162,6 +2192,36 @@ protected function getExpectedElementDefaultProperties() {
   unique_error: ''
   unique_user: false
   wrapper_attributes: {  }
+webform_card:
+  access_create_permissions: {  }
+  access_create_roles:
+    - anonymous
+    - authenticated
+  access_create_users: {  }
+  access_update_permissions: {  }
+  access_update_roles:
+    - anonymous
+    - authenticated
+  access_update_users: {  }
+  access_view_permissions: {  }
+  access_view_roles:
+    - anonymous
+    - authenticated
+  access_view_users: {  }
+  admin_title: ''
+  format: details
+  format_attributes: {  }
+  format_html: ''
+  format_text: ''
+  next_button_label: ''
+  prev_button_label: ''
+  private: false
+  states: {  }
+  states_clear: true
+  title: ''
+  title_attributes: {  }
+  title_display: ''
+  title_tag: h2
 webform_checkboxes_other:
   access_create_permissions: {  }
   access_create_roles:
@@ -2206,6 +2266,9 @@ protected function getExpectedElementDefaultProperties() {
   options__properties: {  }
   options_description_display: description
   options_display: one_column
+  options_none: false
+  options_none_text: 'None of the above'
+  options_none_value: none
   options_randomize: false
   other__counter_maximum: ''
   other__counter_maximum_message: ''
@@ -2466,7 +2529,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__empty_items: 1
   multiple__header: false
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -2563,7 +2627,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__empty_items: 1
   multiple__header: true
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -2679,8 +2744,8 @@ protected function getExpectedElementDefaultProperties() {
   help_title: ''
   input_hide: false
   label_attributes: {  }
-  maxlength: ''
-  minlength: ''
+  maxlength: null
+  minlength: null
   more: ''
   more_title: ''
   multiple__add_more: true
@@ -2689,7 +2754,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_input_label: 'more items'
   multiple__add_more_items: 1
   multiple__empty_items: 1
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -2701,7 +2767,7 @@ protected function getExpectedElementDefaultProperties() {
   readonly: false
   required: false
   required_error: ''
-  size: ''
+  size: null
   states: {  }
   states_clear: true
   title: ''
@@ -2747,8 +2813,8 @@ protected function getExpectedElementDefaultProperties() {
   help_title: ''
   input_hide: false
   label_attributes: {  }
-  maxlength: ''
-  minlength: ''
+  maxlength: null
+  minlength: null
   more: ''
   more_title: ''
   multiple__add_more: true
@@ -2758,7 +2824,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -2770,7 +2837,7 @@ protected function getExpectedElementDefaultProperties() {
   readonly: false
   required: false
   required_error: ''
-  size: ''
+  size: null
   states: {  }
   states_clear: true
   title: ''
@@ -2821,6 +2888,9 @@ protected function getExpectedElementDefaultProperties() {
   multiple: true
   multiple_error: ''
   options__properties: {  }
+  options_all: false
+  options_all_text: 'All of the above'
+  options_all_value: all
   options_display: one_column
   options_randomize: false
   prepopulate: false
@@ -2840,37 +2910,6 @@ protected function getExpectedElementDefaultProperties() {
   unique_user: false
   wrapper_attributes: {  }
   wrapper_type: fieldset
-'webform_entity_print_attachment:pdf':
-  access_create_permissions: {  }
-  access_create_roles:
-    - anonymous
-    - authenticated
-  access_create_users: {  }
-  access_update_permissions: {  }
-  access_update_roles:
-    - anonymous
-    - authenticated
-  access_update_users: {  }
-  access_view_permissions: {  }
-  access_view_roles:
-    - anonymous
-    - authenticated
-  access_view_users: {  }
-  admin_title: ''
-  display_on: none
-  download: false
-  filename: ''
-  flex: 1
-  label_attributes: {  }
-  link_title: ''
-  private: false
-  sanitize: false
-  states: {  }
-  template: ''
-  title: ''
-  title_display: ''
-  view_mode: html
-  wrapper_attributes: {  }
 webform_entity_radios:
   access_create_permissions: {  }
   access_create_roles:
@@ -2980,6 +3019,7 @@ protected function getExpectedElementDefaultProperties() {
   selection_handler: ''
   selection_settings: {  }
   size: ''
+  sort_options: false
   states: {  }
   states_clear: true
   target_type: ''
@@ -3125,6 +3165,7 @@ protected function getExpectedElementDefaultProperties() {
   required_error: ''
   show_label: false
   size: ''
+  sort_options: false
   states: {  }
   states_clear: true
   title: ''
@@ -3234,7 +3275,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__empty_items: 1
   multiple__header: false
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -3263,6 +3305,81 @@ protected function getExpectedElementDefaultProperties() {
   url__type: url
   wrapper_attributes: {  }
   wrapper_type: fieldset
+webform_location_geocomplete:
+  access_create_permissions: {  }
+  access_create_roles:
+    - anonymous
+    - authenticated
+  access_create_users: {  }
+  access_update_permissions: {  }
+  access_update_roles:
+    - anonymous
+    - authenticated
+  access_update_users: {  }
+  access_view_permissions: {  }
+  access_view_roles:
+    - anonymous
+    - authenticated
+  access_view_users: {  }
+  admin_title: ''
+  administrative_area_level_1__access: false
+  administrative_area_level_1__title: State/Province
+  api_key: ''
+  country__access: false
+  country__title: Country
+  country_short__access: false
+  country_short__title: 'Country Code'
+  default_value: {  }
+  description: ''
+  description_display: ''
+  disabled: false
+  flex: 1
+  format: value
+  format_html: ''
+  format_items: ul
+  format_items_html: ''
+  format_items_text: ''
+  format_text: ''
+  formatted_address__access: false
+  formatted_address__title: 'Formatted Address'
+  geolocation: false
+  help: ''
+  help_title: ''
+  hidden: false
+  label_attributes: {  }
+  lat__access: false
+  lat__title: Latitude
+  lng__access: false
+  lng__title: Longitude
+  locality__access: false
+  locality__title: Locality
+  location__access: false
+  location__title: Location
+  map: false
+  more: ''
+  more_title: ''
+  multiple: false
+  postal_code__access: false
+  postal_code__title: 'Postal Code'
+  prepopulate: false
+  private: false
+  required: false
+  required_error: ''
+  states: {  }
+  states_clear: true
+  street_address__access: false
+  street_address__title: 'Street Address'
+  street_number__access: false
+  street_number__title: 'Street Number'
+  sublocality__access: false
+  sublocality__title: City
+  subpremise__access: false
+  subpremise__title: Unit
+  title: ''
+  title_display: ''
+  value__placeholder: ''
+  value__title: Address
+  wrapper_attributes: {  }
 webform_location_places:
   access_create_permissions: {  }
   access_create_roles:
@@ -3539,7 +3656,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__empty_items: 1
   multiple__header: false
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -3624,6 +3742,7 @@ protected function getExpectedElementDefaultProperties() {
   required_error: ''
   select2: false
   size: ''
+  sort_options: false
   states: {  }
   states_clear: true
   title: ''
@@ -3687,6 +3806,7 @@ protected function getExpectedElementDefaultProperties() {
   required_error: ''
   select2: false
   size: ''
+  sort_options: false
   states: {  }
   states_clear: true
   title: ''
@@ -3869,6 +3989,63 @@ protected function getExpectedElementDefaultProperties() {
   title: ''
   title_display: after
   wrapper_attributes: {  }
+webform_scale:
+  access_create_permissions: {  }
+  access_create_roles:
+    - anonymous
+    - authenticated
+  access_create_users: {  }
+  access_update_permissions: {  }
+  access_update_roles:
+    - anonymous
+    - authenticated
+  access_update_users: {  }
+  access_view_permissions: {  }
+  access_view_roles:
+    - anonymous
+    - authenticated
+  access_view_users: {  }
+  admin_title: ''
+  attributes: {  }
+  default_value: ''
+  description: ''
+  description_display: ''
+  disabled: false
+  field_prefix: ''
+  field_suffix: ''
+  flex: 1
+  format: value
+  format_attributes: {  }
+  format_html: ''
+  format_text: ''
+  help: ''
+  help_display: ''
+  help_title: ''
+  label_attributes: {  }
+  max: 5
+  max_text: ''
+  min: 1
+  min_text: ''
+  more: ''
+  more_title: ''
+  prepopulate: false
+  private: false
+  readonly: false
+  required: false
+  required_error: ''
+  scale_size: medium
+  scale_text: below
+  scale_type: circle
+  states: {  }
+  states_clear: true
+  title: ''
+  title_display: ''
+  unique: false
+  unique_entity: false
+  unique_error: ''
+  unique_user: false
+  wrapper_attributes: {  }
+  wrapper_type: fieldset
 webform_section:
   access_create_permissions: {  }
   access_create_roles:
@@ -3904,6 +4081,7 @@ protected function getExpectedElementDefaultProperties() {
   states: {  }
   states_clear: true
   title: ''
+  title_attributes: {  }
   title_display: ''
   title_tag: h2
 webform_select_other:
@@ -3977,6 +4155,7 @@ protected function getExpectedElementDefaultProperties() {
   required_error: ''
   select2: false
   size: ''
+  sort_options: false
   states: {  }
   states_clear: true
   title: ''
@@ -4036,7 +4215,7 @@ protected function getExpectedElementDefaultProperties() {
   unique_error: ''
   unique_user: false
   wrapper_attributes: {  }
-webform_table_sort:
+webform_table:
   access_create_permissions: {  }
   access_create_roles:
     - anonymous
@@ -4054,19 +4233,88 @@ protected function getExpectedElementDefaultProperties() {
   access_view_users: {  }
   admin_title: ''
   attributes: {  }
+  caption: ''
   default_value: ''
   description: ''
   description_display: ''
-  disabled: false
   field_prefix: ''
   field_suffix: ''
   flex: 1
-  format: ol
+  format: table
   format_attributes: {  }
   format_html: ''
-  format_items: comma
-  format_items_html: ''
-  format_items_text: ''
+  format_text: ''
+  header: {  }
+  help: ''
+  help_display: ''
+  help_title: ''
+  label_attributes: {  }
+  more: ''
+  more_title: ''
+  prefix_children: true
+  private: false
+  required: false
+  required_error: ''
+  states: {  }
+  states_clear: true
+  sticky: false
+  title: ''
+  title_display: ''
+  wrapper_attributes: {  }
+webform_table_row:
+  access_create_permissions: {  }
+  access_create_roles:
+    - anonymous
+    - authenticated
+  access_create_users: {  }
+  access_update_permissions: {  }
+  access_update_roles:
+    - anonymous
+    - authenticated
+  access_update_users: {  }
+  access_view_permissions: {  }
+  access_view_roles:
+    - anonymous
+    - authenticated
+  access_view_users: {  }
+  admin_title: ''
+  attributes: {  }
+  flex: 1
+  private: false
+  states: {  }
+  states_clear: true
+  title: ''
+webform_table_sort:
+  access_create_permissions: {  }
+  access_create_roles:
+    - anonymous
+    - authenticated
+  access_create_users: {  }
+  access_update_permissions: {  }
+  access_update_roles:
+    - anonymous
+    - authenticated
+  access_update_users: {  }
+  access_view_permissions: {  }
+  access_view_roles:
+    - anonymous
+    - authenticated
+  access_view_users: {  }
+  admin_title: ''
+  attributes: {  }
+  default_value: ''
+  description: ''
+  description_display: ''
+  disabled: false
+  field_prefix: ''
+  field_suffix: ''
+  flex: 1
+  format: ol
+  format_attributes: {  }
+  format_html: ''
+  format_items: comma
+  format_items_html: ''
+  format_items_text: ''
   format_text: ''
   help: ''
   help_display: ''
@@ -4201,7 +4449,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__empty_items: 1
   multiple__header: false
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -4277,7 +4526,13 @@ protected function getExpectedElementDefaultProperties() {
   multiple: true
   multiple_error: ''
   options__properties: {  }
+  options_all: false
+  options_all_text: 'All of the above'
+  options_all_value: all
   options_description_display: description
+  options_none: false
+  options_none_text: 'None of the above'
+  options_none_value: none
   prepopulate: false
   private: false
   required: false
@@ -4451,7 +4706,8 @@ protected function getExpectedElementDefaultProperties() {
   multiple__add_more_items: 1
   multiple__empty_items: 1
   multiple__header_label: ''
-  multiple__min_items: ''
+  multiple__item_label: item
+  multiple__min_items: null
   multiple__no_items_message: 'No items entered. Please add items below.'
   multiple__operations: true
   multiple__sorting: true
@@ -4472,7 +4728,7 @@ protected function getExpectedElementDefaultProperties() {
   unique_error: ''
   unique_user: false
   wrapper_attributes: {  }
-webform_variant:
+webform_toggle:
   access_create_permissions: {  }
   access_create_roles:
     - anonymous
@@ -4490,12 +4746,16 @@ protected function getExpectedElementDefaultProperties() {
   access_view_users: {  }
   admin_title: ''
   attributes: {  }
-  default_value: ''
+  default_value: false
   description: ''
   description_display: ''
-  display_on: none
+  disabled: false
+  exclude_empty: false
+  field_prefix: ''
+  field_suffix: ''
   flex: 1
   format: value
+  format_attributes: {  }
   format_html: ''
   format_text: ''
   help: ''
@@ -4504,14 +4764,20 @@ protected function getExpectedElementDefaultProperties() {
   label_attributes: {  }
   more: ''
   more_title: ''
-  prepopulate: true
+  off_text: ''
+  on_text: ''
+  prepopulate: false
   private: false
-  randomize: false
+  required_error: ''
+  return_value: ''
+  states: {  }
+  states_clear: true
   title: ''
-  title_display: ''
-  variant: ''
+  title_display: after
+  toggle_size: medium
+  toggle_theme: light
   wrapper_attributes: {  }
-webform_video_file:
+webform_toggles:
   access_create_permissions: {  }
   access_create_roles:
     - anonymous
@@ -4529,25 +4795,17 @@ protected function getExpectedElementDefaultProperties() {
   access_view_users: {  }
   admin_title: ''
   attributes: {  }
-  button: false
-  button__attributes: {  }
-  button__title: ''
   default_value: ''
   description: ''
   description_display: ''
   disabled: false
   field_prefix: ''
   field_suffix: ''
-  file_extensions: 'avi mov mp4 ogg wav webm'
-  file_help: ''
-  file_name: ''
-  file_placeholder: ''
-  file_preview: ''
   flex: 1
-  format: file
+  format: value
   format_attributes: {  }
   format_html: ''
-  format_items: ul
+  format_items: comma
   format_items_html: ''
   format_items_text: ''
   format_text: ''
@@ -4555,25 +4813,27 @@ protected function getExpectedElementDefaultProperties() {
   help_display: ''
   help_title: ''
   label_attributes: {  }
-  max_filesize: ''
   more: ''
   more_title: ''
-  multiple: false
+  off_text: ''
+  on_text: ''
+  options: {  }
+  options_randomize: false
+  prepopulate: false
   private: false
-  required: false
   required_error: ''
-  sanitize: false
   states: {  }
   states_clear: true
   title: ''
   title_display: ''
+  toggle_size: medium
+  toggle_theme: light
   unique: false
   unique_entity: false
   unique_error: ''
   unique_user: false
-  uri_scheme: private
   wrapper_attributes: {  }
-webform_wizard_page:
+webform_variant:
   access_create_permissions: {  }
   access_create_roles:
     - anonymous
@@ -4590,198 +4850,29 @@ protected function getExpectedElementDefaultProperties() {
     - authenticated
   access_view_users: {  }
   admin_title: ''
-  format: details
-  format_attributes: {  }
-  format_html: ''
-  format_text: ''
-  next_button_label: ''
-  open: false
-  prev_button_label: ''
-  private: false
-  states: {  }
-  states_clear: true
-  title: ''
-webform_location_geocomplete:
-  geolocation: false
-  hidden: false
-  map: false
-  api_key: ''
-  title: ''
-  default_value: {  }
-  multiple: false
-  help: ''
-  help_title: ''
+  attributes: {  }
+  default_value: ''
   description: ''
-  more: ''
-  more_title: ''
-  title_display: ''
   description_display: ''
-  disabled: false
-  required: false
-  required_error: ''
-  wrapper_attributes: {  }
-  label_attributes: {  }
+  display_on: none
+  flex: 1
   format: value
   format_html: ''
   format_text: ''
-  format_items: ul
-  format_items_html: ''
-  format_items_text: ''
-  admin_title: ''
-  prepopulate: false
-  private: false
-  flex: 1
-  states: {  }
-  states_clear: true
-  access_create_roles:
-    - anonymous
-    - authenticated
-  access_create_users: {  }
-  access_create_permissions: {  }
-  access_update_roles:
-    - anonymous
-    - authenticated
-  access_update_users: {  }
-  access_update_permissions: {  }
-  access_view_roles:
-    - anonymous
-    - authenticated
-  access_view_users: {  }
-  access_view_permissions: {  }
-  value__title: Address
-  value__placeholder: ''
-  lat__title: Latitude
-  lat__access: false
-  lng__title: Longitude
-  lng__access: false
-  location__title: Location
-  location__access: false
-  formatted_address__title: 'Formatted Address'
-  formatted_address__access: false
-  street_address__title: 'Street Address'
-  street_address__access: false
-  street_number__title: 'Street Number'
-  street_number__access: false
-  subpremise__title: Unit
-  subpremise__access: false
-  postal_code__title: 'Postal Code'
-  postal_code__access: false
-  locality__title: Locality
-  locality__access: false
-  sublocality__title: City
-  sublocality__access: false
-  administrative_area_level_1__title: State/Province
-  administrative_area_level_1__access: false
-  country__title: Country
-  country__access: false
-  country_short__title: 'Country Code'
-  country_short__access: false
-webform_toggle:
-  toggle_theme: light
-  toggle_size: medium
-  on_text: ''
-  off_text: ''
-  title_display: after
-  exclude_empty: false
-  default_value: false
-  title: ''
   help: ''
+  help_display: ''
   help_title: ''
-  description: ''
+  label_attributes: {  }
   more: ''
   more_title: ''
-  description_display: ''
-  help_display: ''
-  field_prefix: ''
-  field_suffix: ''
-  disabled: false
-  required_error: ''
-  wrapper_attributes: {  }
-  label_attributes: {  }
-  attributes: {  }
-  format: value
-  format_html: ''
-  format_text: ''
-  format_attributes: {  }
-  admin_title: ''
-  prepopulate: false
+  prepopulate: true
   private: false
-  flex: 1
-  return_value: ''
-  states: {  }
-  states_clear: true
-  access_create_roles:
-    - anonymous
-    - authenticated
-  access_create_users: {  }
-  access_create_permissions: {  }
-  access_update_roles:
-    - anonymous
-    - authenticated
-  access_update_users: {  }
-  access_update_permissions: {  }
-  access_view_roles:
-    - anonymous
-    - authenticated
-  access_view_users: {  }
-  access_view_permissions: {  }
-webform_toggles:
-  toggle_theme: light
-  toggle_size: medium
-  on_text: ''
-  off_text: ''
-  options: {  }
-  options_randomize: false
+  randomize: false
   title: ''
-  default_value: ''
-  help: ''
-  help_title: ''
-  description: ''
-  more: ''
-  more_title: ''
   title_display: ''
-  description_display: ''
-  help_display: ''
-  field_prefix: ''
-  field_suffix: ''
-  disabled: false
-  required_error: ''
+  variant: ''
   wrapper_attributes: {  }
-  label_attributes: {  }
-  attributes: {  }
-  format: value
-  format_html: ''
-  format_text: ''
-  format_items: comma
-  format_items_html: ''
-  format_items_text: ''
-  format_attributes: {  }
-  unique: false
-  unique_user: false
-  unique_entity: false
-  unique_error: ''
-  admin_title: ''
-  prepopulate: false
-  private: false
-  flex: 1
-  states: {  }
-  states_clear: true
-  access_create_roles:
-    - anonymous
-    - authenticated
-  access_create_users: {  }
-  access_create_permissions: {  }
-  access_update_roles:
-    - anonymous
-    - authenticated
-  access_update_users: {  }
-  access_update_permissions: {  }
-  access_view_roles:
-    - anonymous
-    - authenticated
-  access_view_users: {  }
-  access_view_permissions: {  }
-webform_table:
+webform_video_file:
   access_create_permissions: {  }
   access_create_roles:
     - anonymous
@@ -4799,58 +4890,51 @@ protected function getExpectedElementDefaultProperties() {
   access_view_users: {  }
   admin_title: ''
   attributes: {  }
-  caption: ''
+  button: false
+  button__attributes: {  }
+  button__title: ''
   default_value: ''
   description: ''
   description_display: ''
+  disabled: false
   field_prefix: ''
   field_suffix: ''
+  file_extensions: 'avi mov mp4 ogg wav webm'
+  file_help: ''
+  file_name: ''
+  file_placeholder: ''
+  file_preview: ''
   flex: 1
-  format: table
+  format: file
   format_attributes: {  }
   format_html: ''
+  format_items: ul
+  format_items_html: ''
+  format_items_text: ''
   format_text: ''
-  header: {  }
   help: ''
   help_display: ''
   help_title: ''
   label_attributes: {  }
+  max_filesize: ''
   more: ''
   more_title: ''
-  prefix_children: true
+  multiple: false
   private: false
   required: false
   required_error: ''
+  sanitize: false
   states: {  }
   states_clear: true
-  sticky: false
   title: ''
   title_display: ''
+  unique: false
+  unique_entity: false
+  unique_error: ''
+  unique_user: false
+  uri_scheme: private
   wrapper_attributes: {  }
-webform_table_row:
-  access_create_permissions: {  }
-  access_create_roles:
-    - anonymous
-    - authenticated
-  access_create_users: {  }
-  access_update_permissions: {  }
-  access_update_roles:
-    - anonymous
-    - authenticated
-  access_update_users: {  }
-  access_view_permissions: {  }
-  access_view_roles:
-    - anonymous
-    - authenticated
-  access_view_users: {  }
-  admin_title: ''
-  attributes: {  }
-  flex: 1
-  private: false
-  states: {  }
-  states_clear: true
-  title: ''
-webform_scale:
+webform_wizard_page:
   access_create_permissions: {  }
   access_create_roles:
     - anonymous
@@ -4868,45 +4952,17 @@ protected function getExpectedElementDefaultProperties() {
   access_view_users: {  }
   admin_title: ''
   attributes: {  }
-  default_value: ''
-  description: ''
-  description_display: ''
-  disabled: false
-  field_prefix: ''
-  field_suffix: ''
-  flex: 1
-  format: value
+  format: details
   format_attributes: {  }
   format_html: ''
   format_text: ''
-  help: ''
-  help_display: ''
-  help_title: ''
-  label_attributes: {  }
-  max: 5
-  max_text: ''
-  min: 1
-  min_text: ''
-  more: ''
-  more_title: ''
-  prepopulate: false
+  next_button_label: ''
+  open: false
+  prev_button_label: ''
   private: false
-  readonly: false
-  required: false
-  required_error: ''
-  scale_size: medium
-  scale_text: below
-  scale_type: circle
   states: {  }
   states_clear: true
   title: ''
-  title_display: ''
-  unique: false
-  unique_entity: false
-  unique_error: ''
-  unique_user: false
-  wrapper_attributes: {  }
-  wrapper_type: fieldset
 YAML;
     return Yaml::decode($yaml);
   }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementPluginTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementPluginTest.php
index a7ffccfd2e..04b3fd5476 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementPluginTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementPluginTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for the webform element plugin.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementPluginTest extends WebformElementBrowserTestBase {
 
@@ -77,7 +77,7 @@ public function testElementPlugin() {
     $this->assertRaw('Invoked: Drupal\webform_test_element\Plugin\WebformElement\WebformTestElement:postLoad');
 
     // Check update.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_element_plugin/submission/' . $sid . '/edit', [], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_plugin/submission/' . $sid . '/edit', [], 'Save');
     $this->assertRaw('Invoked: Drupal\webform_test_element\Plugin\WebformElement\WebformTestElement:postLoad');
     $this->assertRaw('Invoked: Drupal\webform_test_element\Plugin\WebformElement\WebformTestElement:prepare');
     $this->assertRaw('Invoked: Drupal\webform_test_element\Plugin\WebformElement\WebformTestElement:setDefaultValue');
@@ -97,7 +97,7 @@ public function testElementPlugin() {
     $this->assertRaw('Invoked: Drupal\webform_test_element\Plugin\WebformElement\WebformTestElement:formatText');
 
     // Check delete.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_element_plugin/submission/' . $sid . '/delete', [], t('Delete'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_plugin/submission/' . $sid . '/delete', [], 'Delete');
     $this->assertRaw('Invoked: Drupal\webform_test_element\Plugin\WebformElement\WebformTestElement:preDelete');
     $this->assertRaw('Invoked: Drupal\webform_test_element\Plugin\WebformElement\WebformTestElement:postDelete');
     $this->assertRaw('<em class="placeholder">Test: Element: Test (plugin): Submission #' . $webform_submission->serial() . '</em> has been deleted.');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementPrepopulateTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementPrepopulateTest.php
index 714f56d38a..9da0ec5510 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementPrepopulateTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementPrepopulateTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform element prepopulate.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementPrepopulateTest extends WebformElementBrowserTestBase {
 
@@ -42,7 +42,7 @@ public function testElementPrepopulate() {
     $this->assertFieldByName('textfield_01', '');
     $this->assertFieldByName('textfield_prepopulate_01', '{default_value_01}');
     $this->assertFieldByName('files[managed_file_prepopulate_01]', '');
-    $this->drupalPostForm('/webform/test_element_prepopulate', [], t('Next Page >'));
+    $this->drupalPostForm('/webform/test_element_prepopulate', [], 'Next >');
     $this->assertFieldByName('textfield_02', '');
     $this->assertFieldByName('textfield_prepopulate_02', '{default_value_02}');
 
@@ -59,7 +59,7 @@ public function testElementPrepopulate() {
     ];
     $this->drupalGet('/webform/test_element_prepopulate', $options);
     $this->assertFieldByName('textfield_prepopulate_01', 'value_01');
-    $this->drupalPostForm('/webform/test_element_prepopulate', [], t('Next Page >'), $options);
+    $this->drupalPostForm('/webform/test_element_prepopulate', [], 'Next >', $options);
     $this->assertFieldByName('textfield_prepopulate_02', 'value_02');
 
     // Check prepopulating textfield on multiple pages and changing the value
@@ -71,9 +71,9 @@ public function testElementPrepopulate() {
     ];
     $this->drupalGet('/webform/test_element_prepopulate', $options);
     $this->assertFieldByName('textfield_prepopulate_01', 'value_01');
-    $this->drupalPostForm('/webform/test_element_prepopulate', ['textfield_prepopulate_01' => 'edit_01'], t('Next Page >'), $options);
+    $this->drupalPostForm('/webform/test_element_prepopulate', ['textfield_prepopulate_01' => 'edit_01'], 'Next >', $options);
     $this->assertFieldByName('textfield_prepopulate_02', 'value_02');
-    $this->drupalPostForm(NULL, [], t('< Previous Page'), $options);
+    $this->drupalPostForm(NULL, [], '< Previous', $options);
     $this->assertNoFieldByName('textfield_prepopulate_01', 'value_01');
     $this->assertFieldByName('textfield_prepopulate_01', 'edit_01');
 
@@ -83,8 +83,8 @@ public function testElementPrepopulate() {
     $edit = [
       'files[managed_file_prepopulate_01]' => \Drupal::service('file_system')->realpath($files[0]->uri),
     ];
-    $this->drupalPostForm('/webform/test_element_prepopulate', $edit, t('Next Page >'));
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_prepopulate', $edit, 'Next >');
+    $this->drupalPostForm(NULL, [], 'Submit');
     $sid = $this->getLastSubmissionId($webform);
     $webform_submission = WebformSubmission::load($sid);
     $fid = $webform_submission->getElementData('managed_file_prepopulate_01');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementPrivateTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementPrivateTest.php
index e4170f725e..15149dbd6a 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementPrivateTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementPrivateTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform element private.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementPrivateTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementRadiosTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementRadiosTest.php
index 71754f6e99..2b84293beb 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementRadiosTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementRadiosTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform element radios.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementRadiosTest extends WebformElementBrowserTestBase {
 
@@ -38,6 +38,12 @@ public function testElementRadios() {
     $this->assertRaw('<input data-drupal-selector="edit-radios-buttons-yes" class="visually-hidden form-radio" type="radio" id="edit-radios-buttons-yes" name="radios_buttons" value="Yes" />');
     $this->assertRaw('<label class="webform-options-display-buttons-label option" for="edit-radios-buttons-yes">Yes</label>');
 
+    // Check radios displayed as buttons_horizontal.
+    $this->assertRaw('<div id="edit-radios-buttons-horizontal" class="js-webform-radios webform-options-display-buttons webform-options-display-buttons-horizontal form-radios"><div class="webform-options-display-buttons-wrapper">');
+
+    // Check radios displayed as buttons_vertical.
+    $this->assertRaw('<div id="edit-radios-buttons-vertical" class="js-webform-radios webform-options-display-buttons webform-options-display-buttons-vertical form-radios"><div class="webform-options-display-buttons-wrapper">');
+
     // Check radios displayed as buttons with description.
     $this->assertRaw('<label class="webform-options-display-buttons-label option" for="edit-radios-buttons-description-one"><div class="webform-options-display-buttons-title">One</div><div class="webform-options-display-buttons-description description">This is a description</div></label>');
 
@@ -61,7 +67,7 @@ public function testElementRadios() {
       'radios_description' => 'one',
       'radios_help' => 'two',
     ];
-    $this->drupalPostForm('/webform/test_element_radios', $edit, t('Preview'));
+    $this->drupalPostForm('/webform/test_element_radios', $edit, 'Preview');
     $this->assertPattern('#<label>radios_description</label>\s+One#');
     $this->assertPattern('#<label>radios_help</label>\s+Two#');
   }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementRangeTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementRangeTest.php
index 218044a6e9..aee23ba398 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementRangeTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementRangeTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for range element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementRangeTest extends WebformElementBrowserTestBase {
 
@@ -48,7 +48,7 @@ public function testRating() {
     $this->assertRaw('<input style="width:4em" type="number" id="range_output_right__output" step="1" min="0" max="100" class="form-number" />');
 
     // Check processing.
-    $this->drupalPostForm('/webform/test_element_range', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_range', [], 'Submit');
     $this->assertRaw("range: '50'
 range_advanced: '0'
 range_output_above: '50'
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementRatingTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementRatingTest.php
index 255b70948c..d005dc6775 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementRatingTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementRatingTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for rating element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementRatingTest extends WebformElementBrowserTestBase {
 
@@ -43,13 +43,13 @@ public function testRating() {
       'rating_advanced' => '2',
       'rating_required' => '3',
     ];
-    $this->drupalPostForm('/webform/test_element_rating', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_rating', $edit, 'Submit');
     $this->assertRaw("rating_basic: '1'
 rating_advanced: '2'
 rating_required: '3'");
 
     // Check required validation.
-    $this->drupalPostForm('/webform/test_element_rating', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_rating', [], 'Submit');
     $this->assertRaw('rating_required field is required.');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementReadonlyTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementReadonlyTest.php
index 78cef42761..8550eb2413 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementReadonlyTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementReadonlyTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform element readonly attribute.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementReadonlyTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementSameTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementSameTest.php
index f4cb51ffe2..8f4ef8706d 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementSameTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementSameTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for same element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementSameTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementScaleTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementScaleTest.php
index 76897b1d0c..d9709df96d 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementScaleTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementScaleTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for scale element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementScaleTest extends WebformElementBrowserTestBase {
 
@@ -36,7 +36,7 @@ public function testRating() {
       'scale' => 1,
       'scale_text' => 2,
     ];
-    $this->drupalPostForm('/webform/test_element_scale', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_scale', $edit, 'Submit');
     $this->assertRaw("scale: '1'
 scale_text: '2'
 scale_text_above: null
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementSectionTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementSectionTest.php
index 5aea4d2a98..e5a70a6bba 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementSectionTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementSectionTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for element section.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementSectionTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementSelectTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementSelectTest.php
index 2332692031..f1ed926bdb 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementSelectTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementSelectTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for select element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementSelectTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementSignatureTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementSignatureTest.php
index c22abe4edc..0d2c9ed4a9 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementSignatureTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementSignatureTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for signature element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementSignatureTest extends WebformElementBrowserTestBase {
 
@@ -39,17 +39,17 @@ public function testSignature() {
     $this->assertRaw('<div id="edit-signature--description" class="webform-element-description">Sign above</div>');
 
     // Check signature preview image.
-    $this->postSubmissionTest($webform, [], t('Preview'));
+    $this->postSubmissionTest($webform, [], 'Preview');
     $this->assertRaw("$signature_path/signature-");
     $this->assertRaw(' alt="Signature" class="webform-signature-image" />');
-    $this->assertEqual(count(file_scan_directory($signature_directory, '/^signature-.*\.png$/')), 1);
+    $this->assertCount(1, \Drupal::service('file_system')->scanDirectory($signature_directory, '/^signature-.*\.png$/'));
 
     // Check signature saved image.
     $sid = $this->postSubmissionTest($webform);
     $webform_submission = WebformSubmission::load($sid);
     $this->assertRaw("$signature_path/$sid/signature-");
-    $this->assertTrue(file_exists("$signature_directory/$sid"));
-    $this->assertEqual(count(file_scan_directory($signature_directory, '/^signature-.*\.png$/')), 1);
+    $this->assertFileExists("$signature_directory/$sid");
+    $this->assertCount(1, \Drupal::service('file_system')->scanDirectory($signature_directory, '/^signature-.*\.png$/'));
 
     /**************************************************************************/
     // Validation.
@@ -71,13 +71,13 @@ public function testSignature() {
 
     // Check deleting the submission deletes submission's signature directory.
     $webform_submission->delete();
-    $this->assertTrue(file_exists("$signature_directory"));
-    $this->assertFalse(file_exists("$signature_directory/$sid"));
-    $this->assertEqual(count(file_scan_directory($signature_directory, '/^signature-.*\.png$/')), 1);
+    $this->assertFileExists("$signature_directory");
+    $this->assertFileNotExists("$signature_directory/$sid");
+    $this->assertCount(1, \Drupal::service('file_system')->scanDirectory($signature_directory, '/^signature-.*\.png$/'));
 
     // Check deleting the webform deletes webform's signature directory.
     $webform->delete();
-    $this->assertFalse(file_exists("$signature_directory"));
+    $this->assertFileNotExists("$signature_directory");
   }
 
   /**
@@ -95,7 +95,7 @@ protected function assertSignature($value, $is_valid = TRUE) {
     $this->drupalGet('/webform/test_element_signature');
     $field = $this->assertSession()->hiddenFieldExists('signature');
     $field->setValue($value);
-    $this->submitForm([], t('Submit'));
+    $this->submitForm([], 'Submit');
     if ($is_valid) {
       $this->assertNoRaw('signature contains an invalid signature.');
     }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementStatesSelectorsTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementStatesSelectorsTest.php
index 59c4d345e0..a36ab2047b 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementStatesSelectorsTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementStatesSelectorsTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform element #states selectors.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementStatesSelectorsTest extends WebformElementBrowserTestBase {
 
@@ -30,7 +30,7 @@ class WebformElementStatesSelectorsTest extends WebformElementBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create 'tags' vocabulary.
@@ -75,7 +75,7 @@ public function testSelectors() {
 
     // Check the value element is excluded.
     $selectors = $webform->getElementsSelectorOptions();
-    $this->assert(!isset($selectors[':input[name="value"]']));
+    $this->assertArrayNotHasKey(':input[name="value"]', $selectors);
 
     // Check the value element is included.
     $selectors = $webform->getElementsSelectorOptions(['excluded_elements' => []]);
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementStatesTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementStatesTest.php
index 62a0b81dfe..12c2dd3c90 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementStatesTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementStatesTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform element #states.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementStatesTest extends WebformElementBrowserTestBase {
 
@@ -26,7 +26,7 @@ public function testElement() {
     /**************************************************************************/
 
     // Check default value handling.
-    $this->drupalPostForm('/webform/test_element_states', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_states', [], 'Submit');
 
     $this->assertRaw("states_basic:
   enabled:
@@ -110,12 +110,12 @@ public function testElement() {
 
     // Check duplicate states validation.
     $edit = ['states_basic[states][0][state]' => 'required'];
-    $this->drupalPostForm('/webform/test_element_states', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_states', $edit, 'Submit');
     $this->assertRaw('The <em class="placeholder">Required</em> state is declared more than once. There can only be one declaration per state.');
 
     // Check duplicate selectors validation.
     $edit = ['states_basic[states][3][selector]' => 'selector_02'];
-    $this->drupalPostForm('/webform/test_element_states', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_states', $edit, 'Submit');
     $this->assertRaw('The <em class="placeholder">Selector 02 (selector_02)</em> element is used more than once within the <em class="placeholder">Required</em> state. To use multiple values within a trigger try using the pattern trigger.');
 
     /**************************************************************************/
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsReplaceTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsReplaceTest.php
index 1e5cb5034c..5e66f0dab1 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsReplaceTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsReplaceTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform submission views replace element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementSubmissionViewsReplaceTest extends WebformElementBrowserTestBase {
 
@@ -38,7 +38,7 @@ public function testSubmissionViewsReplace() {
     $this->assertNoRaw('<fieldset data-drupal-selector="edit-webform-submission-views-replace-node-routes" id="edit-webform-submission-views-replace-node-routes--wrapper" class="fieldgroup form-composite js-form-item form-item js-form-wrapper form-wrapper">');
 
     // Check processing clears hidden webform_submission_views_replace.
-    $this->drupalPostForm('/webform/test_element_submission_views_r', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_submission_views_r', [], 'Submit');
     $this->assertRaw("webform_submission_views_replace_global:
   global_routes:
     - entity.webform_submission.collection
@@ -64,7 +64,7 @@ public function testSubmissionViewsReplace() {
     $this->assertRaw('<fieldset data-drupal-selector="edit-webform-submission-views-replace-node-routes" id="edit-webform-submission-views-replace-node-routes--wrapper" class="fieldgroup form-composite js-form-item form-item js-form-wrapper form-wrapper">');
 
     // Check processing with webform replace element is visible.
-    $this->drupalPostForm('/webform/test_element_submission_views_r', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_submission_views_r', [], 'Submit');
     $this->assertRaw("webform_submission_views_replace_global:
   global_routes:
     - entity.webform_submission.collection
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsTest.php
index c723363a8e..76f1262c6d 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementSubmissionViewsTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform submission views element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementSubmissionViewsTest extends WebformElementBrowserTestBase {
 
@@ -40,21 +40,21 @@ public function testSubmissionViews() {
 
     // Check name validation.
     $edit = ['webform_submission_views_global[items][0][name]' => ''];
-    $this->drupalPostForm('/webform/test_element_submission_views', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_submission_views', $edit, 'Submit');
     $this->assertRaw('Name is required');
 
     // Check view validation.
     $edit = ['webform_submission_views_global[items][0][view]' => ''];
-    $this->drupalPostForm('/webform/test_element_submission_views', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_submission_views', $edit, 'Submit');
     $this->assertRaw('View name/display id is required.');
 
     // Check title validation.
     $edit = ['webform_submission_views_global[items][0][title]' => ''];
-    $this->drupalPostForm('/webform/test_element_submission_views', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_submission_views', $edit, 'Submit');
     $this->assertRaw('Title is required.');
 
     // Check processing.
-    $this->drupalPostForm('/webform/test_element_submission_views', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_submission_views', [], 'Submit');
     $this->assertRaw("webform_submission_views_global:
   admin:
     view: 'webform_submissions:embed_administer'
@@ -83,7 +83,7 @@ public function testSubmissionViews() {
       'webform_submission_views_global[items][0][webform_routes][entity.webform.results_submissions]' => FALSE,
       'webform_submission_views_global[items][0][node_routes][entity.node.webform.results_submissions]' => FALSE,
     ];
-    $this->drupalPostForm('/webform/test_element_submission_views', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_submission_views', $edit, 'Submit');
     $this->assertNoRaw('Name is required');
     $this->assertNoRaw('View name/display id is required.');
     $this->assertNoRaw('Title is required.');
@@ -106,7 +106,7 @@ public function testSubmissionViews() {
     $this->assertNoRaw('<th class="webform_submission_views-table--node_routes webform-multiple-table--node_routes">');
 
     // Check processing removes node settings.
-    $this->drupalPostForm('/webform/test_element_submission_views', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_submission_views', [], 'Submit');
     $this->assertRaw("webform_submission_views_global:
   admin:
     view: 'webform_submissions:embed_administer'
@@ -131,7 +131,7 @@ public function testSubmissionViews() {
     $this->assertNoRaw('<th class="webform_submission_views-table--name_title_view webform-multiple-table--name_title_view">');
 
     // Check that value is preserved.
-    $this->drupalPostForm('/webform/test_element_submission_views', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_submission_views', [], 'Submit');
     $this->assertRaw("webform_submission_views_global: {  }
 webform_submission_views: {  }");
   }
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementSubmittedValueTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementSubmittedValueTest.php
index d554fb2ff0..96c893b7a3 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementSubmittedValueTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementSubmittedValueTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform submission value.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementSubmittedValueTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementTableSelectSortTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementTableSelectSortTest.php
index 5bf31ed018..4e5af14e3f 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementTableSelectSortTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementTableSelectSortTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for table select and sort elements.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementTableSelectSortTest extends WebformElementBrowserTestBase {
 
@@ -42,7 +42,7 @@ public function testTableSelectSort() {
       'webform_tableselect_sort_custom[four][checkbox]' => TRUE,
       'webform_tableselect_sort_custom[five][checkbox]' => TRUE,
     ];
-    $this->drupalPostForm('/webform/test_element_table_select_sort', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_table_select_sort', $edit, 'Submit');
     $this->assertRaw("webform_tableselect_sort_custom:
   - five
   - four
@@ -62,7 +62,7 @@ public function testTableSelectSort() {
       'webform_table_sort_custom[four][weight]' => '1',
       'webform_table_sort_custom[five][weight]' => '0',
     ];
-    $this->drupalPostForm('/webform/test_element_table_select_sort', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_table_select_sort', $edit, 'Submit');
     $this->assertRaw("webform_table_sort_custom:
   - five
   - four
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementTableTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementTableTest.php
index f766d12107..fb0d6a2505 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementTableTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementTableTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for table elements.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementTableTest extends WebformElementBrowserTestBase {
 
@@ -72,7 +72,7 @@ public function testTable() {
       'table_advanced_01_last_name' => 'Lennon',
       'table_advanced_01_gender' => 'Male',
     ];
-    $this->drupalPostForm('/webform/test_element_table', $edit, t('Preview'));
+    $this->drupalPostForm('/webform/test_element_table', $edit, 'Preview');
 
     // Check data.
     $this->assertRaw("table__1__first_name: John
@@ -140,7 +140,7 @@ public function testTable() {
     $this->assertFieldByName('properties[duplicate]', TRUE);
 
     // Check table row element sub elements are duplicated.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row', [], t('Save'), ['query' => ['parent' => 'table_basic']]);
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row', [], 'Save', ['query' => ['parent' => 'table_basic']]);
     $this->assertRaw('>table_basic_02<');
     $this->assertRaw('>table_basic_02_first_name<');
     $this->assertRaw('>table_basic_02_last_name<');
@@ -148,7 +148,7 @@ public function testTable() {
     $this->assertRaw('>table_basic_02_markup<');
 
     // Check table row element sub elements are NOT duplicated.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row', ['properties[duplicate]' => FALSE], t('Save'), ['query' => ['parent' => 'table_basic']]);
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_table/element/add/webform_table_row', ['properties[duplicate]' => FALSE], 'Save', ['query' => ['parent' => 'table_basic']]);
     $this->assertRaw('>table_basic_03<');
     $this->assertNoRaw('>table_basic_03_first_name<');
     $this->assertNoRaw('>table_basic_03_last_name<');
@@ -166,7 +166,7 @@ public function testTable() {
       'properties[title]' => 'Testing',
     ];
     $options = ['query' => ['parent' => 'table_basic_01']];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_element_table/element/add/textfield', $edit, t('Save'), $options);
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_table/element/add/textfield', $edit, 'Save', $options);
     $this->assertRaw('>table_basic_01_testing<');
 
     // Check table row element can NOT duplicate sub elements from the
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementTelephoneTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementTelephoneTest.php
index 6b470f8a0c..89a9603585 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementTelephoneTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementTelephoneTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for telephone element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementTelephoneTest extends WebformElementBrowserTestBase {
 
@@ -24,10 +24,20 @@ class WebformElementTelephoneTest extends WebformElementBrowserTestBase {
    */
   protected static $testWebforms = ['test_element_telephone'];
 
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    if (floatval(\Drupal::VERSION) >= 9) {
+      $this->markTestSkipped('Issue #3110478: [Webform 8.x-6.x] Track the D9 readiness state of the Webform module\'s (optional) dependencies');
+    }
+    parent::setUp();
+  }
+
   /**
    * Test telephone element.
    */
-  public function testRating() {
+  public function testTelephone() {
     $this->drupalGet('/webform/test_element_telephone');
 
     // Check basic tel.
@@ -47,7 +57,7 @@ public function testRating() {
       'tel_validation_e164' => '12024561111',
       'tel_validation_national' => '12024561111',
     ];
-    $this->drupalPostForm('/webform/test_element_telephone', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_telephone', $edit, 'Submit');
     $this->assertRaw('The phone number <em class="placeholder">12024561111</em> is not valid.');
 
     // Check telephone validation with plus sign.
@@ -55,14 +65,14 @@ public function testRating() {
       'tel_validation_e164' => '+12024561111',
       'tel_validation_national' => '+12024561111',
     ];
-    $this->drupalPostForm('/webform/test_element_telephone', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_telephone', $edit, 'Submit');
     $this->assertNoRaw('The phone number <em class="placeholder">12024561111</em> is not valid.');
 
     // Check telephone validation with non US number.
     $edit = [
       'tel_validation_national' => '+74956970349',
     ];
-    $this->drupalPostForm('/webform/test_element_telephone', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_telephone', $edit, 'Submit');
     $this->assertRaw('The phone number <em class="placeholder">+74956970349</em> is not valid.');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementTermReferenceTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementTermReferenceTest.php
index 57096d3c96..bec6131125 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementTermReferenceTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementTermReferenceTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for term reference elements.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementTermReferenceTest extends WebformElementBrowserTestBase {
 
@@ -29,7 +29,7 @@ class WebformElementTermReferenceTest extends WebformElementBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create 'tags' vocabulary.
@@ -68,7 +68,7 @@ public function testTermReference() {
       'webform_term_checkboxes_breadcrumb_advanced[2]' => TRUE,
       'webform_term_checkboxes_breadcrumb_advanced[3]' => TRUE,
     ];
-    $this->postSubmission($webform, $edit, t('Preview'));
+    $this->postSubmission($webform, $edit, 'Preview');
     $this->assertRaw('<label>webform_term_checkboxes_breadcrumb_advanced</label>');
     $this->assertRaw('<div class="item-list"><ul><li>Parent 1 › Parent 1: Child 1</li><li>Parent 1 › Parent 1: Child 2</li></ul></div>');
 
@@ -126,7 +126,7 @@ public function testTermReference() {
     $edit = [
       'webform_term_select_breadcrumb_advanced[]' => [2, 3],
     ];
-    $this->postSubmission($webform, $edit, t('Preview'));
+    $this->postSubmission($webform, $edit, 'Preview');
     $this->assertRaw('<label>webform_term_select_breadcrumb_advanced</label>');
     $this->assertRaw('<div class="item-list"><ul><li>Parent 1 › Parent 1: Child 1</li><li>Parent 1 › Parent 1: Child 2</li></ul></div>');
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementTermsOfServiceTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementTermsOfServiceTest.php
index 2eea2a461a..79eda2adb4 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementTermsOfServiceTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementTermsOfServiceTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform terms of service element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementTermsOfServiceTest extends WebformElementBrowserTestBase {
 
@@ -43,7 +43,7 @@ public function testTermsOfService() {
     $this->assertRaw('<label for="edit-terms-of-service-slideout" class="option">I agree to the <a role="button" href="#terms">terms of service</a>. (slideout)</label>');
 
     // Check validation.
-    $this->drupalPostForm('/webform/test_element_terms_of_service', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_element_terms_of_service', [], 'Preview');
     $this->assertRaw('I agree to the {terms of service}. (default) field is required.');
 
     // Check preview.
@@ -52,7 +52,7 @@ public function testTermsOfService() {
       'terms_of_service_modal' => TRUE,
       'terms_of_service_slideout' => TRUE,
     ];
-    $this->drupalPostForm('/webform/test_element_terms_of_service', $edit, t('Preview'));
+    $this->drupalPostForm('/webform/test_element_terms_of_service', $edit, 'Preview');
     $this->assertRaw('I agree to the terms of service. (default)');
     $this->assertRaw('I agree to the terms of service. (modal)');
     $this->assertRaw('I agree to the terms of service. (slideout)');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementTest.php
index 53ccf10264..2cd9bb231c 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementTest extends WebformElementBrowserTestBase {
 
@@ -47,7 +47,7 @@ public function testWebform() {
       'subject' => '{subject}',
       'message' => '{message}',
     ];
-    $this->drupalPostForm('/webform_test_element', $edit, t('Send message'));
+    $this->drupalPostForm('/webform_test_element', $edit, 'Send message');
     $this->assertUrl('/');
     $this->assertRaw('Your message has been sent.');
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementTextFormatTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementTextFormatTest.php
index 2113f8ff22..77d6a03b42 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementTextFormatTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementTextFormatTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for text format element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementTextFormatTest extends WebformElementBrowserTestBase {
 
@@ -40,7 +40,7 @@ class WebformElementTextFormatTest extends WebformElementBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     $this->fileUsage = $this->container->get('file.usage');
@@ -54,13 +54,7 @@ public function testTextFormat() {
 
     // Check that formats and tips are removed and/or hidden.
     $this->drupalGet('/webform/test_element_text_format');
-    // @todo Remove once Drupal 8.8.x is only supported.
-    if (floatval(\Drupal::VERSION) >= 8.8) {
-      $this->assertRaw('<div class="js-filter-wrapper filter-wrapper js-form-wrapper form-wrapper" data-drupal-selector="edit-text-format-format" style="display: none" id="edit-text-format-format">');
-    }
-    else {
-      $this->assertRaw('<div class="filter-wrapper js-form-wrapper form-wrapper" data-drupal-selector="edit-text-format-format" style="display: none" id="edit-text-format-format">');
-    }
+    $this->assertRaw('<div class="js-filter-wrapper filter-wrapper js-form-wrapper form-wrapper" data-drupal-selector="edit-text-format-format" style="display: none" id="edit-text-format-format">');
     $this->assertRaw('<div class="filter-help js-form-wrapper form-wrapper" data-drupal-selector="edit-text-format-format-help" style="display: none" id="edit-text-format-format-help">');
 
     // Check description + more.
@@ -127,7 +121,7 @@ public function testTextFormatFiles() {
       'text_format[value]' => '<img data-entity-type="file" data-entity-uuid="' . $images[0]->uuid() . '"/><img data-entity-type="file" data-entity-uuid="' . $images[1]->uuid() . '"/>',
       'text_format[format]' => 'full_html',
     ];
-    $this->drupalPostForm("/admin/structure/webform/manage/test_element_text_format/submission/$sid/edit", $edit, t('Save'));
+    $this->drupalPostForm("/admin/structure/webform/manage/test_element_text_format/submission/$sid/edit", $edit, 'Save');
     $this->reloadImages($images);
 
     // Check that first and second image are not temporary.
@@ -144,7 +138,7 @@ public function testTextFormatFiles() {
       'text_format[value]' => '<img data-entity-type="file" data-entity-uuid="' . $images[1]->uuid() . '"/>',
       'text_format[format]' => 'full_html',
     ];
-    $this->drupalPostForm("/admin/structure/webform/manage/test_element_text_format/submission/$sid/edit", $edit, t('Save'));
+    $this->drupalPostForm("/admin/structure/webform/manage/test_element_text_format/submission/$sid/edit", $edit, 'Save');
     $this->reloadImages($images);
 
     // Check that first is temporary and second image is not temporary.
@@ -171,7 +165,7 @@ public function testTextFormatFiles() {
     $this->assertIdentical(['editor' => ['webform_submission' => [$sid => '1']]], $this->fileUsage->listUsage($images[1]), 'The file has 1 usage.');
 
     // Delete the webform submission.
-    $this->drupalPostForm("/admin/structure/webform/manage/test_element_text_format/submission/$sid/delete", [], t('Delete'));
+    $this->drupalPostForm("/admin/structure/webform/manage/test_element_text_format/submission/$sid/delete", [], 'Delete');
     $this->reloadImages($images);
 
     // Check that first and second image are temporary.
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementTimeTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementTimeTest.php
index c035e06c86..e0dea25833 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementTimeTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementTimeTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform time element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementTimeTest extends WebformElementBrowserTestBase {
 
@@ -32,7 +32,7 @@ public function testTime() {
     $this->assertRaw('<input placeholder="{time}" data-drupal-selector="edit-time-timepicker-placeholder" data-webform-time-format="H:i" type="text" id="edit-time-timepicker-placeholder" name="time_timepicker_placeholder" value="" size="12" maxlength="12" class="form-time webform-time" />');
 
     // Check time processing.
-    $this->drupalPostForm('/webform/test_element_time', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_time', [], 'Submit');
     $time_12_hour_plus_6_hours = date('H:i:00', strtotime('+6 hours'));
     $this->assertRaw("time_default: '14:00:00'
 time_24_hour: '14:00:00'
@@ -45,33 +45,33 @@ public function testTime() {
 
     // Check time validation.
     $edit = ['time_24_hour' => 'not-valid'];
-    $this->drupalPostForm('/webform/test_element_time', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_time', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">time_24_hour</em> must be a valid time.');
 
     // Check '0' string trigger validation error.
     $edit = ['time_default' => '0'];
-    $this->drupalPostForm('/webform/test_element_time', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_time', $edit, 'Submit');
     $this->assertRaw('em class="placeholder">time_default</em> must be a valid time.');
 
     // Check '++' string (faulty relative date) trigger validation error.
     $edit = ['time_default' => '++'];
-    $this->drupalPostForm('/webform/test_element_time', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_time', $edit, 'Submit');
     $this->assertRaw('em class="placeholder">time_default</em> must be a valid time.');
 
     // Check empty string trigger does not validation error.
     $edit = ['time_default' => ''];
-    $this->drupalPostForm('/webform/test_element_time', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_time', $edit, 'Submit');
     $this->assertNoRaw('<em class="placeholder">time_default</em> must be a valid time.');
     $this->assertRaw("time_default: ''");
 
     // Check time #max validation.
     $edit = ['time_min_max' => '12:00'];
-    $this->drupalPostForm('/webform/test_element_time', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_time', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">time_min_max</em> must be on or after <em class="placeholder">14:00</em>.');
 
     // Check time #min validation.
     $edit = ['time_min_max' => '22:00'];
-    $this->drupalPostForm('/webform/test_element_time', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_time', $edit, 'Submit');
     $this->assertRaw('<em class="placeholder">time_min_max</em> must be on or before <em class="placeholder">18:00</em>.');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementValidateMinlengthTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementValidateMinlengthTest.php
index 7e235f82c0..8d4cb823c0 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementValidateMinlengthTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementValidateMinlengthTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform validate minlength.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementValidateMinlengthTest extends WebformElementBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementValidateMultipleTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementValidateMultipleTest.php
index a3a2cc9704..49b241b3d5 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementValidateMultipleTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementValidateMultipleTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform validate multiple.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementValidateMultipleTest extends WebformElementBrowserTestBase {
 
@@ -48,7 +48,7 @@ public function testValidateMultiple() {
       'webform_element_multiple_checkboxes_two[three]' => 'three',
       'webform_element_multiple_select_two[]' => ['one', 'two', 'three'],
     ];
-    $this->drupalPostForm('/webform/test_element_validate_multiple', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_validate_multiple', $edit, 'Submit');
 
     // Check checkboxes multiple custom error message.
     $this->assertRaw('Please check only two options.');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementValidatePatternTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementValidatePatternTest.php
index d462a0a84c..5adb8f0791 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementValidatePatternTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementValidatePatternTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform pattern validation.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementValidatePatternTest extends WebformElementBrowserTestBase {
 
@@ -34,7 +34,7 @@ public function testPattern() {
       'pattern_error_html' => 'GoodBye',
       'pattern_unicode' => 'Unicode',
     ];
-    $this->drupalPostForm('/webform/test_element_validate_pattern', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_validate_pattern', $edit, 'Submit');
     $this->assertRaw('<li class="messages__item"><em class="placeholder">pattern</em> field is not in the right format.</li>');
     $this->assertRaw('<li class="messages__item">You did not enter &#039;Hello&#039;</li>');
     $this->assertRaw('<li class="messages__item">You did not enter <strong>Hello</strong></li>');
@@ -47,7 +47,7 @@ public function testPattern() {
       'pattern_error_html' => 'Hello',
       'pattern_unicode' => '⺏',
     ];
-    $this->drupalPostForm('/webform/test_element_validate_pattern', $edit, t('Submit'));
+    $this->drupalPostForm('/webform/test_element_validate_pattern', $edit, 'Submit');
     $this->assertNoRaw('<li class="messages__item"><em class="placeholder">pattern</em> field is not in the right format.</li>');
     $this->assertNoRaw('<li class="messages__item">You did not enter &#039;Hello&#039;</li>');
     $this->assertNoRaw('<li class="messages__item">You did not enter <strong>Hello</strong></li>');
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementValidateRequiredTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementValidateRequiredTest.php
index 705a700346..329ab41021 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementValidateRequiredTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementValidateRequiredTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform required validation.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementValidateRequiredTest extends WebformElementBrowserTestBase {
 
@@ -25,7 +25,7 @@ public function testPattern() {
     $this->assertRaw(' <input data-webform-required-error="This is a custom required message" data-drupal-selector="edit-required-textfield-html" type="text" id="edit-required-textfield-html" name="required_textfield_html" value="" size="60" maxlength="255" class="form-text required" required="required" aria-required="true" />');
 
     // Check that HTML tags are rendered in validation message.
-    $this->drupalPostForm('/webform/test_element_validate_required', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_element_validate_required', [], 'Submit');
     $this->assertRaw('<li class="messages__item">This is a <em>custom required message</em></li>');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementValidateUniqueTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementValidateUniqueTest.php
index 264f0dd1aa..bfd599514b 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementValidateUniqueTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementValidateUniqueTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform validate unique.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementValidateUniqueTest extends WebformElementBrowserTestBase {
 
@@ -59,7 +59,7 @@ public function testValidateUnique() {
     $this->assertRaw('unique_multiple error message.');
 
     // Check #unique element can be updated.
-    $this->drupalPostForm("admin/structure/webform/manage/test_element_validate_unique/submission/$sid/edit", [], t('Save'));
+    $this->drupalPostForm("admin/structure/webform/manage/test_element_validate_unique/submission/$sid/edit", [], 'Save');
     $this->assertNoRaw('The value <em class="placeholder">{unique_textfield}</em> has already been submitted once for the <em class="placeholder">unique_textfield</em> element. You may have already submitted this webform, or you need to use a different value.</li>');
     $this->assertNoRaw('unique_user_textfield error message.');
     $this->assertNoRaw('unique_entity_textfield error message.');
@@ -79,7 +79,7 @@ public function testValidateUnique() {
       'unique_textfield_multiple[items][0][_item_]' => '{same}',
       'unique_textfield_multiple[items][2][_item_]' => '{same}',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Submit'));
+    $this->drupalPostForm(NULL, $edit, 'Submit');
     $this->assertRaw('unique_textfield_multiple error message.');
 
     // Purge existing submissions.
diff --git a/web/modules/webform/tests/src/Functional/Element/WebformElementViewTest.php b/web/modules/webform/tests/src/Functional/Element/WebformElementViewTest.php
index c0bc45e0d7..510c3f042c 100644
--- a/web/modules/webform/tests/src/Functional/Element/WebformElementViewTest.php
+++ b/web/modules/webform/tests/src/Functional/Element/WebformElementViewTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for view element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformElementViewTest extends WebformElementBrowserTestBase {
 
@@ -51,17 +51,17 @@ public function testView() {
 
     // Check view name validation.
     $edit = ['properties[name]' => 'xxx'];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_element_view/element/view/edit', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_view/element/view/edit', $edit, 'Save');
     $this->assertRaw('View <em class="placeholder">xxx</em> does not exist.');
 
     // Check view display id validation.
     $edit = ['properties[display_id]' => 'xxx'];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_element_view/element/view/edit', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_view/element/view/edit', $edit, 'Save');
     $this->assertRaw('View display <em class="placeholder">xxx</em> does not exist.');
 
     // Check view exposed filter validation.
     $edit = ['properties[display_id]' => 'embed_administer'];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_element_view/element/view/edit', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_view/element/view/edit', $edit, 'Save');
     $this->assertRaw('View display <em class="placeholder">embed_administer</em> has exposed filters which will break the webform.');
 
     // Check view exposed filter validation.
@@ -69,7 +69,7 @@ public function testView() {
       'properties[display_id]' => 'embed_administer',
       'properties[display_on]' => 'view',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_element_view/element/view/edit', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_element_view/element/view/edit', $edit, 'Save');
     $this->assertNoRaw('View display <em class="placeholder">embed_administer</em> has exposed filters which will break the webform.');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Exporter/WebformExporterExcludedTest.php b/web/modules/webform/tests/src/Functional/Exporter/WebformExporterExcludedTest.php
index b9446a7891..09f69c709c 100644
--- a/web/modules/webform/tests/src/Functional/Exporter/WebformExporterExcludedTest.php
+++ b/web/modules/webform/tests/src/Functional/Exporter/WebformExporterExcludedTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for the webform exporter excluded.
  *
- * @group Webform
+ * @group webform
  */
 class WebformExporterExcludedTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Exporter/WebformExporterOptionsTest.php b/web/modules/webform/tests/src/Functional/Exporter/WebformExporterOptionsTest.php
index 6bf5217ba0..2ba1bb989b 100644
--- a/web/modules/webform/tests/src/Functional/Exporter/WebformExporterOptionsTest.php
+++ b/web/modules/webform/tests/src/Functional/Exporter/WebformExporterOptionsTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for the webform exporter options.
  *
- * @group Webform
+ * @group webform
  */
 class WebformExporterOptionsTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Form/WebformFormPropertiesTest.php b/web/modules/webform/tests/src/Functional/Form/WebformFormPropertiesTest.php
index 94a89fe0e0..29737ebf94 100644
--- a/web/modules/webform/tests/src/Functional/Form/WebformFormPropertiesTest.php
+++ b/web/modules/webform/tests/src/Functional/Form/WebformFormPropertiesTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for form properties.
  *
- * @group Webform
+ * @group webform
  */
 class WebformFormPropertiesTest extends WebformBrowserTestBase {
 
@@ -47,7 +47,7 @@ public function testProperties() {
       'custom' => "'suffix': 'Form suffix TEST'
 'prefix': 'Form prefix TEST'",
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_form_properties/settings/form', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_form_properties/settings/form', $edit, 'Save');
     $this->drupalGet('/webform/test_form_properties');
     $this->assertPattern('/Form prefix TEST<form /');
     $this->assertPattern('/<\/form>\s+Form suffix TEST/');
diff --git a/web/modules/webform/tests/src/Functional/Form/WebformFormValidateTest.php b/web/modules/webform/tests/src/Functional/Form/WebformFormValidateTest.php
index cdfa79d22c..51782c051c 100644
--- a/web/modules/webform/tests/src/Functional/Form/WebformFormValidateTest.php
+++ b/web/modules/webform/tests/src/Functional/Form/WebformFormValidateTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform form validation.
  *
- * @group Webform
+ * @group webform
  */
 class WebformFormValidateTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerActionTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerActionTest.php
index a083b11096..5c164f5ac5 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerActionTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerActionTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for action webform handler functionality.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerActionTest extends WebformBrowserTestBase {
 
@@ -42,17 +42,17 @@ public function testActionHandler() {
     $this->assertFalse($webform_submission->isLocked());
 
     // Check that submission notes is empty.
-    $this->assertTrue(empty($webform_submission->getNotes()));
+    $this->assertEmpty($webform_submission->getNotes());
 
     // Check that last note is empty.
-    $this->assertTrue(empty($webform_submission->getElementData('notes_add')));
+    $this->assertEmpty($webform_submission->getElementData('notes_add'));
 
     // Flag and add new note to the submission.
     $edit = [
       'sticky' => 'flag',
       'notes_add' => 'This is the first note',
     ];
-    $this->drupalPostForm("admin/structure/webform/manage/test_handler_action/submission/$sid/edit", $edit, t('Save'));
+    $this->drupalPostForm("admin/structure/webform/manage/test_handler_action/submission/$sid/edit", $edit, 'Save');
 
     // Check messages.
     $this->assertRaw('Submission has been flagged.');
@@ -66,7 +66,7 @@ public function testActionHandler() {
     $this->assertTrue($webform_submission->isSticky());
 
     // Change that notes_add is empty.
-    $this->assertTrue(empty($webform_submission->getElementData('notes_add')));
+    $this->assertEmpty($webform_submission->getElementData('notes_add'));
 
     // Check that notes_last is updated.
     $this->assertEqual($webform_submission->getElementData('notes_last'), 'This is the first note');
@@ -76,7 +76,7 @@ public function testActionHandler() {
       'sticky' => 'unflag',
       'notes_add' => 'This is the second note',
     ];
-    $this->drupalPostForm("admin/structure/webform/manage/test_handler_action/submission/$sid/edit", $edit, t('Save'));
+    $this->drupalPostForm("admin/structure/webform/manage/test_handler_action/submission/$sid/edit", $edit, 'Save');
 
     // Check messages.
     $this->assertRaw('Submission has been unflagged.');
@@ -91,7 +91,7 @@ public function testActionHandler() {
     $this->assertFalse($webform_submission->isSticky());
 
     // Change that notes_add is empty.
-    $this->assertTrue(empty($webform_submission->getElementData('notes_add')));
+    $this->assertEmpty($webform_submission->getElementData('notes_add'));
 
     // Check that notes updated.
     $this->assertEqual($webform_submission->getNotes(), 'This is the first note' . PHP_EOL . PHP_EOL . 'This is the second note');
@@ -103,7 +103,7 @@ public function testActionHandler() {
     $edit = [
       'lock' => 'locked',
     ];
-    $this->drupalPostForm("admin/structure/webform/manage/test_handler_action/submission/$sid/edit", $edit, t('Save'));
+    $this->drupalPostForm("admin/structure/webform/manage/test_handler_action/submission/$sid/edit", $edit, 'Save');
 
     // Check locked message.
     $this->assertRaw('Submission has been locked.');
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerConditionsTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerConditionsTest.php
index 4e4d5d03b0..45ed466586 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerConditionsTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerConditionsTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform handler plugin conditions.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerConditionsTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailAdvancedTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailAdvancedTest.php
index bf11ca16cd..13481bc328 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailAdvancedTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailAdvancedTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for advanced email webform handler functionality with HTML and attachments.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerEmailAdvancedTest extends WebformBrowserTestBase {
 
@@ -24,7 +24,7 @@ class WebformHandlerEmailAdvancedTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create filter.
@@ -58,7 +58,7 @@ public function testAdvancedEmailHandler() {
     $this->assertEqual($sent_email['headers']['Sender'], 'sender_name <sender_mail@example.com>');
     $this->assertEqual($sent_email['headers']['Reply-to'], 'reply_to@example.com');
     $this->assertEqual($sent_email['params']['custom_parameter'], 'test');
-    $this->assert(!isset($sent_email['params']['parameters']));
+    $this->assertArrayNotHasKey('parameters', $sent_email['params']);
 
     $email_handler = $webform->getHandler('email');
     $configuration = $email_handler->getConfiguration();
@@ -134,15 +134,15 @@ public function testAdvancedEmailHandler() {
     $this->assertEqual($sent_email['subject'], 'This has "special" \'chararacters\'');
 
     // Check email body is HTML.
-    $this->assertContains('<b>First name</b><br />John<br /><br />', $sent_email['params']['body']);
-    $this->assertContains('<b>Last name</b><br />Smith<br /><br />', $sent_email['params']['body']);
-    $this->assertContains('<b>Email</b><br /><a href="mailto:from@example.com">from@example.com</a><br /><br />', $sent_email['params']['body']);
-    $this->assertContains('<b>Subject</b><br />This has &lt;removed&gt;&quot;special&quot; &#039;chararacters&#039;<br /><br />', $sent_email['params']['body']);
-    $this->assertContains('<b>Message</b><br /><p><em>Please enter a message.</em> Test that double "quotes" are not encoded.</p><br /><br />', $sent_email['params']['body']);
-    $this->assertContains('<p style="color:yellow"><em>Custom styled HTML markup</em></p>', $sent_email['params']['body']);
-    $this->assertContains('<b>File</b><br />', $sent_email['params']['body']);
-    $this->assertNotContains('<b>Optional</b><br />{Empty}<br /><br />', $sent_email['params']['body']);
-    $this->assertNotContains('<b>Checkbox/b><br />Yes<br /><br />', $sent_email['params']['body']);
+    $this->assertStringContainsString('<b>First name</b><br />John<br /><br />', $sent_email['params']['body']);
+    $this->assertStringContainsString('<b>Last name</b><br />Smith<br /><br />', $sent_email['params']['body']);
+    $this->assertStringContainsString('<b>Email</b><br /><a href="mailto:from@example.com">from@example.com</a><br /><br />', $sent_email['params']['body']);
+    $this->assertStringContainsString('<b>Subject</b><br />This has &lt;removed&gt;&quot;special&quot; &#039;chararacters&#039;<br /><br />', $sent_email['params']['body']);
+    $this->assertStringContainsString('<b>Message</b><br /><p><em>Please enter a message.</em> Test that double "quotes" are not encoded.</p><br /><br />', $sent_email['params']['body']);
+    $this->assertStringContainsString('<p style="color:yellow"><em>Custom styled HTML markup</em></p>', $sent_email['params']['body']);
+    $this->assertStringContainsString('<b>File</b><br />', $sent_email['params']['body']);
+    $this->assertStringNotContainsString('<b>Optional</b><br />{Empty}<br /><br />', $sent_email['params']['body']);
+    $this->assertStringNotContainsString('<b>Checkbox/b><br />Yes<br /><br />', $sent_email['params']['body']);
 
     // Check email has attachment.
     $this->assertEqual($sent_email['params']['attachments'][0]['filecontent'], "this is a sample txt file\nit has two lines\n");
@@ -154,9 +154,9 @@ public function testAdvancedEmailHandler() {
     $this->assertRaw('<strong><a href="' . $base_url . '/system/files/webform/test_handler_email_advanced/6/file.txt">file.txt</a></strong> (text/plain) - 43 bytes');
 
     // Check resend webform with custom message.
-    $this->drupalPostForm("admin/structure/webform/manage/test_handler_email_advanced/submission/$sid/resend", ['message[body][value]' => 'Testing 123…'], t('Resend message'));
+    $this->drupalPostForm("admin/structure/webform/manage/test_handler_email_advanced/submission/$sid/resend", ['message[body][value]' => 'Testing 123…'], 'Resend message');
     $sent_email = $this->getLastEmail();
-    $this->assertNotContains('<b>First name</b><br />John<br /><br />', $sent_email['params']['body']);
+    $this->assertStringNotContainsString('<b>First name</b><br />John<br /><br />', $sent_email['params']['body']);
     $this->debug($sent_email['params']['body']);
     $this->assertEqual($sent_email['params']['body'], 'Testing 123…');
 
@@ -176,8 +176,8 @@ public function testAdvancedEmailHandler() {
     // Check excluding attachments.
     $this->postSubmissionTest($webform);
     $sent_email = $this->getLastEmail();
-    $this->assertNotContains('<b>File</b><br />', $sent_email['params']['body']);
-    $this->assertTrue(isset($sent_email['params']['attachments'][0]['filecontent']));
+    $this->assertStringNotContainsString('<b>File</b><br />', $sent_email['params']['body']);
+    $this->assertArrayHasKey('filecontent', $sent_email['params']['attachments'][0]);
 
     // Exclude file element.
     $configuration = $email_handler->getConfiguration();
@@ -188,13 +188,13 @@ public function testAdvancedEmailHandler() {
     // Check excluding files.
     $this->postSubmissionTest($webform);
     $sent_email = $this->getLastEmail();
-    $this->assertNotContains('<b>File</b><br />', $sent_email['params']['body']);
+    $this->assertStringNotContainsString('<b>File</b><br />', $sent_email['params']['body']);
     $this->assertFalse(isset($sent_email['params']['attachments'][0]['filecontent']));
 
     // Check empty element is excluded.
     $this->postSubmission($webform);
     $sent_email = $this->getLastEmail();
-    $this->assertNotContains('<b>Optional</b><br />{Empty}<br /><br />', $sent_email['params']['body']);
+    $this->assertStringNotContainsString('<b>Optional</b><br />{Empty}<br /><br />', $sent_email['params']['body']);
 
     // Include empty.
     $configuration = $email_handler->getConfiguration();
@@ -206,8 +206,8 @@ public function testAdvancedEmailHandler() {
     // Check empty included.
     $this->postSubmission($webform);
     $sent_email = $this->getLastEmail();
-    $this->assertContains('<b>Optional</b><br />{Empty}<br /><br />', $sent_email['params']['body']);
-    $this->assertContains('<b>Checkbox</b><br />No<br /><br />', $sent_email['params']['body']);
+    $this->assertStringContainsString('<b>Optional</b><br />{Empty}<br /><br />', $sent_email['params']['body']);
+    $this->assertStringContainsString('<b>Checkbox</b><br />No<br /><br />', $sent_email['params']['body']);
 
     // Logut and use anonymous user account.
     $this->drupalLogout();
@@ -215,7 +215,7 @@ public function testAdvancedEmailHandler() {
     // Check that private is include in email because 'ignore_access' is TRUE.
     $this->postSubmission($webform);
     $sent_email = $this->getLastEmail();
-    $this->assertContains('<b>Notes</b><br />These notes are private.<br /><br />', $sent_email['params']['body']);
+    $this->assertStringContainsString('<b>Notes</b><br />These notes are private.<br /><br />', $sent_email['params']['body']);
 
     // Disable ignore_access.
     $email_handler = $webform->getHandler('email');
@@ -227,7 +227,7 @@ public function testAdvancedEmailHandler() {
     // Check that private is excluded from email because 'ignore_access' is FALSE.
     $this->postSubmission($webform);
     $sent_email = $this->getLastEmail();
-    $this->assertNotContains('<b>Notes</b><br />These notes are private.<br /><br />', $sent_email['params']['body']);
+    $this->assertStringNotContainsString('<b>Notes</b><br />These notes are private.<br /><br />', $sent_email['params']['body']);
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailBasicTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailBasicTest.php
index 6a63a68391..782d537b3e 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailBasicTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailBasicTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for basic email webform handler functionality.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerEmailBasicTest extends WebformBrowserTestBase {
 
@@ -41,9 +41,9 @@ public function testBasicEmailHandler() {
     $sent_email = $this->getLastEmail();
     $this->assertEqual($sent_email['key'], 'test_handler_email_email');
     $this->assertEqual($sent_email['reply-to'], "John Smith <from@example.com>");
-    $this->assertContains('Submitted by: Anonymous', $sent_email['body']);
-    $this->assertContains('First name: John', $sent_email['body']);
-    $this->assertContains('Last name: Smith', $sent_email['body']);
+    $this->assertStringContainsString('Submitted by: Anonymous', $sent_email['body']);
+    $this->assertStringContainsString('First name: John', $sent_email['body']);
+    $this->assertStringContainsString('Last name: Smith', $sent_email['body']);
     $this->assertEqual($sent_email['headers']['From'], 'John Smith <from@example.com>');
     $this->assertEqual($sent_email['headers']['Cc'], 'cc@example.com');
     $this->assertEqual($sent_email['headers']['Bcc'], 'bcc@example.com');
@@ -56,8 +56,8 @@ public function testBasicEmailHandler() {
     $webform->setSetting('results_disabled', TRUE)->save();
     $this->postSubmission($webform, ['first_name' => 'Jane', 'last_name' => 'Doe']);
     $sent_email = $this->getLastEmail();
-    $this->assertContains('First name: Jane', $sent_email['body']);
-    $this->assertContains('Last name: Doe', $sent_email['body']);
+    $this->assertStringContainsString('First name: Jane', $sent_email['body']);
+    $this->assertStringContainsString('Last name: Doe', $sent_email['body']);
     $webform->setSetting('results_disabled', FALSE)->save();
 
     // Check sending a custom email using tokens.
@@ -74,27 +74,27 @@ public function testBasicEmailHandler() {
       'Test that "double quotes" are not encoded.',
     ]);
 
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_email/handlers/email/edit', ['settings[body]' => WebformSelectOther::OTHER_OPTION, 'settings[body_custom_text]' => $body], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_email/handlers/email/edit', ['settings[body]' => WebformSelectOther::OTHER_OPTION, 'settings[body_custom_text]' => $body], 'Save');
 
     $sid = $this->postSubmission($webform);
     /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
     $webform_submission = WebformSubmission::load($sid);
 
     $sent_email = $this->getLastEmail();
-    $this->assertContains('full name: John Smith', $sent_email['body']);
-    $this->assertContains('uuid: ' . $webform_submission->uuid->value, $sent_email['body']);
-    $this->assertContains('sid: ' . $sid, $sent_email['body']);
+    $this->assertStringContainsString('full name: John Smith', $sent_email['body']);
+    $this->assertStringContainsString('uuid: ' . $webform_submission->uuid->value, $sent_email['body']);
+    $this->assertStringContainsString('sid: ' . $sid, $sent_email['body']);
     $date_value = \Drupal::service('date.formatter')->format($webform_submission->created->value, 'medium');
-    $this->assertContains('date: ' . $date_value, $sent_email['body']);
-    $this->assertContains('ip-address: ' . $webform_submission->remote_addr->value, $sent_email['body']);
-    $this->assertContains('user: ' . $admin_user->label(), $sent_email['body']);
-    $this->assertContains("url:", $sent_email['body']);
-    $this->assertContains($webform_submission->toUrl('canonical', ['absolute' => TRUE])
+    $this->assertStringContainsString('date: ' . $date_value, $sent_email['body']);
+    $this->assertStringContainsString('ip-address: ' . $webform_submission->remote_addr->value, $sent_email['body']);
+    $this->assertStringContainsString('user: ' . $admin_user->label(), $sent_email['body']);
+    $this->assertStringContainsString("url:", $sent_email['body']);
+    $this->assertStringContainsString($webform_submission->toUrl('canonical', ['absolute' => TRUE])
       ->toString(), $sent_email['body']);
-    $this->assertContains("edit-url:", $sent_email['body']);
-    $this->assertContains($webform_submission->toUrl('edit-form', ['absolute' => TRUE])
+    $this->assertStringContainsString("edit-url:", $sent_email['body']);
+    $this->assertStringContainsString($webform_submission->toUrl('edit-form', ['absolute' => TRUE])
       ->toString(), $sent_email['body']);
-    $this->assertContains('Test that "double quotes" are not encoded.', $sent_email['body']);
+    $this->assertStringContainsString('Test that "double quotes" are not encoded.', $sent_email['body']);
 
     // Create a submission using HTML is subject and message.
     $edit = [
@@ -102,7 +102,7 @@ public function testBasicEmailHandler() {
       'settings[body]' => '_other_',
       'settings[body_custom_text]' => '[webform_submission:values][webform_submission:values:message:value]',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_email/handlers/email/edit', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_email/handlers/email/edit', $edit, 'Save');
 
     // Check special characters in message value.
     $edit = [
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailMappingTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailMappingTest.php
index 4754dec585..cef3168049 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailMappingTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailMappingTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for email webform handler #options mapping functionality.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerEmailMappingTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailRenderingTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailRenderingTest.php
index 3a149e00bf..d80cd7ed72 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailRenderingTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailRenderingTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for email webform handler rendering functionality.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerEmailRenderingTest extends WebformBrowserTestBase {
 
@@ -18,12 +18,12 @@ class WebformHandlerEmailRenderingTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Make sure we are using distinct default and administrative themes for
     // the duration of these tests.
-    \Drupal::service('theme_handler')->install(['webform_test_bartik', 'seven']);
+    \Drupal::service('theme_installer')->install(['webform_test_bartik', 'seven']);
     $this->config('system.theme')
       ->set('default', 'webform_test_bartik')
       ->set('admin', 'seven')
@@ -55,12 +55,12 @@ public function testEmailRendering() {
     // Check submitting contact form and sending emails using the
     // default bartik.theme.
     $sent_emails = $this->getMails();
-    $this->assertContains('HEADER 1 (CONTACT_EMAIL_CONFIRMATION)', $sent_emails[0]['body']);
-    $this->assertContains('Please ignore this email.', $sent_emails[0]['body']);
-    $this->assertContains('address (contact_email_confirmation)', $sent_emails[0]['body']);
-    $this->assertContains('HEADER 1 (GLOBAL)', $sent_emails[1]['body']);
-    $this->assertContains('Please ignore this email.', $sent_emails[1]['body']);
-    $this->assertContains('address (global)', $sent_emails[1]['body']);
+    $this->assertStringContainsString('HEADER 1 (CONTACT_EMAIL_CONFIRMATION)', $sent_emails[0]['body']);
+    $this->assertStringContainsString('Please ignore this email.', $sent_emails[0]['body']);
+    $this->assertStringContainsString('address (contact_email_confirmation)', $sent_emails[0]['body']);
+    $this->assertStringContainsString('HEADER 1 (GLOBAL)', $sent_emails[1]['body']);
+    $this->assertStringContainsString('Please ignore this email.', $sent_emails[1]['body']);
+    $this->assertStringContainsString('address (global)', $sent_emails[1]['body']);
 
     // Disable dedicated page which will cause the form to now use the
     // seven.theme.
@@ -80,12 +80,12 @@ public function testEmailRendering() {
     // bartik.theme.
     // @see \Drupal\webform\Plugin\WebformHandler\EmailWebformHandler::getMessage
     $sent_emails = $this->getMails();
-    $this->assertContains('HEADER 1 (CONTACT_EMAIL_CONFIRMATION)', $sent_emails[2]['body']);
-    $this->assertContains('Please ignore this email.', $sent_emails[2]['body']);
-    $this->assertContains('address (contact_email_confirmation)', $sent_emails[2]['body']);
-    $this->assertContains('HEADER 1 (GLOBAL)', $sent_emails[3]['body']);
-    $this->assertContains('Please ignore this email.', $sent_emails[3]['body']);
-    $this->assertContains('address (global)', $sent_emails[3]['body']);
+    $this->assertStringContainsString('HEADER 1 (CONTACT_EMAIL_CONFIRMATION)', $sent_emails[2]['body']);
+    $this->assertStringContainsString('Please ignore this email.', $sent_emails[2]['body']);
+    $this->assertStringContainsString('address (contact_email_confirmation)', $sent_emails[2]['body']);
+    $this->assertStringContainsString('HEADER 1 (GLOBAL)', $sent_emails[3]['body']);
+    $this->assertStringContainsString('Please ignore this email.', $sent_emails[3]['body']);
+    $this->assertStringContainsString('address (global)', $sent_emails[3]['body']);
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailRolesTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailRolesTest.php
index 70196f04bc..ca374f28d3 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailRolesTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailRolesTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for email webform handler email roles functionality.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerEmailRolesTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailStatesTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailStatesTest.php
index 13a04baa32..6fdc1e4cc3 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailStatesTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailStatesTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for email webform handler email states.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerEmailStatesTest extends WebformBrowserTestBase {
 
@@ -26,7 +26,7 @@ public function testEmailStates() {
     $webform = Webform::load('test_handler_email_states');
 
     // Check draft saved email.
-    $this->drupalPostForm('/webform/test_handler_email_states', [], t('Save Draft'));
+    $this->drupalPostForm('/webform/test_handler_email_states', [], 'Save Draft');
     $this->assertRaw('Debug: Email: Draft saved');
 
     // Check completed email.
@@ -40,7 +40,7 @@ public function testEmailStates() {
     $this->assertEqual($email['id'], 'webform_test_handler_email_states_email_converted');
 
     // Check updated email.
-    $this->drupalPostForm("/admin/structure/webform/manage/test_handler_email_states/submission/$sid/edit", [], t('Save'));
+    $this->drupalPostForm("/admin/structure/webform/manage/test_handler_email_states/submission/$sid/edit", [], 'Save');
 
     /**************************************************************************/
     // @todo Fix random test failure that can't be reproduced locally.
@@ -58,11 +58,11 @@ public function testEmailStates() {
     $this->assertRaw('<b>Subject:</b> Submission custom<br />');
 
     // Check locked email.
-    $this->drupalPostForm("/admin/structure/webform/manage/test_handler_email_states/submission/$sid/notes", ['locked' => TRUE], t('Save'));
+    $this->drupalPostForm("/admin/structure/webform/manage/test_handler_email_states/submission/$sid/notes", ['locked' => TRUE], 'Save');
     $this->assertRaw('Debug: Email: Submission locked');
 
     // Check deleted email.
-    $this->drupalPostForm("/admin/structure/webform/manage/test_handler_email_states/submission/$sid/delete", [], t('Delete'));
+    $this->drupalPostForm("/admin/structure/webform/manage/test_handler_email_states/submission/$sid/delete", [], 'Delete');
     $this->assertRaw('Debug: Email: Submission deleted');
 
     // Check that 'Send when…' is visible.
@@ -84,7 +84,7 @@ public function testEmailStates() {
 
     // Check that resave draft handler automatically switches
     // states to completed.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_email_states/handlers/email_draft/edit', [], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_email_states/handlers/email_draft/edit', [], 'Save');
     $this->postSubmission($webform);
     $this->assertRaw('Debug: Email: Draft saved');
     $this->assertRaw('Debug: Email: Submission completed');
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailTwigTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailTwigTest.php
index 3aa3456d86..4329e50d48 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailTwigTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerEmailTwigTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for email webform handler Twig functionality.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerEmailTwigTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerExcludedTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerExcludedTest.php
index 4a2fba9848..9204707341 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerExcludedTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerExcludedTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for the webform handler excluded.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerExcludedTest extends WebformBrowserTestBase {
 
@@ -21,7 +21,7 @@ class WebformHandlerExcludedTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
     $this->drupalPlaceBlock('local_actions_block');
   }
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerInvokeAlterHookTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerInvokeAlterHookTest.php
index b7e643e21c..d1c6cd8751 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerInvokeAlterHookTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerInvokeAlterHookTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for the webform handler invoke alter hook.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerInvokeAlterHookTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerPluginTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerPluginTest.php
index 3231e95f17..c5c9a29917 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerPluginTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerPluginTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for the webform handler plugin.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerPluginTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php
index ac4c5749ff..8da58c2d6b 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerRemotePostTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for remote post webform handler functionality.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerRemotePostTest extends WebformBrowserTestBase {
 
@@ -72,7 +72,7 @@ public function testRemotePostHandler() {
   response_type: '200'
   first_name: John
   last_name: Smith");
-    $this->assertRaw('Processed completed request.');
+    $this->assertRaw('This is a custom 200 success message.');
 
     // Check confirmation number is set via the
     // [webform:handler:remote_post:completed:confirmation_number] token.
@@ -85,7 +85,7 @@ public function testRemotePostHandler() {
     sleep(1);
 
     // Check 'updated' operation.
-    $this->drupalPostForm("admin/structure/webform/manage/test_handler_remote_post/submission/$sid/edit", [], t('Save'));
+    $this->drupalPostForm("admin/structure/webform/manage/test_handler_remote_post/submission/$sid/edit", [], 'Save');
     $this->assertRaw("form_params:
   custom_updated: true
   custom_data: true
@@ -95,7 +95,7 @@ public function testRemotePostHandler() {
     $this->assertRaw('Processed updated request.');
 
     // Check 'deleted`' operation.
-    $this->drupalPostForm("admin/structure/webform/manage/test_handler_remote_post/submission/$sid/delete", [], t('Delete'));
+    $this->drupalPostForm("admin/structure/webform/manage/test_handler_remote_post/submission/$sid/delete", [], 'Delete');
     $this->assertRaw("form_params:
   custom_deleted: true
   custom_data: true
@@ -108,7 +108,7 @@ public function testRemotePostHandler() {
     $this->drupalLogout();
 
     // Check 'draft' operation.
-    $this->postSubmission($webform, [], t('Save Draft'));
+    $this->postSubmission($webform, [], 'Save Draft');
     $this->assertRaw("form_params:
   custom_draft_created: true
   custom_data: true
@@ -144,10 +144,19 @@ public function testRemotePostHandler() {
     $this->assertRaw("sid: '$sid'");
     $this->assertNoRaw('Unable to process this submission. Please contact the site administrator.');
 
+    // Check 200 Success Error.
+    $this->postSubmission($webform, ['response_type' => '200']);
+    $this->assertRaw('This is a custom 200 success message.');
+    $this->assertRaw('Processed completed request.');
+    $this->assertRaw('messages--status');
+    $this->assertNoRaw('messages--error');
+
     // Check 500 Internal Server Error.
     $this->postSubmission($webform, ['response_type' => '500']);
     $this->assertRaw('Failed to process completed request.');
     $this->assertRaw('Unable to process this submission. Please contact the site administrator.');
+    $this->assertRaw('messages--error');
+    $this->assertNoRaw('messages--status');
 
     // Check default custom response message.
     $handler = $webform->getHandler('remote_post');
@@ -160,11 +169,21 @@ public function testRemotePostHandler() {
     $this->assertNoRaw('Unable to process this submission. Please contact the site administrator.');
     $this->assertRaw('This is a custom response message');
 
+    // Check 201 Completed with no custom message.
+    $this->postSubmission($webform, ['response_type' => '201']);
+
+    $this->assertNoRaw('Processed created request.');
+    $this->assertNoRaw('This is a custom 404 not found message.');
+    $this->assertNoRaw('messages--status');
+    $this->assertNoRaw('messages--error');
+
     // Check 404 Not Found with custom message.
     $this->postSubmission($webform, ['response_type' => '404']);
     $this->assertRaw('File not found');
     $this->assertNoRaw('Unable to process this submission. Please contact the site administrator.');
     $this->assertRaw('This is a custom 404 not found message.');
+    $this->assertRaw('messages--error');
+    $this->assertNoRaw('messages--status');
 
     // Check 401 Unauthorized with custom message and token.
     $this->postSubmission($webform, ['response_type' => '401']);
@@ -172,6 +191,12 @@ public function testRemotePostHandler() {
     $this->assertNoRaw('Unable to process this submission. Please contact the site administrator.');
     $this->assertRaw('This is a message token <strong>Unauthorized to process completed request.</strong>');
 
+    // Check 405 Method Not Allowed with custom message and token.
+    $this->postSubmission($webform, ['response_type' => '405']);
+    $this->assertRaw('Method Not Allowed');
+    $this->assertNoRaw('Unable to process this submission. Please contact the site administrator.');
+    $this->assertRaw('This is a array token <strong>[webform:handler:remote_post:options]</strong>');
+
     // Disable saving of results.
     $webform->setSetting('results_disabled', TRUE);
     $webform->save();
@@ -310,16 +335,18 @@ public function testRemotePostHandler() {
     ];
     $this->postSubmission($webform, $edit);
     $this->assertRaw("form_params:
-    checkbox: true
-    number: 10
-    number_multiple:
-      - 10.5
-    custom_composite:
-      -
-        textfield: text
-        checkbox: true
-        number: 20.5");
-
+  boolean_true: true
+  integer: 100
+  float: 100.01
+  checkbox: true
+  number: !!float 10
+  number_multiple:
+    - 10.5
+  custom_composite:
+    -
+      textfield: text
+      checkbox: true
+      number: 20.5");
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerSettingsTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerSettingsTest.php
index 85b9112493..49169a7d9e 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerSettingsTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerSettingsTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for settings webform handler functionality.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerSettingsTest extends WebformBrowserTestBase {
 
@@ -32,7 +32,7 @@ public function testSettingsHandler() {
       'confirmation' => TRUE,
       'custom' => TRUE,
     ];
-    $this->drupalPostForm('/webform/test_handler_settings', $edit, t('Save Draft'));
+    $this->drupalPostForm('/webform/test_handler_settings', $edit, 'Save Draft');
     $this->assertRaw($message_indentation . '{Custom draft saved message}');
 
     // Check custom save load message.
@@ -41,12 +41,12 @@ public function testSettingsHandler() {
     $this->assertRaw($message_indentation . '{Custom draft loaded message}');
 
     // Check custom preview title and message.
-    $this->drupalPostForm('/webform/test_handler_settings', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_handler_settings', [], 'Preview');
     $this->assertRaw('<li class="messages__item">{Custom preview message}</li>');
     $this->assertRaw('<h1 class="page-title">{Custom preview title}</h1>');
 
     // Check custom confirmation title and message.
-    $this->drupalPostForm('/webform/test_handler_settings', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_handler_settings', [], 'Submit');
     $this->assertRaw('<h1 class="page-title">{Custom confirmation title}</h1>');
     $this->assertRaw('<div class="webform-confirmation__message">{Custom confirmation message}</div>');
 
@@ -56,7 +56,7 @@ public function testSettingsHandler() {
       'confirmation' => FALSE,
       'custom' => FALSE,
     ];
-    $this->drupalPostForm('/webform/test_handler_settings', $edit, t('Save Draft'));
+    $this->drupalPostForm('/webform/test_handler_settings', $edit, 'Save Draft');
     $this->assertNoRaw($message_indentation . '{Custom draft saved message}');
 
     // Check no custom save load message.
@@ -64,12 +64,12 @@ public function testSettingsHandler() {
     $this->assertNoRaw($message_indentation . '{Custom draft loaded message}');
 
     // Check no custom preview title and message.
-    $this->drupalPostForm('/webform/test_handler_settings', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_handler_settings', [], 'Preview');
     $this->assertNoRaw('<h1 class="page-title">{Custom confirmation title}</h1>');
     $this->assertNoRaw('<div class="webform-confirmation__message">{Custom confirmation message}</div>');
 
     // Check no custom confirmation title and message.
-    $this->drupalPostForm('/webform/test_handler_settings', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_handler_settings', [], 'Submit');
     $this->assertNoRaw('{Custom confirmation title}');
     $this->assertNoRaw('{Custom confirmation message}');
   }
diff --git a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerTest.php b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerTest.php
index 8ba40eb140..0a87cd0c6a 100644
--- a/web/modules/webform/tests/src/Functional/Handler/WebformHandlerTest.php
+++ b/web/modules/webform/tests/src/Functional/Handler/WebformHandlerTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform handler plugin.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHandlerTest extends WebformBrowserTestBase {
 
@@ -102,12 +102,12 @@ public function testWebformHandler() {
     $this->assertRaw('<div class="webform-confirmation__message">::preprocessConfirmation</div>');
 
     // Check update submission plugin invoking.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/submission/' . $sid . '/edit', [], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/submission/' . $sid . '/edit', [], 'Save');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:accessSubmission');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:postSave update');
 
     // Check delete submission plugin invoking.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/submission/' . $sid . '/delete', [], t('Delete'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/submission/' . $sid . '/delete', [], 'Delete');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:accessSubmission');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:postLoad');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:preDelete');
@@ -144,12 +144,12 @@ public function testWebformHandler() {
     $this->assertNoFieldByName('element', 'element_access_denied');
 
     // Check configuration settings.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/test/edit', ['settings[message]' => '{message}'], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/test/edit', ['settings[message]' => '{message}'], 'Save');
     $this->postSubmission($webform_handler_test);
     $this->assertRaw('{message}');
 
     // Check disabling a handler.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/test/edit', ['status' => FALSE], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/test/edit', ['status' => FALSE], 'Save');
     $this->drupalGet('/webform/test_handler_test');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:preCreate');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:postCreate');
@@ -158,7 +158,7 @@ public function testWebformHandler() {
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:alterForm');
 
     // Enable the handler and disable the saving of results.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/test/edit', ['status' => TRUE], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/test/edit', ['status' => TRUE], 'Save');
     $webform_handler_test->setSettings(['results_disabled' => TRUE]);
     $webform_handler_test->save();
 
@@ -208,16 +208,16 @@ public function testWebformHandler() {
     /**************************************************************************/
 
     // Check update handler.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/test/edit', [], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/test/edit', [], 'Save');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:updateHandler');
     $this->assertRaw('The webform handler was successfully updated.');
 
     // Check delete handler.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/test/delete', [], t('Delete'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/test/delete', [], 'Delete');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:deleteHandler');
 
     // Check create handler.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/add/test', ['handler_id' => 'test'], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test/handlers/add/test', ['handler_id' => 'test'], 'Save');
     $this->assertRaw('The webform handler was successfully added.');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:createHandler');
 
@@ -235,7 +235,7 @@ public function testWebformHandler() {
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:alterForm');
 
     // Check test handler is enabled and debug handler is disabled.
-    $this->drupalPostForm('/webform/test_handler_test/test', ['element' => ''], t('Submit'));
+    $this->drupalPostForm('/webform/test_handler_test/test', ['element' => ''], 'Submit');
     $this->assertRaw('One two one two this is just a test');
     $this->assertNoRaw("element: ''");
 
@@ -249,7 +249,7 @@ public function testWebformHandler() {
     $this->assertRaw('Testing the <em class="placeholder">Test: Handler: Test invoke methods</em> webform <em class="placeholder">Debug</em> handler. <strong>All other emails/handlers are disabled.</strong>');
 
     // Check test handler is now disabled and debug handler is enabled.
-    $this->drupalPostForm('/webform/test_handler_test/test', ['element' => ''], t('Submit'), ['query' => ['_webform_handler' => 'debug']]);
+    $this->drupalPostForm('/webform/test_handler_test/test', ['element' => ''], 'Submit', ['query' => ['_webform_handler' => 'debug']]);
     $this->assertNoRaw('One two one two this is just a test');
     $this->assertRaw("element: ''");
 
@@ -272,7 +272,7 @@ public function testWebformHandlerElement() {
   '#title': 'Empty element'
   '#description': 'Entering any value will throw an error",
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test', $edit, 'Save');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:createElement');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:updateElement');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:deleteElement');
@@ -286,7 +286,7 @@ public function testWebformHandlerElement() {
 test:
   '#type': textfield",
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test', $edit, 'Save');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:createElement');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:updateElement');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:deleteElement');
@@ -301,7 +301,7 @@ public function testWebformHandlerElement() {
   '#type': textfield
   '#title': Test",
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test', $edit, 'Save');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:createElement');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:updateElement');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:deleteElement');
@@ -313,7 +313,7 @@ public function testWebformHandlerElement() {
   '#title': 'Empty element'
   '#description': 'Entering any value will throw an error'",
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_handler_test', $edit, 'Save');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:createElement');
     $this->assertNoRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:updateElement');
     $this->assertRaw('Invoked test: Drupal\webform_test_handler\Plugin\WebformHandler\TestWebformHandler:deleteElement');
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAccessDeniedTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAccessDeniedTest.php
index ed05cedfbb..e79d7ffeba 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAccessDeniedTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAccessDeniedTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for access denied webform and submissions.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsAccessDeniedTest extends WebformBrowserTestBase {
 
@@ -31,7 +31,7 @@ class WebformSettingsAccessDeniedTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Place blocks.
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAdminTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAdminTest.php
index bce59e05b8..17f5a26af0 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAdminTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAdminTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform entity.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsAdminTest extends WebformBrowserTestBase {
 
@@ -29,7 +29,7 @@ class WebformSettingsAdminTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
     $this->drupalPlaceBlock('local_actions_block');
   }
@@ -58,7 +58,7 @@ public function testAdminSettings() {
       'advanced' => 'admin/structure/webform/config/advanced',
     ];
     foreach ($types as $path) {
-      $this->drupalPostForm($path, [], t('Save configuration'));
+      $this->drupalPostForm($path, [], 'Save configuration');
       \Drupal::configFactory()->reset('webform.settings');
       $updated_data = \Drupal::configFactory()->getEditable('webform.settings')->getRawData();
       $this->ksort($updated_data);
@@ -81,7 +81,7 @@ public function testAdminSettings() {
     $this->assertPattern('#\{item title\}.+\{item markup\}.+\{item description\}#ms');
 
     // Set the default description display to 'before'.
-    $this->drupalPostForm('/admin/structure/webform/config/elements', ['element[default_description_display]' => 'before'], t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/elements', ['element[default_description_display]' => 'before'], 'Save configuration');
 
     // Check that description is 'before' the element.
     $this->drupalGet('/webform/test_element');
@@ -95,7 +95,7 @@ public function testAdminSettings() {
     $this->assertRaw('<a href="' . $base_path . 'admin/structure/webform/add" class="webform-ajax-link button button-action" data-dialog-type="modal" data-dialog-options="{&quot;width&quot;:700,&quot;dialogClass&quot;:&quot;webform-ui-dialog&quot;}" data-drupal-link-system-path="admin/structure/webform/add">Add webform</a>');
 
     // Disable dialogs.
-    $this->drupalPostForm('/admin/structure/webform/config/advanced', ['ui[dialog_disabled]' => TRUE], t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/advanced', ['ui[dialog_disabled]' => TRUE], 'Save configuration');
 
     // Check that dialogs are disabled. (i.e. use-ajax is not included)
     $this->drupalGet('/admin/structure/webform');
@@ -105,11 +105,11 @@ public function testAdminSettings() {
     /* UI description help */
 
     // Check moving #description to #help for webform admin routes.
-    $this->drupalPostForm('/admin/structure/webform/config/advanced', ['ui[description_help]' => TRUE], t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/advanced', ['ui[description_help]' => TRUE], 'Save configuration');
     $this->assertRaw('<span class="webform-element-help" role="tooltip" tabindex="0" data-webform-help="&lt;div class=&quot;webform-element-help--title&quot;&gt;Display element description as help text (tooltip)&lt;/div&gt;&lt;div class=&quot;webform-element-help--content&quot;&gt;If checked, all element descriptions will be moved to help text (tooltip).&lt;/div&gt;"><span aria-hidden="true">?</span></span>');
 
     // Check moving #description to #help for webform admin routes.
-    $this->drupalPostForm('/admin/structure/webform/config/advanced', ['ui[description_help]' => FALSE], t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/advanced', ['ui[description_help]' => FALSE], 'Save configuration');
     $this->assertNoRaw('<span class="webform-element-help" role="tooltip" tabindex="0" data-webform-help="&lt;div class=&quot;webform-element-help--title&quot;&gt;Display element description as help text (tooltip)&lt;/div&gt;&lt;div class=&quot;webform-element-help--content&quot;&gt;If checked, all element descriptions will be moved to help text (tooltip).&lt;/div&gt;"><span aria-hidden="true">?</span></span>');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAjaxTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAjaxTest.php
index 029dc1058e..e6d9a82ed8 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAjaxTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAjaxTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform submission form ajax.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsAjaxTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsArchivedTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsArchivedTest.php
index b7781138ca..7bc2c3c3dc 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsArchivedTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsArchivedTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform archived.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsArchivedTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAssetsTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAssetsTest.php
index 6c05a9465e..7867caebc0 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAssetsTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAssetsTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform assets settings.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsAssetsTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAutofillTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAutofillTest.php
index b597a7c29c..fb2e6af8b0 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAutofillTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsAutofillTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform submission form autofill.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsAutofillTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsBehaviorsTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsBehaviorsTest.php
index b6d6b18522..7e4f1dc96c 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsBehaviorsTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsBehaviorsTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform settings behaviors.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsBehaviorsTest extends WebformBrowserTestBase {
 
@@ -33,7 +33,7 @@ class WebformSettingsBehaviorsTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
     // Disable description help icon.
     $this->config('webform.settings')->set('ui.description_help', FALSE)->save();
@@ -170,7 +170,7 @@ public function testSettings() {
 
     // Check webform has .js-webform-unsaved class.
     $this->drupalGet('/webform/test_form_unsaved');
-    $this->assertCssSelect('form.js-webform-unsaved', t('Form has .js-webform-unsaved class.'));
+    $this->assertCssSelect('form.js-webform-unsaved', 'Form has .js-webform-unsaved class.');
 
     // Disable YAML specific webform unsaved setting.
     $webform_form_unsaved->setSetting('form_unsaved', FALSE);
@@ -182,7 +182,7 @@ public function testSettings() {
 
     // Check webform no longer has .js-webform-unsaved class.
     $this->drupalGet('/webform/test_form_novalidate');
-    $this->assertNoCssSelect('webform.js-webform-unsaved', t('Webform does not have .js-webform-unsaved class.'));
+    $this->assertNoCssSelect('webform.js-webform-unsaved', 'Webform does not have .js-webform-unsaved class.');
 
     // Enable default (global) unsaved on all webforms.
     \Drupal::configFactory()->getEditable('webform.settings')
@@ -196,7 +196,7 @@ public function testSettings() {
 
     // Check unsaved attribute added to webform.
     $this->drupalGet('/webform/test_form_unsaved');
-    $this->assertCssSelect('form.js-webform-unsaved', t('Form has .js-webform-unsaved class.'));
+    $this->assertCssSelect('form.js-webform-unsaved', 'Form has .js-webform-unsaved class.');
 
     /**************************************************************************/
     /* Test webform disable autocomplete (form_disable_autocomplete) */
@@ -204,7 +204,7 @@ public function testSettings() {
 
     // Check webform has autocomplete=off attribute.
     $this->drupalGet('/webform/test_form_disable_autocomplete');
-    $this->assertCssSelect('form[autocomplete="off"]', t('Form has autocomplete=off attribute.'));
+    $this->assertCssSelect('form[autocomplete="off"]', 'Form has autocomplete=off attribute.');
 
     /**************************************************************************/
     /* Test webform (client-side) novalidate (form_novalidate) */
@@ -214,7 +214,7 @@ public function testSettings() {
 
     // Check webform has novalidate attribute.
     $this->drupalGet('/webform/test_form_novalidate');
-    $this->assertCssSelect('form[novalidate="novalidate"]', t('Form has the proper novalidate attribute.'));
+    $this->assertCssSelect('form[novalidate="novalidate"]', 'Form has the proper novalidate attribute.');
 
     // Disable YAML specific webform client-side validation setting.
     $webform_form_novalidate->setSetting('form_novalidate', FALSE);
@@ -223,11 +223,11 @@ public function testSettings() {
     // Check novalidate checkbox is enabled.
     $this->drupalGet('/admin/structure/webform/manage/test_form_novalidate/settings/form');
     $this->assertRaw('<input data-drupal-selector="edit-form-novalidate" aria-describedby="edit-form-novalidate--description" type="checkbox" id="edit-form-novalidate" name="form_novalidate" value class="form-checkbox" />');
-    $this->assertRaw('If checked, the <a href="http://www.w3schools.com/tags/att_form_novalidate.asp">novalidate</a> attribute, which disables client-side validation, will be added to this form.');
+    $this->assertRaw('If checked, the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form">novalidate</a> attribute, which disables client-side validation, will be added to this form.');
 
     // Check webform no longer has novalidate attribute.
     $this->drupalGet('/webform/test_form_novalidate');
-    $this->assertNoCssSelect('form[novalidate="novalidate"]', t('Webform have client-side validation enabled.'));
+    $this->assertNoCssSelect('form[novalidate="novalidate"]', 'Webform have client-side validation enabled.');
 
     // Enable default (global) disable client-side validation on all webforms.
     \Drupal::configFactory()->getEditable('webform.settings')
@@ -236,13 +236,13 @@ public function testSettings() {
 
     // Check novalidate checkbox is disabled.
     $this->drupalGet('/admin/structure/webform/manage/test_form_novalidate/settings/form');
-    $this->assertNoRaw('If checked, the <a href="http://www.w3schools.com/tags/att_form_novalidate.asp">novalidate</a> attribute, which disables client-side validation, will be added to this form.');
+    $this->assertNoRaw('If checked, the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form">novalidate</a> attribute, which disables client-side validation, will be added to this form.');
     $this->assertRaw('<input data-drupal-selector="edit-form-novalidate-disabled" aria-describedby="edit-form-novalidate-disabled--description" disabled="disabled" type="checkbox" id="edit-form-novalidate-disabled" name="form_novalidate_disabled" value="1" checked="checked" class="form-checkbox" />');
     $this->assertRaw('Client-side validation is disabled for all forms.');
 
     // Check novalidate attribute added to webform.
     $this->drupalGet('/webform/test_form_novalidate');
-    $this->assertCssSelect('form[novalidate="novalidate"]', t('Form has the proper novalidate attribute.'));
+    $this->assertCssSelect('form[novalidate="novalidate"]', 'Form has the proper novalidate attribute.');
 
     /**************************************************************************/
     /* Test required indicator (form_required) */
@@ -302,7 +302,7 @@ public function testSettings() {
 
     // Check webform has .webform-details-toggle class.
     $this->drupalGet('/webform/test_form_details_toggle');
-    $this->assertCssSelect('form.webform-details-toggle', t('Form has the .webform-details-toggle class.'));
+    $this->assertCssSelect('form.webform-details-toggle', 'Form has the .webform-details-toggle class.');
 
     // Check details toggle checkbox is disabled.
     $this->drupalGet('/admin/structure/webform/manage/test_form_details_toggle/settings/form');
@@ -316,7 +316,7 @@ public function testSettings() {
 
     // Check .webform-details-toggle class still added to webform.
     $this->drupalGet('/webform/test_form_details_toggle');
-    $this->assertCssSelect('form.webform-details-toggle', t('Form has the .webform-details-toggle class.'));
+    $this->assertCssSelect('form.webform-details-toggle', 'Form has the .webform-details-toggle class.');
 
     // Check details toggle checkbox is enabled.
     $this->drupalGet('/admin/structure/webform/manage/test_form_details_toggle/settings/form');
@@ -329,7 +329,7 @@ public function testSettings() {
 
     // Check webform does not hav .webform-details-toggle class.
     $this->drupalGet('/webform/test_form_details_toggle');
-    $this->assertNoCssSelect('webform.webform-details-toggle', t('Webform does not have the .webform-details-toggle class.'));
+    $this->assertNoCssSelect('webform.webform-details-toggle', 'Webform does not have the .webform-details-toggle class.');
 
     /**************************************************************************/
     /* Test webform disable inline form errors (test_form_disable_inline_errors) */
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsConfidentialTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsConfidentialTest.php
index 81d9cdb9d2..3a3b8dd94f 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsConfidentialTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsConfidentialTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for confidential webform submissions.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsConfidentialTest extends WebformBrowserTestBase {
 
@@ -51,7 +51,7 @@ public function testConfidential() {
     // Check that test submission does not record the IP address.
     $sid = $this->postSubmissionTest($webform, ['name' => 'John']);
     $webform_submission = WebformSubmission::load($sid);
-    $this->assertEqual($webform_submission->getRemoteAddr(), t('(unknown)'));
+    $this->assertEqual($webform_submission->getRemoteAddr(), '(unknown)');
     $this->assertEqual($webform_submission->getOwnerId(), 0);
 
     // Check anonymous access to webform.
@@ -63,7 +63,7 @@ public function testConfidential() {
     // Check that submission does not track the requests IP address.
     $sid = $this->postSubmission($webform, ['name' => 'John']);
     $webform_submission = WebformSubmission::load($sid);
-    $this->assertEqual($webform_submission->getRemoteAddr(), t('(unknown)'));
+    $this->assertEqual($webform_submission->getRemoteAddr(), '(unknown)');
     $this->assertEqual($webform_submission->getOwnerId(), 0);
 
     // Check that previous submissions are visible.
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsConfirmationTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsConfirmationTest.php
index ff35cf99f4..c1fd7bd4b7 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsConfirmationTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsConfirmationTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform submission form confirmation.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsConfirmationTest extends WebformBrowserTestBase {
 
@@ -32,7 +32,7 @@ class WebformSettingsConfirmationTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Set page.front (aka <front>) to /node instead of /user/login.
@@ -65,7 +65,7 @@ public function testConfirmation() {
     sleep(1);
 
     // Check default message when submission is updated.
-    $this->drupalPostForm("/admin/structure/webform/manage/test_confirmation_message/submission/$sid/edit", [], t('Save'));
+    $this->drupalPostForm("/admin/structure/webform/manage/test_confirmation_message/submission/$sid/edit", [], 'Save');
     $this->assertNoRaw('This is a <b>custom</b> confirmation message. (test: )');
     $this->assertRaw('Submission updated in <em class="placeholder">Test: Confirmation: Message</em>.');
 
@@ -74,7 +74,7 @@ public function testConfirmation() {
       ->save();
 
     // Check default message when submission is updated.
-    $this->drupalPostForm("/admin/structure/webform/manage/test_confirmation_message/submission/$sid/edit", [], t('Save'));
+    $this->drupalPostForm("/admin/structure/webform/manage/test_confirmation_message/submission/$sid/edit", [], 'Save');
     $this->assertRaw('This is a <b>custom</b> confirmation message. (test: )');
     $this->assertNoRaw('Submission updated in <em class="placeholder">Test: Confirmation: Message</em>.');
 
@@ -92,7 +92,7 @@ public function testConfirmation() {
     $this->assertUrl('webform/test_confirmation_modal');
 
     // Check confirmation modal update does not display modal.
-    $this->drupalPostForm("/admin/structure/webform/manage/test_confirmation_modal/submission/$sid/edit", [], t('Save'));
+    $this->drupalPostForm("/admin/structure/webform/manage/test_confirmation_modal/submission/$sid/edit", [], 'Save');
     $this->assertRaw('Submission updated in <em class="placeholder">Test: Confirmation: Modal</em>.');
 
     // Set display confirmation modal when submission is updated.
@@ -100,7 +100,7 @@ public function testConfirmation() {
       ->save();
 
     // Check confirmation modal update does display modal.
-    $this->drupalPostForm("/admin/structure/webform/manage/test_confirmation_modal/submission/$sid/edit", [], t('Save'));
+    $this->drupalPostForm("/admin/structure/webform/manage/test_confirmation_modal/submission/$sid/edit", [], 'Save');
     $this->assertRaw('<b class="webform-confirmation-modal--title">Custom confirmation modal</b><br /><div class="webform-confirmation-modal--content">This is a <b>custom</b> confirmation modal. (test: value)</div>');
 
     /* Test confirmation inline (confirmation_type=inline) */
@@ -108,12 +108,12 @@ public function testConfirmation() {
     $webform_confirmation_inline = Webform::load('test_confirmation_inline');
 
     // Check confirmation inline.
-    $this->drupalPostForm('/webform/test_confirmation_inline', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_confirmation_inline', [], 'Submit');
     $this->assertRaw('<a href="' . $webform_confirmation_inline->toUrl('canonical', ['absolute' => TRUE])->toString() . '" rel="prev" 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->drupalPostForm('/webform/test_confirmation_inline', [], 'Submit', ['query' => ['custom' => 'param']]);
     $this->assertRaw('<a href="' . $webform_confirmation_inline->toUrl('canonical', ['absolute' => TRUE, 'query' => ['custom' => 'param']])->toString() . '" rel="prev" title="Back to form">Back to form</a>');
     $this->assertUrl('webform/test_confirmation_inline', ['query' => ['custom' => 'param']]);
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsDraftTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsDraftTest.php
index 822cfa2699..3483d654f0 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsDraftTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsDraftTest.php
@@ -11,7 +11,7 @@
 /**
  * Tests for webform submission form draft.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsDraftTest extends WebformBrowserTestBase {
 
@@ -57,7 +57,7 @@ public function testDraft() {
       'test_form_draft_anonymous' => 'Test: Webform: Draft anonymous',
     ];
     foreach ($webform_ids as $webform_id => $webform_title) {
-      $is_authenticated = ($webform_id == 'test_form_draft_authenticated') ? TRUE : FALSE;
+      $is_authenticated = ($webform_id === 'test_form_draft_authenticated') ? TRUE : FALSE;
 
       // Login draft account.
       ($is_authenticated) ? $this->drupalLogin($normal_user) : $this->drupalLogout();
@@ -65,7 +65,7 @@ public function testDraft() {
       $webform = Webform::load($webform_id);
 
       // Save a draft.
-      $sid = $this->postSubmission($webform, ['name' => 'John Smith'], t('Save Draft'));
+      $sid = $this->postSubmission($webform, ['name' => 'John Smith'], 'Save Draft');
       /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
       $webform_submission = WebformSubmission::load($sid);
 
@@ -110,7 +110,7 @@ public function testDraft() {
       $this->drupalPostForm("webform/$webform_id", [
         'name' => '',
         'comment' => 'Hello World!',
-      ], t('Save Draft'));
+      ], 'Save Draft');
       $this->assertRaw('Your draft has been saved');
       $this->assertNoRaw('You have an existing draft');
       $this->assertFieldByName('name', '');
@@ -120,7 +120,7 @@ public function testDraft() {
       $this->drupalPostForm("webform/$webform_id", [
         'name' => 'John Smith',
         'comment' => 'Hello World!',
-      ], t('Preview'));
+      ], 'Preview');
       $this->assertNoRaw('Your draft has been saved');
       $this->assertNoRaw('You have an existing draft');
       $this->assertNoFieldByName('name', '');
@@ -130,7 +130,7 @@ public function testDraft() {
       $this->assertRaw('Please review your submission. Your submission is not complete until you press the "Submit" button!');
 
       // Check submit.
-      $this->drupalPostForm("webform/$webform_id", [], t('Submit'));
+      $this->drupalPostForm("webform/$webform_id", [], 'Submit');
       $this->assertRaw("New submission added to $webform_title.");
 
       // Check submission not in draft.
@@ -148,7 +148,7 @@ public function testDraft() {
     $webform = Webform::load('test_form_draft_anonymous');
 
     // Save a draft.
-    $sid = $this->postSubmission($webform, ['name' => 'John Smith'], t('Save Draft'));
+    $sid = $this->postSubmission($webform, ['name' => 'John Smith'], 'Save Draft');
     $this->assertRaw('Your draft has been saved');
 
     // Check that submission is owned anonymous.
@@ -188,7 +188,7 @@ public function testDraft() {
     $webform->setSetting('form_confidential', TRUE);
 
     // Save a draft.
-    $sid = $this->postSubmission($webform, ['name' => 'John Smith'], t('Save Draft'));
+    $sid = $this->postSubmission($webform, ['name' => 'John Smith'], 'Save Draft');
     $this->assertRaw('Your draft has been saved');
 
     // Check that submission is owned anonymous.
@@ -226,13 +226,13 @@ public function testDraft() {
     $this->assertNoFieldByName('state', 'all');
 
     // Check autosave on submit with validation errors.
-    $this->drupalPostForm('/webform/test_form_draft_authenticated', [], t('Submit'));
+    $this->drupalPostForm('/webform/test_form_draft_authenticated', [], 'Submit');
     $this->assertRaw('Name field is required.');
     $this->drupalGet('/webform/test_form_draft_authenticated');
     $this->assertRaw('You have an existing draft');
 
     // Check autosave on preview.
-    $this->drupalPostForm('/webform/test_form_draft_authenticated', ['name' => 'John Smith'], t('Preview'));
+    $this->drupalPostForm('/webform/test_form_draft_authenticated', ['name' => 'John Smith'], 'Preview');
     $this->assertRaw('Please review your submission.');
     $this->drupalGet('/webform/test_form_draft_authenticated');
     $this->assertRaw('You have an existing draft');
@@ -248,7 +248,7 @@ public function testDraft() {
     $webform = Webform::load('test_form_draft_multiple');
 
     // Save first draft.
-    $sid_1 = $this->postSubmission($webform, ['name' => 'John Smith'], t('Save Draft'));
+    $sid_1 = $this->postSubmission($webform, ['name' => 'John Smith'], 'Save Draft');
     $this->assertRaw('Submission saved. You may return to this form later and it will restore the current values.');
     $webform_submission_1 = WebformSubmission::load($sid_1);
 
@@ -285,7 +285,7 @@ public function testDraft() {
     $this->assertRaw('token=' . $webform_submission_1->getToken());
 
     // Save second draft.
-    $sid_2 = $this->postSubmission($webform, ['name' => 'John Smith'], t('Save Draft'));
+    $sid_2 = $this->postSubmission($webform, ['name' => 'John Smith'], 'Save Draft');
     $webform_submission_2 = WebformSubmission::load($sid_2);
     $this->assertRaw('Submission saved. You may return to this form later and it will restore the current values.');
     $this->drupalGet('/webform/test_form_draft_multiple');
@@ -318,7 +318,7 @@ public function testDraft() {
     $this->assertFieldByName('name', '');
 
     // Save third anonymous draft.
-    $this->postSubmission($webform, ['name' => 'Jane Doe'], t('Save Draft'));
+    $this->postSubmission($webform, ['name' => 'Jane Doe'], 'Save Draft');
     $this->assertRaw('Submission saved. You may return to this form later and it will restore the current values.');
 
     // Check restore third anonymous draft.
@@ -340,26 +340,26 @@ public function testDraft() {
     $webform = Webform::load('test_form_draft_authenticated');
 
     // Check saved draft.
-    $sid = $this->postSubmission($webform, ['name' => 'John Smith'], t('Save Draft'));
+    $sid = $this->postSubmission($webform, ['name' => 'John Smith'], 'Save Draft');
     $this->assertNotNull($sid);
     $webform_submission = WebformSubmission::load($sid);
     $this->assertEqual($sid, $webform_submission->id());
 
     // Check reset delete's the draft.
-    $this->postSubmission($webform, [], t('Reset'));
+    $this->postSubmission($webform, [], 'Reset');
     \Drupal::entityTypeManager()->getStorage('webform_submission')->resetCache();
     $webform_submission = WebformSubmission::load($sid);
     $this->assertNull($webform_submission);
 
     // Check submission with comment.
-    $sid = $this->postSubmission($webform, ['name' => 'John Smith', 'comment' => 'This is a comment'], t('Save Draft'));
+    $sid = $this->postSubmission($webform, ['name' => 'John Smith', 'comment' => 'This is a comment'], 'Save Draft');
     $this->postSubmission($webform);
     \Drupal::entityTypeManager()->getStorage('webform_submission')->resetCache();
     $webform_submission = WebformSubmission::load($sid);
     $this->assertEqual('This is a comment', $webform_submission->getElementData('comment'));
 
     // Check submitted draft is not delete on reset.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_form_draft_authenticated/submission/' . $sid . '/edit', ['comment' => 'This is ignored'], t('Reset'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_form_draft_authenticated/submission/' . $sid . '/edit', ['comment' => 'This is ignored'], 'Reset');
     \Drupal::entityTypeManager()->getStorage('webform_submission')->resetCache();
     $webform_submission = WebformSubmission::load($sid);
     $this->assertEqual($sid, $webform_submission->id());
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsFormTitleTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsFormTitleTest.php
index 13fbc35902..4a09679bfe 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsFormTitleTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsFormTitleTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform form title.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsFormTitleTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsLimitUniqueTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsLimitUniqueTest.php
index c9d77e0cba..3ea019a4e5 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsLimitUniqueTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsLimitUniqueTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform submission form unique limit.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsLimitUniqueTest extends WebformNodeBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsLimitsTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsLimitsTest.php
index 1b564640cd..e1ad82cb19 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsLimitsTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsLimitsTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform submission form limits.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsLimitsTest extends WebformBrowserTestBase {
 
@@ -30,7 +30,7 @@ class WebformSettingsLimitsTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Place webform test blocks.
@@ -72,7 +72,7 @@ public function testFormLimits() {
     $this->drupalLogin($own_submission_user);
 
     // Check that draft does not count toward limit.
-    $this->postSubmission($webform_limit, [], t('Save Draft'));
+    $this->postSubmission($webform_limit, [], 'Save Draft');
     $this->drupalGet('/webform/test_form_limit');
     $this->assertFieldByName('op', 'Submit');
     $this->assertRaw('A partially-completed form was found. Please complete the remaining portions.');
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPathTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPathTest.php
index 81370b6f4d..53393b9329 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPathTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPathTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform path and page.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsPathTest extends WebformBrowserTestBase {
 
@@ -20,8 +20,8 @@ class WebformSettingsPathTest extends WebformBrowserTestBase {
    * Tests YAML page and title.
    */
   public function testPaths() {
-    /** @var \Drupal\Core\Path\AliasStorageInterface $alias_storage */
-    $alias_storage = $this->container->get('path.alias_storage');
+    /** @var \Drupal\path_alias\AliasRepositoryInterface $path_alias_repository */
+    $path_alias_repository = $this->container->get('path_alias.repository');
 
     $node = $this->drupalCreateNode();
 
@@ -47,10 +47,10 @@ public function testPaths() {
     $this->drupalLogin($this->rootUser);
 
     // Check that aliases exist.
-    $this->assert(is_array($alias_storage->load(['alias' => $form_path])));
-    $this->assert(is_array($alias_storage->load(['alias' => "$form_path/confirmation"])));
-    $this->assert(is_array($alias_storage->load(['alias' => "$form_path/drafts"])));
-    $this->assert(is_array($alias_storage->load(['alias' => "$form_path/submissions"])));
+    $this->assertIsArray($path_alias_repository->lookupByAlias($form_path, 'en'));
+    $this->assertIsArray($path_alias_repository->lookupByAlias("$form_path/confirmation", 'en'));
+    $this->assertIsArray($path_alias_repository->lookupByAlias("$form_path/drafts", 'en'));
+    $this->assertIsArray($path_alias_repository->lookupByAlias("$form_path/submissions", 'en'));
 
     // Check default system submit path.
     $this->drupalGet($webform_path);
@@ -78,10 +78,10 @@ public function testPaths() {
     $webform->setSettings(['page' => FALSE])->save();
 
     // Check that aliases do not exist.
-    $this->assertFalse($alias_storage->load(['alias' => $form_path]));
-    $this->assertFalse($alias_storage->load(['alias' => "$form_path/confirmation"]));
-    $this->assertFalse($alias_storage->load(['alias' => "$form_path/drafts"]));
-    $this->assertFalse($alias_storage->load(['alias' => "$form_path/submissions"]));
+    $this->assertNull($path_alias_repository->lookupByAlias($form_path, 'en'));
+    $this->assertNull($path_alias_repository->lookupByAlias("$form_path/confirmation", 'en'));
+    $this->assertNull($path_alias_repository->lookupByAlias("$form_path/drafts", 'en'));
+    $this->assertNull($path_alias_repository->lookupByAlias("$form_path/submissions", 'en'));
 
     // Check page hidden (i.e. access denied).
     $this->drupalGet($webform_path);
@@ -116,7 +116,7 @@ public function testPaths() {
     // Check custom base path.
     $webform->setSettings(['page_submit_path' => '', 'page_confirm_path' => ''])->save();
     $this->drupalLogin($this->rootUser);
-    $this->drupalPostForm('/admin/structure/webform/config', ['page_settings[default_page_base_path]' => 'base/path'], t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config', ['page_settings[default_page_base_path]' => 'base/path'], 'Save configuration');
     $this->drupalGet('/base/path/' . str_replace('_', '-', $webform->id()));
     $this->assertResponse(200, 'Submit URL alias with custom base path exists');
     $this->drupalGet('/base/path/' . str_replace('_', '-', $webform->id()) . '/confirmation');
@@ -160,7 +160,7 @@ public function testPaths() {
     $this->assertResponse(404, 'Submit URL alias does not exist');
 
     /**************************************************************************/
-    // Admin theme.
+    // Page theme.
     /**************************************************************************/
 
     $this->drupalLogin($this->rootUser);
@@ -181,14 +181,14 @@ public function testPaths() {
     $this->assertNoRaw('seven');
 
     // Install Seven and set it as the default admin theme.
-    \Drupal::service('theme_handler')->install(['seven']);
+    \Drupal::service('theme_installer')->install(['seven']);
 
     $edit = [
       'admin_theme' => 'seven',
       'use_admin_theme' => TRUE,
     ];
-    $this->drupalPostForm('/admin/appearance', $edit, t('Save configuration'));
-    $webform->setSetting('page_admin_theme', TRUE)->save();
+    $this->drupalPostForm('/admin/appearance', $edit, 'Save configuration');
+    $webform->setSetting('page_theme_name', 'seven')->save();
 
     // Check that admin theme is applied.
     $this->drupalGet('/webform/test_admin_theme');
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPrepopulateTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPrepopulateTest.php
index cbd445ad61..61f93654b5 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPrepopulateTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPrepopulateTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform prepopulate settings.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsPrepopulateTest extends WebformBrowserTestBase {
 
@@ -31,7 +31,7 @@ class WebformSettingsPrepopulateTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
     $this->placeBlocks();
   }
@@ -71,7 +71,7 @@ public function testPrepopulate() {
     /**************************************************************************/
 
     // Check prepopulating source entity.
-    $this->drupalPostForm('/webform/test_form_prepopulate', [], t('Submit'), ['query' => ['source_entity_type' => 'webform', 'source_entity_id' => 'contact']]);
+    $this->drupalPostForm('/webform/test_form_prepopulate', [], 'Submit', ['query' => ['source_entity_type' => 'webform', 'source_entity_id' => 'contact']]);
     $sid = $this->getLastSubmissionId($webform_prepopulate);
     $webform_submission = WebformSubmission::load($sid);
     $this->assertNotNull($webform_submission->getSourceEntity());
@@ -83,10 +83,10 @@ public function testPrepopulate() {
     // Check disabling prepopulation source entity.
     $webform_prepopulate->setSetting('form_prepopulate_source_entity', FALSE);
     $webform_prepopulate->save();
-    $this->drupalPostForm('/webform/test_form_prepopulate', [], t('Submit'), ['query' => ['source_entity_type' => 'webform', 'source_entity_id' => 'contact']]);
+    $this->drupalPostForm('/webform/test_form_prepopulate', [], 'Submit', ['query' => ['source_entity_type' => 'webform', 'source_entity_id' => 'contact']]);
     $sid = $this->getLastSubmissionId($webform_prepopulate);
     $webform_submission = WebformSubmission::load($sid);
-    $this->assert(!$webform_submission->getSourceEntity());
+    $this->assertNull($webform_submission->getSourceEntity());
 
     // Set prepopulated source entity required.
     $webform_prepopulate->setSetting('form_prepopulate_source_entity', TRUE);
@@ -110,7 +110,7 @@ public function testPrepopulate() {
 
     // Check that required prepopulated source entity can be updated (edit).
     $this->drupalLogin($this->rootUser);
-    $sid = $this->postSubmission($webform_prepopulate, [], t('Submit'), ['query' => ['source_entity_type' => 'webform', 'source_entity_id' => 'contact']]);
+    $sid = $this->postSubmission($webform_prepopulate, [], 'Submit', ['query' => ['source_entity_type' => 'webform', 'source_entity_id' => 'contact']]);
     $this->drupalGet("/admin/structure/webform/manage/test_form_prepopulate/submission/$sid/edit");
     $this->assertNoRaw('This webform is not available. Please contact the site administrator.');
     $this->drupalLogout();
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPreviewTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPreviewTest.php
index 8411965b43..1354ac52e8 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPreviewTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPreviewTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform submission form preview.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsPreviewTest extends WebformBrowserTestBase {
 
@@ -22,7 +22,7 @@ class WebformSettingsPreviewTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Exclude Progress tracker so that the default progress bar is displayed.
@@ -46,7 +46,7 @@ public function testPreview() {
     $this->assertFieldByName('op', 'Preview');
 
     // Check default preview with values.
-    $this->drupalPostForm('/webform/test_form_preview', ['name' => 'test', 'email' => 'example@example.com', 'checkbox' => TRUE], t('Preview'));
+    $this->drupalPostForm('/webform/test_form_preview', ['name' => 'test', 'email' => 'example@example.com', 'checkbox' => TRUE], 'Preview');
 
     $this->assertRaw('<h1 class="page-title">Test: Webform: Preview: Preview</h1>');
 
@@ -73,7 +73,7 @@ public function testPreview() {
     $this->assertRaw('<div class="webform-preview js-form-wrapper form-wrapper" data-drupal-selector="edit-preview" id="edit-preview">');
 
     // Check default preview without values.
-    $this->drupalPostForm('/webform/test_form_preview', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_form_preview', [], 'Preview');
     $this->assertNoRaw('<label>Name</label>');
     $this->assertNoRaw('<label>Email</label>');
     $this->assertNoRaw('<label>Checkbox</label>');
@@ -98,7 +98,7 @@ public function testPreview() {
       ->save();
 
     // Check blank preview message is not displayed.
-    $this->drupalPostForm('/webform/test_form_preview', ['name' => 'test', 'email' => 'example@example.com'], t('Preview'));
+    $this->drupalPostForm('/webform/test_form_preview', ['name' => 'test', 'email' => 'example@example.com'], 'Preview');
     $this->assertNoRaw('Please review your submission. Your submission is not complete until you press the "Submit" button!');
 
     // Set preview and submission to include empty.
@@ -109,7 +109,7 @@ public function testPreview() {
     $webform_preview->save();
 
     // Check empty elements are included in preview.
-    $this->drupalPostForm('/webform/test_form_preview', ['name' => '', 'email' => '', 'checkbox' => FALSE], t('Preview'));
+    $this->drupalPostForm('/webform/test_form_preview', ['name' => '', 'email' => '', 'checkbox' => FALSE], 'Preview');
     $this->assertRaw('<label>Name</label>' . PHP_EOL . '        {Empty}');
     $this->assertRaw('<div class="format-attributes-class webform-element webform-element-type-email js-form-item form-item js-form-type-item form-type-item js-form-item-email form-item-email" id="test_form_preview--email">');
     $this->assertRaw('<label>Email</label>' . PHP_EOL . '        {Empty}');
@@ -139,7 +139,7 @@ public function testPreview() {
     $this->assertRaw('<h1 class="page-title">This has special characters. &#039;&lt;&gt;&quot;&amp;</h1>');
 
     // Check special characters in preview page title.
-    $this->drupalPostForm('/webform/test_form_preview', ['name' => 'test'], t('Preview'));
+    $this->drupalPostForm('/webform/test_form_preview', ['name' => 'test'], 'Preview');
     $this->assertRaw('<title>This has special characters. \'"&: Preview | Drupal</title>');
     $this->assertRaw('<h1 class="page-title">This has special characters. &#039;&lt;&gt;&quot;&amp;: Preview</h1>');
 
@@ -162,7 +162,7 @@ public function testPreview() {
     $webform_preview->save();
 
     // Check custom preview.
-    $this->drupalPostForm('/webform/test_form_preview', ['name' => 'test'], t('{Preview}'));
+    $this->drupalPostForm('/webform/test_form_preview', ['name' => 'test'], '{Preview}');
     $this->assertRaw('<h1 class="page-title">{Title}</h1>');
     $this->assertRaw('<b>{Label}</b></li>');
     $this->assertRaw('{Message}');
@@ -177,7 +177,7 @@ public function testPreview() {
     $this->assertFieldByName('op', '{Preview}');
 
     // Check empty element is excluded from preview.
-    $this->drupalPostForm('/webform/test_form_preview', ['name' => 'test', 'email' => ''], t('{Preview}'));
+    $this->drupalPostForm('/webform/test_form_preview', ['name' => 'test', 'email' => ''], '{Preview}');
     $this->assertRaw('<label>Name</label>' . PHP_EOL . '        test');
     $this->assertNoRaw('<label>Email</label>');
   }
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPreviousTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPreviousTest.php
index 7d17f2c20c..282e0e1d05 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPreviousTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsPreviousTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform submission form previous.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsPreviousTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsRemoteAddrTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsRemoteAddrTest.php
index 9af0ecad46..c3ef5a27c8 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsRemoteAddrTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsRemoteAddrTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for disable tracking of remote IP address.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsRemoteAddrTest extends WebformBrowserTestBase {
 
@@ -39,11 +39,11 @@ public function testRemoteAddr() {
     $webform = Webform::load('test_form_remote_addr');
     $sid = $this->postSubmission($webform, ['name' => 'John']);
     $webform_submission = WebformSubmission::load($sid);
-    $this->assertEqual($webform_submission->getRemoteAddr(), t('(unknown)'));
+    $this->assertEqual($webform_submission->getRemoteAddr(), '(unknown)');
     $this->assertEqual($webform_submission->getOwnerId(), 1);
 
     $webform_submission = WebformSubmissionForm::submitFormValues($values);
-    $this->assertEqual($webform_submission->getRemoteAddr(), t('(unknown)'));
+    $this->assertEqual($webform_submission->getRemoteAddr(), '(unknown)');
     $this->assertEqual($webform_submission->getOwnerId(), 1);
 
     // Enable the setting and make sure the IP is stored.
@@ -51,11 +51,11 @@ public function testRemoteAddr() {
     $webform->save();
     $sid = $this->postSubmission($webform, ['name' => 'John']);
     $webform_submission = WebformSubmission::load($sid);
-    $this->assertNotEqual($webform_submission->getRemoteAddr(), t('(unknown)'));
+    $this->assertNotEqual($webform_submission->getRemoteAddr(), '(unknown)');
     $this->assertEqual($webform_submission->getOwnerId(), 1);
 
     $webform_submission = WebformSubmissionForm::submitFormValues($values);
-    $this->assertNotEqual($webform_submission->getRemoteAddr(), t('(unknown)'));
+    $this->assertNotEqual($webform_submission->getRemoteAddr(), '(unknown)');
     $this->assertEqual($webform_submission->getOwnerId(), 1);
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsScheduleTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsScheduleTest.php
index 4f7431f62a..2909838c59 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsScheduleTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsScheduleTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform submission form settings.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsScheduleTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsSerialTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsSerialTest.php
index d84d4e1e3b..ed03e01805 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsSerialTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsSerialTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform submission serial number.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsSerialTest extends WebformBrowserTestBase {
 
@@ -23,7 +23,7 @@ public function testSettings() {
     $webform_contact = Webform::load('contact');
 
     // Set next serial to 99.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings/submissions', ['next_serial' => 99], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings/submissions', ['next_serial' => 99], 'Save');
 
     // Check next serial is 99.
     $sid = $this->postSubmissionTest($webform_contact);
@@ -31,7 +31,7 @@ public function testSettings() {
     $this->assertEqual($webform_submission->serial(), 99);
 
     // Check that next serial is set to max serial.
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings/submissions', ['next_serial' => 1], t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings/submissions', ['next_serial' => 1], 'Save');
     $this->assertRaw('The next submission number was increased to 100 to make it higher than existing submissions.');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsStatusTest.php b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsStatusTest.php
index ec14b3c3dc..fa8851599c 100644
--- a/web/modules/webform/tests/src/Functional/Settings/WebformSettingsStatusTest.php
+++ b/web/modules/webform/tests/src/Functional/Settings/WebformSettingsStatusTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform default status.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSettingsStatusTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/States/WebformStatesHiddenTest.php b/web/modules/webform/tests/src/Functional/States/WebformStatesHiddenTest.php
index 371d838576..de6c287554 100644
--- a/web/modules/webform/tests/src/Functional/States/WebformStatesHiddenTest.php
+++ b/web/modules/webform/tests/src/Functional/States/WebformStatesHiddenTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform states hidden.
  *
- * @group Webform
+ * @group webform
  */
 class WebformStatesHiddenTest extends WebformBrowserTestBase {
 
@@ -28,7 +28,7 @@ class WebformStatesHiddenTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create filters.
@@ -36,7 +36,7 @@ public function setUp() {
   }
 
   /**
-   * Tests states hidden..
+   * Tests states hidden.
    */
   public function testFormStatesHidden() {
     $this->drupalGet('/webform/test_states_server_hidden');
diff --git a/web/modules/webform/tests/src/Functional/States/WebformStatesPreviewTest.php b/web/modules/webform/tests/src/Functional/States/WebformStatesPreviewTest.php
index 1ddc6a408a..5a588cab8e 100644
--- a/web/modules/webform/tests/src/Functional/States/WebformStatesPreviewTest.php
+++ b/web/modules/webform/tests/src/Functional/States/WebformStatesPreviewTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform states preview.
  *
- * @group Webform
+ * @group webform
  */
 class WebformStatesPreviewTest extends WebformBrowserTestBase {
 
@@ -30,7 +30,7 @@ public function testStatesValidatorElementVisible() {
     $webform_preview = Webform::load('test_states_server_preview');
 
     // Check trigger unchecked and elements are conditionally hidden.
-    $this->postSubmission($webform_preview, [], t('Preview'));
+    $this->postSubmission($webform_preview, [], 'Preview');
     $this->assertRaw('trigger_checkbox');
     $this->assertNoRaw('dependent_checkbox');
     $this->assertNoRaw('dependent_markup');
@@ -39,7 +39,7 @@ public function testStatesValidatorElementVisible() {
     $this->assertNoRaw('nested_textfield');
 
     // Check trigger checked and elements are conditionally visible.
-    $this->postSubmission($webform_preview, ['trigger_checkbox' => TRUE], t('Preview'));
+    $this->postSubmission($webform_preview, ['trigger_checkbox' => TRUE], 'Preview');
     $this->assertRaw('trigger_checkbox');
     $this->assertRaw('dependent_checkbox');
     $this->assertRaw('dependent_markup');
@@ -50,7 +50,7 @@ public function testStatesValidatorElementVisible() {
     $webform_save = Webform::load('test_states_server_save');
 
     // Check trigger unchecked and saved.
-    $this->postSubmission($webform_save, ['trigger_checkbox' => FALSE], t('Submit'));
+    $this->postSubmission($webform_save, ['trigger_checkbox' => FALSE], 'Submit');
     $this->assertRaw("trigger_checkbox: 0
 dependent_hidden: ''
 dependent_checkbox: ''
@@ -60,7 +60,7 @@ public function testStatesValidatorElementVisible() {
 dependent_details_textfield: ''");
 
     // Check trigger checked and saved.
-    $this->postSubmission($webform_save, ['trigger_checkbox' => TRUE], t('Submit'));
+    $this->postSubmission($webform_save, ['trigger_checkbox' => TRUE], 'Submit');
     $this->assertRaw("trigger_checkbox: 1
 dependent_hidden: '{dependent_hidden}'
 dependent_checkbox: 0
@@ -73,7 +73,7 @@ public function testStatesValidatorElementVisible() {
     $webform_clear = Webform::load('test_states_server_clear');
 
     // Check trigger unchecked and not cleared.
-    $this->postSubmission($webform_clear, ['trigger_checkbox' => FALSE], t('Submit'));
+    $this->postSubmission($webform_clear, ['trigger_checkbox' => FALSE], 'Submit');
     $this->assertRaw("trigger_checkbox: 0
 dependent_hidden: '{dependent_hidden}'
 dependent_checkbox: 1
diff --git a/web/modules/webform/tests/src/Functional/States/WebformStatesServerTest.php b/web/modules/webform/tests/src/Functional/States/WebformStatesServerTest.php
index 522779589c..4e6869a5f6 100644
--- a/web/modules/webform/tests/src/Functional/States/WebformStatesServerTest.php
+++ b/web/modules/webform/tests/src/Functional/States/WebformStatesServerTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform submission conditions (#states) validator.
  *
- * @group Webform
+ * @group webform
  */
 class WebformStatesServerTest extends WebformBrowserTestBase {
 
@@ -40,7 +40,7 @@ class WebformStatesServerTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create filters.
@@ -496,17 +496,17 @@ public function testFormStatesValidatorRequired() {
 
     // Check a and b sets target required page 1.
     $edit = ['a' => TRUE, 'b' => TRUE, 'c' => FALSE];
-    $this->drupalPostForm('/webform/test_states_server_nested', $edit, t('Next Page >'));
+    $this->drupalPostForm('/webform/test_states_server_nested', $edit, 'Next >');
     $this->assertRaw('page_1_target: [a and b] or c = required field is required.');
 
     // Check c sets target required page 1.
     $edit = ['a' => FALSE, 'b' => TRUE, 'c' => TRUE];
-    $this->drupalPostForm('/webform/test_states_server_nested', $edit, t('Next Page >'));
+    $this->drupalPostForm('/webform/test_states_server_nested', $edit, 'Next >');
     $this->assertRaw('page_1_target: [a and b] or c = required field is required.');
 
     // Check none sets target not required page 1.
     $edit = ['a' => FALSE, 'b' => FALSE, 'c' => FALSE];
-    $this->drupalPostForm('/webform/test_states_server_nested', $edit, t('Next Page >'));
+    $this->drupalPostForm('/webform/test_states_server_nested', $edit, 'Next >');
     $this->assertNoRaw('page_1_target: [a and b] or c = required field is required.');
 
     // Check none sets target not required page 2.
@@ -515,7 +515,7 @@ public function testFormStatesValidatorRequired() {
 
     // Check a and b sets target required page 2.
     $edit = ['a' => TRUE, 'b' => TRUE, 'c' => FALSE, 'page_1_target' => '{value}'];
-    $this->drupalPostForm('/webform/test_states_server_nested', $edit, t('Next Page >'));
+    $this->drupalPostForm('/webform/test_states_server_nested', $edit, 'Next >');
     $this->assertNoRaw('<input data-drupal-selector="edit-page-2-target" type="text" id="edit-page-2-target" name="page_2_target" value="" size="60" maxlength="255" class="form-text" />');
     $this->assertRaw('<label for="edit-page-2-target" class="js-form-required form-required">page_2_target: [a and b] or c = required</label>');
     $this->assertRaw('<input data-drupal-selector="edit-page-2-target" type="text" id="edit-page-2-target" name="page_2_target" value="" size="60" maxlength="255" class="form-text required" required="required" aria-required="true" />');
@@ -535,7 +535,7 @@ public function testFormStatesValidatorRequired() {
     $this->assertFieldByName($trigger_2_name);
 
     // Check cross page states attribute and input on page 2.
-    $this->postSubmission($webform, ['trigger_1' => TRUE], t('Next Page >'));
+    $this->postSubmission($webform, ['trigger_1' => TRUE], 'Next >');
     $this->assertRaw(':input[name=\u0022' . $trigger_1_name . '\u0022]');
     $this->assertFieldByName($trigger_1_name);
   }
diff --git a/web/modules/webform/tests/src/Functional/States/WebformStatesWizardTest.php b/web/modules/webform/tests/src/Functional/States/WebformStatesWizardTest.php
index 4d39072f68..2a9a574b3b 100644
--- a/web/modules/webform/tests/src/Functional/States/WebformStatesWizardTest.php
+++ b/web/modules/webform/tests/src/Functional/States/WebformStatesWizardTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform states wizard server.
  *
- * @group Webform
+ * @group webform
  */
 class WebformStatesWizardTest extends WebformBrowserTestBase {
 
@@ -30,7 +30,7 @@ public function testFormStatesValidatorWizard() {
     /**************************************************************************/
 
     // Go to default #states for page 02 with trigger-checkbox unchecked.
-    $this->postSubmission($webform, [], t('Next Page >'));
+    $this->postSubmission($webform, [], 'Next >');
 
     $this->assertRaw("page_01_trigger_checkbox: 0
 page_01_textfield_required: '{default_value}'
@@ -92,7 +92,7 @@ public function testFormStatesValidatorWizard() {
     $this->assertRaw('<details data-webform-details-nosave data-webform-key="page_02_details_collapsed" data-drupal-selector="edit-page-02-details-collapsed" aria-describedby="edit-page-02-details-collapsed--description" id="edit-page-02-details-collapsed" class="js-form-wrapper form-wrapper" open="open">');
 
     // Check submission data.
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm(NULL, [], 'Submit');
     $this->assertRaw("page_01_trigger_checkbox: 0
 page_01_textfield_required: '{default_value}'
 page_01_textfield_optional: '{default_value}'
@@ -116,7 +116,7 @@ public function testFormStatesValidatorWizard() {
     /**************************************************************************/
 
     // Go to default #states for page 02 with trigger_checkbox checked.
-    $this->postSubmission($webform, ['page_01_trigger_checkbox' => TRUE], t('Next Page >'));
+    $this->postSubmission($webform, ['page_01_trigger_checkbox' => TRUE], 'Next >');
 
     $this->assertRaw("page_01_trigger_checkbox: 1
 page_01_textfield_required: '{default_value}'
@@ -182,7 +182,7 @@ public function testFormStatesValidatorWizard() {
     $this->assertRaw('<details data-webform-details-nosave data-webform-key="page_02_details_collapsed" data-drupal-selector="edit-page-02-details-collapsed" aria-describedby="edit-page-02-details-collapsed--description" id="edit-page-02-details-collapsed" class="js-form-wrapper form-wrapper">');
 
     // Check submission data.
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm(NULL, [], 'Submit');
     $this->assertRaw("page_01_trigger_checkbox: 1
 page_01_textfield_required: '{default_value}'
 page_01_textfield_optional: '{default_value}'
diff --git a/web/modules/webform/tests/src/Functional/Token/WebformTokenSubmissionValueTest.php b/web/modules/webform/tests/src/Functional/Token/WebformTokenSubmissionValueTest.php
index 75ae2a5611..1e7372b630 100644
--- a/web/modules/webform/tests/src/Functional/Token/WebformTokenSubmissionValueTest.php
+++ b/web/modules/webform/tests/src/Functional/Token/WebformTokenSubmissionValueTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform token submission value.
  *
- * @group Webform
+ * @group webform
  */
 class WebformTokenSubmissionValueTest extends WebformBrowserTestBase {
 
@@ -29,7 +29,7 @@ class WebformTokenSubmissionValueTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create 'tags' vocabulary.
diff --git a/web/modules/webform/tests/src/Functional/Token/WebformTokenSuffixesTest.php b/web/modules/webform/tests/src/Functional/Token/WebformTokenSuffixesTest.php
index bf5034c18e..1eb39b94ef 100644
--- a/web/modules/webform/tests/src/Functional/Token/WebformTokenSuffixesTest.php
+++ b/web/modules/webform/tests/src/Functional/Token/WebformTokenSuffixesTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform token suffixes.
  *
- * @group Webform
+ * @group webform
  */
 class WebformTokenSuffixesTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Token/WebformTokenValidateTest.php b/web/modules/webform/tests/src/Functional/Token/WebformTokenValidateTest.php
index be0653e1fb..bdb97464bb 100644
--- a/web/modules/webform/tests/src/Functional/Token/WebformTokenValidateTest.php
+++ b/web/modules/webform/tests/src/Functional/Token/WebformTokenValidateTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform token element validation.
  *
- * @group Webform
+ * @group webform
  */
 class WebformTokenValidateTest extends WebformBrowserTestBase {
 
@@ -25,12 +25,12 @@ public function testWebformTokenValidate() {
     $this->drupalLogin($this->rootUser);
 
     // Check invalid token validation.
-    $this->drupalPostForm('/admin/structure/webform/config', ['form_settings[default_form_open_message][value]' => '[webform:invalid]'], t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config', ['form_settings[default_form_open_message][value]' => '[webform:invalid]'], 'Save configuration');
     $this->assertRaw('invalid tokens');
     $this->assertRaw('<em class="placeholder">Default open message</em> is using the following invalid tokens: [webform:invalid].');
 
     // Check valid token validation.
-    $this->drupalPostForm('/admin/structure/webform/config', ['form_settings[default_form_open_message][value]' => '[webform:title]'], t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config', ['form_settings[default_form_open_message][value]' => '[webform:title]'], 'Save configuration');
     $this->assertNoRaw('invalid tokens');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Variant/WebformVariantApplyTest.php b/web/modules/webform/tests/src/Functional/Variant/WebformVariantApplyTest.php
index b5243732cf..d24d05833a 100644
--- a/web/modules/webform/tests/src/Functional/Variant/WebformVariantApplyTest.php
+++ b/web/modules/webform/tests/src/Functional/Variant/WebformVariantApplyTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for the webform variant apply.
  *
- * @group Webform
+ * @group webform
  */
 class WebformVariantApplyTest extends WebformBrowserTestBase {
 
@@ -63,7 +63,7 @@ public function testVariantApply() {
 
     // Apply 'a' variant.
     $edit = ['delete' => 'none'];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_variant_randomize/variants/apply', $edit, t('Apply'), ['query' => ['variant_id' => 'a']]);
+    $this->drupalPostForm('/admin/structure/webform/manage/test_variant_randomize/variants/apply', $edit, 'Apply', ['query' => ['variant_id' => 'a']]);
     $webform = $this->reloadWebform('test_variant_randomize');
 
     // Check that the 'a' variant has been applied and no variants have been deleted.
@@ -80,7 +80,7 @@ public function testVariantApply() {
 
     // Apply the 'b' variant which is disabled.
     $edit = ['delete' => 'none'];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_variant_randomize/variants/apply', $edit, t('Apply'), ['query' => ['variant_id' => 'b']]);
+    $this->drupalPostForm('/admin/structure/webform/manage/test_variant_randomize/variants/apply', $edit, 'Apply', ['query' => ['variant_id' => 'b']]);
     $webform = $this->reloadWebform('test_variant_randomize');
     $this->assertNoRaw('{X}');
     $this->assertRaw('[B]');
@@ -89,7 +89,7 @@ public function testVariantApply() {
 
     // Apply and delete the 'a' variant.
     $edit = ['delete' => 'selected'];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_variant_randomize/variants/apply', $edit, t('Apply'), ['query' => ['variant_id' => 'a']]);
+    $this->drupalPostForm('/admin/structure/webform/manage/test_variant_randomize/variants/apply', $edit, 'Apply', ['query' => ['variant_id' => 'a']]);
     $webform = $this->reloadWebform('test_variant_randomize');
 
     // Check that the 'a' variant has been applied and no variants have been deleted.
@@ -101,7 +101,7 @@ public function testVariantApply() {
 
     // Apply the 'b' variant and delete all variants.
     $edit = ['delete' => 'all'];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_variant_randomize/variants/apply', $edit, t('Apply'), ['query' => ['variant_id' => 'b']]);
+    $this->drupalPostForm('/admin/structure/webform/manage/test_variant_randomize/variants/apply', $edit, 'Apply', ['query' => ['variant_id' => 'b']]);
     $webform = $this->reloadWebform('test_variant_randomize');
 
     // Check that the 'b' variant has been applied and all variants have been deleted.
diff --git a/web/modules/webform/tests/src/Functional/Variant/WebformVariantElementTest.php b/web/modules/webform/tests/src/Functional/Variant/WebformVariantElementTest.php
index 92843cb8af..5b510d14ba 100644
--- a/web/modules/webform/tests/src/Functional/Variant/WebformVariantElementTest.php
+++ b/web/modules/webform/tests/src/Functional/Variant/WebformVariantElementTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for the webform variant element.
  *
- * @group Webform
+ * @group webform
  */
 class WebformVariantElementTest extends WebformBrowserTestBase {
 
@@ -29,7 +29,7 @@ class WebformVariantElementTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
     $this->placeBlocks();
   }
@@ -88,7 +88,7 @@ public function testVariantElement() {
       'properties[title]' => '{variant_title}',
       'properties[variant]' => 'override',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/webform_variant', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/element/add/webform_variant', $edit, 'Save');
 
     // Check that the 'Variants' tab is visible.
     $this->drupalGet('/admin/structure/webform/manage/contact');
diff --git a/web/modules/webform/tests/src/Functional/Variant/WebformVariantExcludedTest.php b/web/modules/webform/tests/src/Functional/Variant/WebformVariantExcludedTest.php
index 5f5f49ea9c..612c6b91df 100644
--- a/web/modules/webform/tests/src/Functional/Variant/WebformVariantExcludedTest.php
+++ b/web/modules/webform/tests/src/Functional/Variant/WebformVariantExcludedTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for the webform variant excluded.
  *
- * @group Webform
+ * @group webform
  */
 class WebformVariantExcludedTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Variant/WebformVariantOperationsTest.php b/web/modules/webform/tests/src/Functional/Variant/WebformVariantOperationsTest.php
index b2bb5e8178..12b792198a 100644
--- a/web/modules/webform/tests/src/Functional/Variant/WebformVariantOperationsTest.php
+++ b/web/modules/webform/tests/src/Functional/Variant/WebformVariantOperationsTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for the webform variant operations.
  *
- * @group Webform
+ * @group webform
  */
 class WebformVariantOperationsTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Variant/WebformVariantOverrideTest.php b/web/modules/webform/tests/src/Functional/Variant/WebformVariantOverrideTest.php
index ecdda8c25b..d648b4618e 100644
--- a/web/modules/webform/tests/src/Functional/Variant/WebformVariantOverrideTest.php
+++ b/web/modules/webform/tests/src/Functional/Variant/WebformVariantOverrideTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for the webform variant override.
  *
- * @group Webform
+ * @group webform
  */
 class WebformVariantOverrideTest extends WebformBrowserTestBase {
 
@@ -53,6 +53,10 @@ public function testVariantOverride() {
     $this->assertNoRaw('New submission added to Test: Variant override.');
     $this->assertRaw('No results were saved to the database.');
 
+    // Check overriding form properties such as method and action.
+    $this->drupalGet('/webform/test_variant_override', ['query' => ['_webform_variant[variant]' => 'custom_form_properties']]);
+    $this->assertRaw('action="https://drupal.org" method="get"');
+
     // Check missing variant instance displays a warning.
     $this->drupalGet('/webform/test_variant_override');
     $this->drupalGet('/webform/test_variant_override', ['query' => ['_webform_variant[variant]' => 'missing']]);
diff --git a/web/modules/webform/tests/src/Functional/Variant/WebformVariantPluginTest.php b/web/modules/webform/tests/src/Functional/Variant/WebformVariantPluginTest.php
index 3c09a6be99..3057af32b6 100644
--- a/web/modules/webform/tests/src/Functional/Variant/WebformVariantPluginTest.php
+++ b/web/modules/webform/tests/src/Functional/Variant/WebformVariantPluginTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for the webform variant plugin.
  *
- * @group Webform
+ * @group webform
  */
 class WebformVariantPluginTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Variant/WebformVariantRandomizeTest.php b/web/modules/webform/tests/src/Functional/Variant/WebformVariantRandomizeTest.php
index fa7f9b3b4c..fcba54f129 100644
--- a/web/modules/webform/tests/src/Functional/Variant/WebformVariantRandomizeTest.php
+++ b/web/modules/webform/tests/src/Functional/Variant/WebformVariantRandomizeTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for the webform variant randomize.
  *
- * @group Webform
+ * @group webform
  */
 class WebformVariantRandomizeTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/Views/WebformViewsBulkFormTest.php b/web/modules/webform/tests/src/Functional/Views/WebformViewsBulkFormTest.php
index 47496a87f2..24c9d8afe3 100644
--- a/web/modules/webform/tests/src/Functional/Views/WebformViewsBulkFormTest.php
+++ b/web/modules/webform/tests/src/Functional/Views/WebformViewsBulkFormTest.php
@@ -50,7 +50,7 @@ public function testViewsBulkForm() {
       'webform_submission_bulk_form[0]' => TRUE,
       'action' => 'webform_submission_make_sticky_action',
     ];
-    $this->drupalPostForm('/admin/structure/webform/test/views_bulk_form', $edit, t('Apply to selected items'));
+    $this->drupalPostForm('/admin/structure/webform/test/views_bulk_form', $edit, 'Apply to selected items');
     $webform_submission = $this->loadSubmission($webform_submission->id());
     $this->assertTrue($webform_submission->isSticky(), 'Webform submission has been made sticky');
 
@@ -59,7 +59,7 @@ public function testViewsBulkForm() {
       'webform_submission_bulk_form[0]' => TRUE,
       'action' => 'webform_submission_make_unsticky_action',
     ];
-    $this->drupalPostForm('/admin/structure/webform/test/views_bulk_form', $edit, t('Apply to selected items'));
+    $this->drupalPostForm('/admin/structure/webform/test/views_bulk_form', $edit, 'Apply to selected items');
     $webform_submission = $this->loadSubmission($webform_submission->id());
     $this->assertFalse($webform_submission->isSticky(), 'Webform submission is not sticky anymore');
 
@@ -69,7 +69,7 @@ public function testViewsBulkForm() {
       'webform_submission_bulk_form[0]' => TRUE,
       'action' => 'webform_submission_make_lock_action',
     ];
-    $this->drupalPostForm('/admin/structure/webform/test/views_bulk_form', $edit, t('Apply to selected items'));
+    $this->drupalPostForm('/admin/structure/webform/test/views_bulk_form', $edit, 'Apply to selected items');
     $webform_submission = $this->loadSubmission($webform_submission->id());
     $this->assertTrue($webform_submission->isLocked(), 'Webform submission has been locked');
 
@@ -78,7 +78,7 @@ public function testViewsBulkForm() {
       'webform_submission_bulk_form[0]' => TRUE,
       'action' => 'webform_submission_make_unlock_action',
     ];
-    $this->drupalPostForm('/admin/structure/webform/test/views_bulk_form', $edit, t('Apply to selected items'));
+    $this->drupalPostForm('/admin/structure/webform/test/views_bulk_form', $edit, 'Apply to selected items');
     $webform_submission = $this->loadSubmission($webform_submission->id());
     $this->assertFalse($webform_submission->isLocked(), 'Webform submission is not locked anymore');
 
@@ -87,8 +87,8 @@ public function testViewsBulkForm() {
       'webform_submission_bulk_form[0]' => TRUE,
       'action' => 'webform_submission_delete_action',
     ];
-    $this->drupalPostForm('/admin/structure/webform/test/views_bulk_form', $edit, t('Apply to selected items'));
-    $this->drupalPostForm(NULL, [], t('Delete'));
+    $this->drupalPostForm('/admin/structure/webform/test/views_bulk_form', $edit, 'Apply to selected items');
+    $this->drupalPostForm(NULL, [], 'Delete');
     $webform_submission = $this->loadSubmission($webform_submission->id());
     $this->assertNull($webform_submission, '1: Webform submission has been deleted');
 
diff --git a/web/modules/webform/tests/src/Functional/WebformAlterHooksTest.php b/web/modules/webform/tests/src/Functional/WebformAlterHooksTest.php
index cf5a557d52..91b0bc8272 100644
--- a/web/modules/webform/tests/src/Functional/WebformAlterHooksTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformAlterHooksTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform alter hooks.
  *
- * @group Webform
+ * @group webform
  */
 class WebformAlterHooksTest extends WebformNodeBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/WebformBlockCacheTest.php b/web/modules/webform/tests/src/Functional/WebformBlockCacheTest.php
index 75076e5784..26a3788b42 100644
--- a/web/modules/webform/tests/src/Functional/WebformBlockCacheTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformBlockCacheTest.php
@@ -3,7 +3,6 @@
 namespace Drupal\Tests\webform\Functional;
 
 use Drupal\node\Entity\Node;
-use Drupal\Tests\BrowserTestBase;
 use Drupal\webform\Entity\Webform;
 
 /**
@@ -13,7 +12,7 @@
  *
  * @group webform_browser
  */
-class WebformBlockCacheTest extends BrowserTestBase {
+class WebformBlockCacheTest extends WebformBrowserTestBase {
 
   /**
    * {@inheritdoc}
@@ -30,7 +29,7 @@ class WebformBlockCacheTest extends BrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  protected function setUp() {
+  public function setUp() {
     parent::setUp();
 
     $this->authenticatedUser = $this->createUser([
diff --git a/web/modules/webform/tests/src/Functional/WebformBrowserTestBase.php b/web/modules/webform/tests/src/Functional/WebformBrowserTestBase.php
index 05a61acb5e..72608c7e19 100644
--- a/web/modules/webform/tests/src/Functional/WebformBrowserTestBase.php
+++ b/web/modules/webform/tests/src/Functional/WebformBrowserTestBase.php
@@ -16,6 +16,14 @@ abstract class WebformBrowserTestBase extends BrowserTestBase {
   use WebformBrowserTestTrait;
   use WebformAssertLegacyTrait;
 
+  /**
+   * Set default theme to classy.
+   *
+   * @var string
+   * @see https://www.drupal.org/node/3083055
+   */
+  protected $defaultTheme = 'classy';
+
   /**
    * Modules to enable.
    *
@@ -33,7 +41,7 @@ abstract class WebformBrowserTestBase extends BrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
     $this->loadWebforms(static::$testWebforms);
   }
@@ -41,7 +49,7 @@ public function setUp() {
   /**
    * {@inheritdoc}
    */
-  public function tearDown() {
+  protected function tearDown() {
     $this->purgeSubmissions();
     parent::tearDown();
   }
diff --git a/web/modules/webform/tests/src/Functional/WebformBrowserTestBaseTest.php b/web/modules/webform/tests/src/Functional/WebformBrowserTestBaseTest.php
index b95ee8cd37..c405aed885 100644
--- a/web/modules/webform/tests/src/Functional/WebformBrowserTestBaseTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformBrowserTestBaseTest.php
@@ -28,7 +28,7 @@ class WebformBrowserTestBaseTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
   }
 
diff --git a/web/modules/webform/tests/src/Functional/WebformEditorTest.php b/web/modules/webform/tests/src/Functional/WebformEditorTest.php
index b9e4a032c4..477182f8ff 100644
--- a/web/modules/webform/tests/src/Functional/WebformEditorTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformEditorTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform editor.
  *
- * @group Webform
+ * @group webform
  */
 class WebformEditorTest extends WebformBrowserTestBase {
 
@@ -32,7 +32,7 @@ class WebformEditorTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     $this->fileUsage = $this->container->get('file.usage');
@@ -62,7 +62,7 @@ public function testWebformSettingsFiles() {
     $edit = [
       'description[value]' => '<img data-entity-type="file" data-entity-uuid="' . $images[0]->uuid() . '"/>',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, 'Save');
     $this->reloadImages($images);
 
     // Check that first image is not temporary.
@@ -77,7 +77,7 @@ public function testWebformSettingsFiles() {
     $edit = [
       'description[value]' => '<img data-entity-type="file" data-entity-uuid="' . $images[0]->uuid() . '"/><img data-entity-type="file" data-entity-uuid="' . $images[1]->uuid() . '"/>',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, 'Save');
     $this->reloadImages($images);
 
     // Check that first and second image are not temporary.
@@ -93,7 +93,7 @@ public function testWebformSettingsFiles() {
     $edit = [
       'description[value]' => '<img data-entity-type="file" data-entity-uuid="' . $images[1]->uuid() . '"/>',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, 'Save');
     $this->reloadImages($images);
 
     // Check that first is temporary and second image is not temporary.
@@ -109,7 +109,7 @@ public function testWebformSettingsFiles() {
     $edit = [
       'description[value]' => '',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, 'Save');
     $this->reloadImages($images);
 
     // Check that first and second image are temporary.
@@ -128,7 +128,7 @@ public function testWebformSettingsFiles() {
     $edit = [
       'description[value]' => '<img data-entity-type="file" data-entity-uuid="' . $images[0]->uuid() . '"/>',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, 'Save');
     $this->reloadImages($images);
     $this->assertFalse($images[0]->isTemporary());
 
@@ -136,7 +136,7 @@ public function testWebformSettingsFiles() {
     $edit = [
       'description[value]' => '',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, 'Save');
     $this->reloadImages($images);
     $this->assertFalse($images[0]->isTemporary());
 
@@ -148,7 +148,7 @@ public function testWebformSettingsFiles() {
     $edit = [
       'description[value]' => '<img data-entity-type="file" data-entity-uuid="' . $images[0]->uuid() . '"/>',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, 'Save');
     $this->reloadImages($images);
 
     // Check that upload file is not temporary.
@@ -186,7 +186,7 @@ public function testWebformConfigurationFiles() {
     $edit = [
       'form_settings[default_form_open_message][value]' => '<img data-entity-type="file" data-entity-uuid="' . $images[0]->uuid() . '"/>',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config', $edit, 'Save configuration');
     $this->reloadImages($images);
 
     // Check that first image is not temporary.
@@ -201,7 +201,7 @@ public function testWebformConfigurationFiles() {
     $edit = [
       'form_settings[default_form_open_message][value]' => '<img data-entity-type="file" data-entity-uuid="' . $images[0]->uuid() . '"/><img data-entity-type="file" data-entity-uuid="' . $images[1]->uuid() . '"/>',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config', $edit, 'Save configuration');
     $this->reloadImages($images);
 
     // Check that first and second image are not temporary.
@@ -217,7 +217,7 @@ public function testWebformConfigurationFiles() {
     $edit = [
       'form_settings[default_form_open_message][value]' => '<img data-entity-type="file" data-entity-uuid="' . $images[1]->uuid() . '"/>',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config', $edit, 'Save configuration');
     $this->reloadImages($images);
 
     // Check that first is temporary and second image is not temporary.
diff --git a/web/modules/webform/tests/src/Functional/WebformEmailProviderTest.php b/web/modules/webform/tests/src/Functional/WebformEmailProviderTest.php
index 5d9ce85dcc..1b477df7ef 100644
--- a/web/modules/webform/tests/src/Functional/WebformEmailProviderTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformEmailProviderTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform email provider.
  *
- * @group Webform
+ * @group webform
  */
 class WebformEmailProviderTest extends WebformBrowserTestBase {
 
@@ -72,7 +72,7 @@ public function testEmailProvider() {
 
     // Turn on the smtp.module via the UI.
     // @see webform_form_smtp_admin_settings_alter()
-    $this->drupalPostForm('/admin/config/system/smtp', ['smtp_on' => TRUE], t('Save configuration'));
+    $this->drupalPostForm('/admin/config/system/smtp', ['smtp_on' => TRUE], 'Save configuration');
 
     // Check SMTP: Default PHP mailer after smtp.module turned on.
     $this->drupalGet('/admin/reports/status');
diff --git a/web/modules/webform/tests/src/Functional/WebformEntityReferenceItemNormalizerTest.php b/web/modules/webform/tests/src/Functional/WebformEntityReferenceItemNormalizerTest.php
index 93db1d68b3..1987a53e9a 100644
--- a/web/modules/webform/tests/src/Functional/WebformEntityReferenceItemNormalizerTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformEntityReferenceItemNormalizerTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests the normalization of webform entity reference items.
  *
- * @group Webform
+ * @group webform
  */
 class WebformEntityReferenceItemNormalizerTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/WebformEntityStorageTest.php b/web/modules/webform/tests/src/Functional/WebformEntityStorageTest.php
index 4086ba6813..ad5d5ec9c6 100644
--- a/web/modules/webform/tests/src/Functional/WebformEntityStorageTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformEntityStorageTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform storage tests.
  *
- * @group Webform
+ * @group webform
  */
 class WebformEntityStorageTest extends WebformBrowserTestBase {
 
@@ -28,7 +28,7 @@ public function testWebformEntityStorage() {
     // The below test will fail when and if
     // 'Issue #1885830: Enable static caching for config entities.'
     // is resolved.
-    $this->assert(!isset($storage->loadMultiple(['contact'])->cached));
+    $this->assertFalse(isset($storage->loadMultiple(['contact'])->cached));
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/WebformEntityTest.php b/web/modules/webform/tests/src/Functional/WebformEntityTest.php
index bc26421349..c080ecdb3b 100644
--- a/web/modules/webform/tests/src/Functional/WebformEntityTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformEntityTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform entity.
  *
- * @group Webform
+ * @group webform
  */
 class WebformEntityTest extends WebformBrowserTestBase {
 
@@ -26,7 +26,7 @@ class WebformEntityTest extends WebformBrowserTestBase {
   protected static $testWebforms = ['test_submissions'];
 
   /**
-   * Webform submission storage.
+   * The webform submission storage.
    *
    * @var \Drupal\webform\WebformSubmissionStorageInterface
    */
@@ -35,7 +35,7 @@ class WebformEntityTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Storage.
@@ -68,7 +68,7 @@ public function testWebform() {
     $webform_test_submissions->set('elements', "not\nvalid\nyaml")->save();
 
     // Check invalid elements.
-    $this->assertFalse($webform_test_submissions->getElementsInitialized());
+    $this->assertEqual($webform_test_submissions->getElementsInitialized(), []);
 
     // Check invalid element columns.
     $this->assertEqual($webform_test_submissions->getElementsInitializedFlattenedAndHasValue(), []);
diff --git a/web/modules/webform/tests/src/Functional/WebformEntityTranslationTest.php b/web/modules/webform/tests/src/Functional/WebformEntityTranslationTest.php
index 432ec9044b..3196a787a0 100644
--- a/web/modules/webform/tests/src/Functional/WebformEntityTranslationTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformEntityTranslationTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform translation.
  *
- * @group Webform
+ * @group webform
  */
 class WebformEntityTranslationTest extends WebformBrowserTestBase {
 
@@ -22,7 +22,7 @@ class WebformEntityTranslationTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Place blocks.
@@ -37,8 +37,8 @@ public function testTranslate() {
     $this->drupalLogin($this->rootUser);
 
     // Set [site:name] to 'Test Website' and translate it into Spanish.
-    $this->drupalPostForm('/admin/config/system/site-information', ['site_name' => 'Test Website'], t('Save configuration'));
-    $this->drupalPostForm('/admin/config/system/site-information/translate/es/add', ['translation[config_names][system.site][name]' => 'Sitio web de prueba'], t('Save translation'));
+    $this->drupalPostForm('/admin/config/system/site-information', ['site_name' => 'Test Website'], 'Save configuration');
+    $this->drupalPostForm('/admin/config/system/site-information/translate/es/add', ['translation[config_names][system.site][name]' => 'Sitio web de prueba'], 'Save translation');
 
     /** @var \Drupal\webform\WebformTranslationManagerInterface $translation_manager */
     $translation_manager = \Drupal::service('webform.translation_manager');
@@ -69,7 +69,7 @@ public function testTranslate() {
     $this->assertNoLink('Campo de texto');
 
     // Check form builder is not translated when reset.
-    $this->drupalPostForm('/es/admin/structure/webform/manage/test_translation', [], t('Reset'));
+    $this->drupalPostForm('/es/admin/structure/webform/manage/test_translation', [], 'Reset');
     $this->assertLink('Text field');
     $this->assertNoLink('Campo de texto');
 
@@ -118,7 +118,7 @@ public function testTranslate() {
     $this->assertEqual($elements, $translation_element);
 
     // Translate [site:name] into French.
-    $this->drupalPostForm('/admin/config/system/site-information/translate/fr/add', ['translation[config_names][system.site][name]' => 'Site Web de test'], t('Save translation'));
+    $this->drupalPostForm('/admin/config/system/site-information/translate/fr/add', ['translation[config_names][system.site][name]' => 'Site Web de test'], 'Save translation');
 
     // Check default elements.
     $this->drupalGet('/admin/structure/webform/manage/test_translation/translate/fr/add');
@@ -180,7 +180,7 @@ public function testTranslate() {
     $edit = [
       'translation[config_names][webform.webform.test_translation][elements]' => Yaml::encode($translation_elements),
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_translation/translate/fr/add', $edit, t('Save translation'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_translation/translate/fr/add', $edit, 'Save translation');
 
     // Check French translation.
     $this->drupalGet('/fr/webform/test_translation');
@@ -273,7 +273,7 @@ public function testTranslate() {
       'title' => 'DUPLICATE',
       'id' => 'duplicate',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_translation/duplicate', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_translation/duplicate', $edit, 'Save');
 
     // Check duplicate English translation.
     $this->drupalGet('/webform/duplicate', ['language' => $language_manager->getLanguage('en')]);
diff --git a/web/modules/webform/tests/src/Functional/WebformExampleFunctionalTest.php b/web/modules/webform/tests/src/Functional/WebformExampleFunctionalTest.php
index a62318f3f0..4af14de201 100644
--- a/web/modules/webform/tests/src/Functional/WebformExampleFunctionalTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformExampleFunctionalTest.php
@@ -2,14 +2,12 @@
 
 namespace Drupal\Tests\webform\Functional;
 
-use Drupal\Tests\BrowserTestBase;
-
 /**
  * Example of webform browser test.
  *
  * @group webform_browser
  */
-class WebformExampleFunctionalTest extends BrowserTestBase {
+class WebformExampleFunctionalTest extends WebformBrowserTestBase {
 
   /**
    * {@inheritdoc}
diff --git a/web/modules/webform/tests/src/Functional/WebformHelpTest.php b/web/modules/webform/tests/src/Functional/WebformHelpTest.php
index 81ca540da1..7e483e8f4e 100644
--- a/web/modules/webform/tests/src/Functional/WebformHelpTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformHelpTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform help.
  *
- * @group Webform
+ * @group webform
  */
 class WebformHelpTest extends WebformBrowserTestBase {
 
@@ -19,7 +19,7 @@ class WebformHelpTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     $this->drupalPlaceBlock('help_block');
@@ -57,7 +57,7 @@ public function testHelp() {
     $this->assertRaw('The <strong>Advanced configuration</strong> page allows an administrator to enable/disable UI behaviors, manage requirements and define data used for testing webforms.');
 
     // Disable help via the UI which will clear the cached help block.
-    $this->drupalPostForm('/admin/structure/webform/config/advanced', ['ui[help_disabled]' => TRUE], t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/advanced', ['ui[help_disabled]' => TRUE], 'Save configuration');
 
     // Check that help is disabled.
     $this->drupalGet('/admin/structure/webform/config/advanced');
diff --git a/web/modules/webform/tests/src/Functional/WebformLibrariesTest.php b/web/modules/webform/tests/src/Functional/WebformLibrariesTest.php
index f724cc3661..e92a4f26b6 100644
--- a/web/modules/webform/tests/src/Functional/WebformLibrariesTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformLibrariesTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform libraries.
  *
- * @group Webform
+ * @group webform
  */
 class WebformLibrariesTest extends WebformBrowserTestBase {
 
@@ -42,7 +42,7 @@ public function testLibraries() {
       'excluded_libraries[choices]' => TRUE,
       'excluded_libraries[jquery.chosen]' => TRUE,
     ];
-    $this->drupalPostForm('/admin/structure/webform/config/libraries', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/libraries', $edit, 'Save configuration');
 
     // Check optional libraries are included.
     $this->drupalGet('/webform/test_libraries_optional');
@@ -75,7 +75,7 @@ public function testLibraries() {
       'excluded_libraries[jquery.timepicker]' => FALSE,
       'excluded_libraries[jquery.textcounter]' => FALSE,
     ];
-    $this->drupalPostForm('/admin/structure/webform/config/libraries', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/libraries', $edit, 'Save configuration');
 
     // Check optional libraries are excluded.
     $this->drupalGet('/webform/test_libraries_optional');
@@ -116,7 +116,7 @@ public function testLibraries() {
       'excluded_elements[webform_rating]' => FALSE,
       'excluded_elements[webform_signature]' => FALSE,
     ];
-    $this->drupalPostForm('/admin/structure/webform/config/elements', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config/elements', $edit, 'Save configuration');
 
     // Check that status report excludes libraries required by element types.
     $this->drupalGet('/admin/reports/status');
@@ -125,28 +125,46 @@ public function testLibraries() {
     $this->assertNoText('Signature Pad library');
     */
 
-    // Check that choices, chosen, and select2 using webform's CDN URLs.
-    $edit = [
-      'excluded_libraries[jquery.select2]' => TRUE,
-      'excluded_libraries[jquery.chosen]' => TRUE,
-    ];
-    $this->drupalPostForm('/admin/structure/webform/config/libraries', $edit, t('Save configuration'));
-    $this->drupalGet('/webform/test_libraries_optional');
-    $this->assertRaw('https://cdnjs.cloudflare.com/ajax/libs/chosen');
-    $this->assertRaw('https://cdnjs.cloudflare.com/ajax/libs/select2');
-
-    // Install chosen and select2 modules.
-    \Drupal::service('module_installer')->install(['chosen', 'chosen_lib', 'select2']);
-    drupal_flush_all_caches();
-
-    // Check that chosen and select2 using module's path and not CDN.
-    $this->drupalGet('/webform/test_libraries_optional');
-    $this->assertNoRaw('https://cdnjs.cloudflare.com/ajax/libs/chosen');
-    $this->assertNoRaw('https://cdnjs.cloudflare.com/ajax/libs/select2');
-    $this->assertRaw('/modules/contrib/chosen/css/chosen-drupal.css');
-    // @todo Fix once Drupal 8.9.x is only supported.
-    if (floatval(\Drupal::VERSION) <= 8.8) {
-      $this->assertRaw('/libraries/select2/dist/css/select2.min.css');
+    if (floatval(\Drupal::VERSION) >= 9) {
+      // Issue #3110478: [Webform 8.x-6.x] Track the D9 readiness state of the
+      // Webform module's (optional) dependencies
+      // @see https://www.drupal.org/project/webform/issues/3110478
+      // Check that choices, chosen, and select2 using webform's CDN URLs.
+      $edit = [
+        'excluded_libraries[jquery.select2]' => TRUE,
+      ];
+      $this->drupalPostForm('/admin/structure/webform/config/libraries', $edit, 'Save configuration');
+      $this->drupalGet('/webform/test_libraries_optional');
+      $this->assertRaw('https://cdnjs.cloudflare.com/ajax/libs/select2');
+
+      // Install chosen and select2 modules.
+      \Drupal::service('module_installer')->install(['select2']);
+      drupal_flush_all_caches();
+
+      // Check that chosen and select2 using module's path and not CDN.
+      $this->drupalGet('/webform/test_libraries_optional');
+      $this->assertNoRaw('https://cdnjs.cloudflare.com/ajax/libs/select2');
+    }
+    else {
+      // Check that choices, chosen, and select2 using webform's CDN URLs.
+      $edit = [
+        'excluded_libraries[jquery.select2]' => TRUE,
+        'excluded_libraries[jquery.chosen]' => TRUE,
+      ];
+      $this->drupalPostForm('/admin/structure/webform/config/libraries', $edit, 'Save configuration');
+      $this->drupalGet('/webform/test_libraries_optional');
+      $this->assertRaw('https://cdnjs.cloudflare.com/ajax/libs/chosen');
+      $this->assertRaw('https://cdnjs.cloudflare.com/ajax/libs/select2');
+
+      // Install chosen and select2 modules.
+      \Drupal::service('module_installer')->install(['chosen', 'chosen_lib', 'select2']);
+      drupal_flush_all_caches();
+
+      // Check that chosen and select2 using module's path and not CDN.
+      $this->drupalGet('/webform/test_libraries_optional');
+      $this->assertNoRaw('https://cdnjs.cloudflare.com/ajax/libs/chosen');
+      $this->assertNoRaw('https://cdnjs.cloudflare.com/ajax/libs/select2');
+      $this->assertRaw('/modules/contrib/chosen/css/chosen-drupal.css');
     }
   }
 
diff --git a/web/modules/webform/tests/src/Functional/WebformListBuilderTest.php b/web/modules/webform/tests/src/Functional/WebformListBuilderTest.php
index 106a567f19..4b62f5283f 100644
--- a/web/modules/webform/tests/src/Functional/WebformListBuilderTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformListBuilderTest.php
@@ -2,14 +2,12 @@
 
 namespace Drupal\Tests\webform\Functional;
 
-use Drupal\Tests\BrowserTestBase;
-
 /**
  * Tests for webform list builder.
  *
- * @group Webform
+ * @group webform
  */
-class WebformListBuilderTest extends BrowserTestBase {
+class WebformListBuilderTest extends WebformBrowserTestBase {
 
   /**
    * Modules to enable.
diff --git a/web/modules/webform/tests/src/Functional/WebformMailTest.php b/web/modules/webform/tests/src/Functional/WebformMailTest.php
index 0ef07f9f03..0a9f116860 100644
--- a/web/modules/webform/tests/src/Functional/WebformMailTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformMailTest.php
@@ -2,14 +2,12 @@
 
 namespace Drupal\Tests\webform\Functional;
 
-use Drupal\Tests\BrowserTestBase;
-
 /**
  * Performs tests on the pluggable mailing framework.
  *
  * @group webform_browser
  */
-class WebformMailTest extends BrowserTestBase {
+class WebformMailTest extends WebformBrowserTestBase {
 
   /**
    * Modules to enable.
diff --git a/web/modules/webform/tests/src/Functional/WebformOptionsTest.php b/web/modules/webform/tests/src/Functional/WebformOptionsTest.php
index ce5e3350d2..5f6b5f937e 100644
--- a/web/modules/webform/tests/src/Functional/WebformOptionsTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformOptionsTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform option entity.
  *
- * @group Webform
+ * @group webform
  */
 class WebformOptionsTest extends WebformBrowserTestBase {
 
@@ -80,7 +80,7 @@ public function testWebformOptions() {
     $webform_options->set('options', "not\nvalid\nyaml")->save();
 
     // Check invalid options.
-    $this->assertFalse($webform_options->getOptions());
+    $this->assertEqual($webform_options->getOptions(), []);
 
     // Check hook_webform_options_alter() && hook_webform_options_WEBFORM_OPTIONS_ID_alter().
     // Check that the default value can be set from the alter hook.
diff --git a/web/modules/webform/tests/src/Functional/WebformRenderingTest.php b/web/modules/webform/tests/src/Functional/WebformRenderingTest.php
index 935d5f78ff..81f324445b 100644
--- a/web/modules/webform/tests/src/Functional/WebformRenderingTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformRenderingTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform token submission value.
  *
- * @group Webform
+ * @group webform
  */
 class WebformRenderingTest extends WebformBrowserTestBase {
 
@@ -31,7 +31,7 @@ class WebformRenderingTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create filters.
@@ -50,7 +50,7 @@ public function testRendering() {
     // Preview.
     /**************************************************************************/
 
-    $this->drupalPostForm('/webform/test_rendering', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_rendering', [], 'Preview');
 
     // Check preview submission_label.
     $this->assertRaw('submission &lt;em&gt;label&lt;/em&gt; (&amp;&gt;&lt;#)');
@@ -84,21 +84,21 @@ public function testRendering() {
     // Check HTML email.
     $this->assertEqual($html_email['subject'], 'submission label (&>');
     $this->assertEqual($html_email['params']['subject'], 'submission <em>label</em> (&><#)');
-    $this->assertContains('<b>submission_label</b><br />submission &lt;em&gt;label&lt;/em&gt; (&amp;&gt;&lt;#)<br /><br />', $html_email['params']['body']);
-    $this->assertContains('<b>textfield_plain_text</b><br />{prefix}{default_value}{suffix}<br /><br />', $html_email['params']['body']);
-    $this->assertContains('<b><em>textfield_markup</em></b><br /><em>{prefix}</em>{default_value}<em>{suffix}</em><br /><br />', $html_email['params']['body']);
-    $this->assertContains('<b>textfield_special_characters (&amp;&gt;&lt;#)</b><br />(&amp;&gt;&lt;#){default_value}(&amp;&gt;&lt;#)<br /><br />', $html_email['params']['body']);
-    $this->assertContains('<b>text_format_basic_html</b><br /><p><em>{default_value}</em></p><br /><br />', $html_email['params']['body']);
+    $this->assertStringContainsString('<b>submission_label</b><br />submission &lt;em&gt;label&lt;/em&gt; (&amp;&gt;&lt;#)<br /><br />', $html_email['params']['body']);
+    $this->assertStringContainsString('<b>textfield_plain_text</b><br />{prefix}{default_value}{suffix}<br /><br />', $html_email['params']['body']);
+    $this->assertStringContainsString('<b><em>textfield_markup</em></b><br /><em>{prefix}</em>{default_value}<em>{suffix}</em><br /><br />', $html_email['params']['body']);
+    $this->assertStringContainsString('<b>textfield_special_characters (&amp;&gt;&lt;#)</b><br />(&amp;&gt;&lt;#){default_value}(&amp;&gt;&lt;#)<br /><br />', $html_email['params']['body']);
+    $this->assertStringContainsString('<b>text_format_basic_html</b><br /><p><em>{default_value}</em></p><br /><br />', $html_email['params']['body']);
 
     // Check plain text email.
     $this->assertEqual($text_email['subject'], 'submission label (&>');
     $this->assertEqual($text_email['params']['subject'], 'submission <em>label</em> (&><#)');
-    $this->assertContains('submission_label: submission <em>label</em> (&><#)', $text_email['params']['body']);
-    $this->assertContains('textfield_plain_text: {prefix}{default_value}{suffix}', $text_email['params']['body']);
-    $this->assertContains('textfield_markup: {prefix}{default_value}{suffix}', $text_email['params']['body']);
-    $this->assertContains('textfield_special_characters (&>: (&>{default_value}(&>', $text_email['params']['body']);
-    $this->assertContains('text_format_basic_html:', $text_email['params']['body']);
-    $this->assertContains('/{default_value}/', $text_email['params']['body']);
+    $this->assertStringContainsString('submission_label: submission <em>label</em> (&><#)', $text_email['params']['body']);
+    $this->assertStringContainsString('textfield_plain_text: {prefix}{default_value}{suffix}', $text_email['params']['body']);
+    $this->assertStringContainsString('textfield_markup: {prefix}{default_value}{suffix}', $text_email['params']['body']);
+    $this->assertStringContainsString('textfield_special_characters (&>: (&>{default_value}(&>', $text_email['params']['body']);
+    $this->assertStringContainsString('text_format_basic_html:', $text_email['params']['body']);
+    $this->assertStringContainsString('/{default_value}/', $text_email['params']['body']);
 
     /**************************************************************************/
     // Submission.
diff --git a/web/modules/webform/tests/src/Functional/WebformResultsDisabledTest.php b/web/modules/webform/tests/src/Functional/WebformResultsDisabledTest.php
index 26b5878757..9cac7786ff 100644
--- a/web/modules/webform/tests/src/Functional/WebformResultsDisabledTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformResultsDisabledTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform results disabled.
  *
- * @group Webform
+ * @group webform
  */
 class WebformResultsDisabledTest extends WebformBrowserTestBase {
 
@@ -28,7 +28,7 @@ public function testSettings() {
     // Check results disabled.
     $webform_results_disabled = Webform::load('test_form_results_disabled');
     $webform_submission = $this->postSubmission($webform_results_disabled);
-    $this->assertFalse($webform_submission, 'Submission not saved to the database.');
+    $this->assertNull($webform_submission, 'Submission not saved to the database.');
 
     // Check that error message is displayed and form is available for admins.
     $this->drupalGet('/webform/test_form_results_disabled');
diff --git a/web/modules/webform/tests/src/Functional/WebformResultsExportDownloadTest.php b/web/modules/webform/tests/src/Functional/WebformResultsExportDownloadTest.php
index dc5d07e5bb..dd51e486f9 100644
--- a/web/modules/webform/tests/src/Functional/WebformResultsExportDownloadTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformResultsExportDownloadTest.php
@@ -9,7 +9,7 @@
 /**
  * Tests for webform results export download.
  *
- * @group Webform
+ * @group webform
  */
 class WebformResultsExportDownloadTest extends WebformBrowserTestBase {
 
@@ -58,13 +58,13 @@ public function testDownloadFiles() {
         'files' => TRUE,
         'archive_type' => $archive_type,
       ];
-      $this->drupalPostForm('/admin/structure/webform/manage/test_element_managed_file/results/download', $edit, t('Download'));
+      $this->drupalPostForm('/admin/structure/webform/manage/test_element_managed_file/results/download', $edit, 'Download');
 
       // Load the archive and get a list of files.
       $files = $this->getArchiveContents($submission_exporter->getArchiveFilePath());
 
       // Check that CSV file exists.
-      $this->assert(isset($files['test_element_managed_file/test_element_managed_file.csv']));
+      $this->assertArrayHasKey('test_element_managed_file/test_element_managed_file.csv', $files);
 
       // Check submission file directories.
       /** @var \Drupal\webform\WebformSubmissionInterface[] $submissions */
@@ -74,7 +74,7 @@ public function testDownloadFiles() {
         $fid = $submission->getElementData('managed_file_single');
         $filename = File::load($fid)->getFilename();
 
-        $this->assert(isset($files["submission-$serial/$filename"]));
+        $this->assertArrayHasKey("submission-$serial/$filename", $files);
       }
 
       /* Download YAML */
@@ -85,13 +85,13 @@ public function testDownloadFiles() {
         'exporter' => 'yaml',
         'archive_type' => $archive_type,
       ];
-      $this->drupalPostForm('/admin/structure/webform/manage/test_element_managed_file/results/download', $edit, t('Download'));
+      $this->drupalPostForm('/admin/structure/webform/manage/test_element_managed_file/results/download', $edit, 'Download');
 
       // Load the archive and get a list of files.
       $files = $this->getArchiveContents($submission_exporter->getArchiveFilePath());
 
       // Check that CSV file does not exists.
-      $this->assert(!isset($files['test_element_managed_file/test_element_managed_file.csv']));
+      $this->assertArrayNotHasKey('test_element_managed_file/test_element_managed_file.csv', $files);
 
       // Check submission file directories.
       /** @var \Drupal\webform\WebformSubmissionInterface[] $submissions */
@@ -101,8 +101,8 @@ public function testDownloadFiles() {
         $fid = $submission->getElementData('managed_file_single');
         $filename = File::load($fid)->getFilename();
 
-        $this->assert(isset($files["submission-$serial.yml"]));
-        $this->assert(isset($files["submission-$serial/$filename"]));
+        $this->assertArrayHasKey("submission-$serial.yml", $files);
+        $this->assertArrayHasKey("submission-$serial/$filename", $files);
       }
     }
   }
diff --git a/web/modules/webform/tests/src/Functional/WebformResultsExportOptionsTest.php b/web/modules/webform/tests/src/Functional/WebformResultsExportOptionsTest.php
index f1a5ac839e..c6a970c24c 100644
--- a/web/modules/webform/tests/src/Functional/WebformResultsExportOptionsTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformResultsExportOptionsTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform results export.
  *
- * @group Webform
+ * @group webform
  */
 class WebformResultsExportOptionsTest extends WebformBrowserTestBase {
 
@@ -195,7 +195,7 @@ public function testExportOptions() {
     $edit = [
       'exporter' => 'table',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', $edit, t('Download'));
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', $edit, 'Download');
     $this->assertRaw('<body><table border="1"><thead><tr bgcolor="#cccccc" valign="top"><th>Serial number</th>');
     $this->assertPattern('#<td>George</td>\s+<td>Washington</td>\s+<td>Male</td>#ms');
 
@@ -204,8 +204,8 @@ public function testExportOptions() {
       'exporter' => 'delimited',
       'exporters[delimited][delimiter]' => '|',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config/exporters', $edit, t('Save configuration'));
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', [], t('Download'));
+    $this->drupalPostForm('/admin/structure/webform/config/exporters', $edit, 'Save configuration');
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', [], 'Download');
     $this->assertRaw('"Submission ID"|"Submission URI"');
 
     // Check saved webform export (delimiter) settings.
@@ -213,13 +213,13 @@ public function testExportOptions() {
       'exporter' => 'delimited',
       'exporters[delimited][delimiter]' => '.',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', $edit, t('Save settings'));
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', [], t('Download'));
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', $edit, 'Save settings');
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', [], 'Download');
     $this->assertRaw('"Submission ID"."Submission URI"');
 
     // Check delete webform export (delimiter) settings.
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', [], t('Reset settings'));
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', [], t('Download'));
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', [], 'Reset settings');
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/download', [], 'Download');
     $this->assertRaw('"Submission ID"|"Submission URI"');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/WebformSubmissionApiTest.php b/web/modules/webform/tests/src/Functional/WebformSubmissionApiTest.php
index c53f612feb..e9b755a3e8 100644
--- a/web/modules/webform/tests/src/Functional/WebformSubmissionApiTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformSubmissionApiTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform submission API.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSubmissionApiTest extends WebformBrowserTestBase {
 
@@ -87,7 +87,7 @@ public function testApi() {
       'data' => [],
     ];
     $webform_submission = WebformSubmissionForm::submitFormValues($values);
-    $this->assert($webform_submission instanceof WebformSubmissionInterface);
+    $this->assertInstanceOf(WebformSubmissionInterface::class, $webform_submission);
 
     /**************************************************************************/
     // Multistep form.
diff --git a/web/modules/webform/tests/src/Functional/WebformSubmissionGenerateTest.php b/web/modules/webform/tests/src/Functional/WebformSubmissionGenerateTest.php
index a6661fffab..3001c46c9e 100644
--- a/web/modules/webform/tests/src/Functional/WebformSubmissionGenerateTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformSubmissionGenerateTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform submission generator.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSubmissionGenerateTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/WebformSubmissionListBuilderCustomizeTest.php b/web/modules/webform/tests/src/Functional/WebformSubmissionListBuilderCustomizeTest.php
index 45ed8196c8..2855fe52ae 100644
--- a/web/modules/webform/tests/src/Functional/WebformSubmissionListBuilderCustomizeTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformSubmissionListBuilderCustomizeTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform submission list builder.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSubmissionListBuilderCustomizeTest extends WebformBrowserTestBase {
 
@@ -115,7 +115,7 @@ public function testCustomize() {
       'limit' => 20,
       'link_type' => 'table',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom', $edit, 'Save');
     $this->assertRaw('The customized table has been saved.');
 
     // Check webform state.
@@ -232,7 +232,7 @@ public function testCustomize() {
     $this->drupalLogin($admin_user);
 
     // Clear customized default able.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom', $edit, t('Reset'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom', $edit, 'Reset');
     $this->assertRaw('The customized table has been reset.');
 
     // Check that 'Customize' button and link are visible.
@@ -277,7 +277,7 @@ public function testCustomize() {
       'columns[element__first_name][weight]' => '8',
       'columns[element__last_name][weight]' => '7',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom/user', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom/user', $edit, 'Save');
     $this->assertRaw('Your customized table has been saved.');
 
     // Check that first name is now after last name.
@@ -291,7 +291,7 @@ public function testCustomize() {
       'columns[element__first_name][checkbox]' => FALSE,
       'columns[element__last_name][checkbox]' => FALSE,
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom', $edit, 'Save');
     $this->assertRaw('The default customized table has been saved.');
     // Check that first name and last name are not visible.
     $this->assertNoRaw('First name');
@@ -317,7 +317,7 @@ public function testCustomize() {
     $this->assertPattern('#Last name.+First name#ms');
 
     // Reset user customized table.
-    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom/user', $edit, t('Reset'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom/user', $edit, 'Reset');
     $this->assertRaw('Your customized table has been reset.');
 
     // Check that first name and last name are now not visible.
@@ -361,12 +361,12 @@ public function testCustomize() {
       'columns[element__first_name][weight]' => '8',
       'columns[element__last_name][weight]' => '7',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom', $edit, 'Save');
     $edit = [
       'columns[element__first_name][weight]' => '8',
       'columns[element__last_name][weight]' => '7',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom/user', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/test_submissions/results/submissions/custom/user', $edit, 'Save');
 
     // Check that state and user data exists.
     $this->assertNotEmpty(\Drupal::state()->get('webform.webform.test_submissions'));
diff --git a/web/modules/webform/tests/src/Functional/WebformSubmissionListBuilderTest.php b/web/modules/webform/tests/src/Functional/WebformSubmissionListBuilderTest.php
index 7c41b898c4..e53f2734e9 100644
--- a/web/modules/webform/tests/src/Functional/WebformSubmissionListBuilderTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformSubmissionListBuilderTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform submission list builder.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSubmissionListBuilderTest extends WebformBrowserTestBase {
 
@@ -77,14 +77,14 @@ public function testResults() {
     $this->assertNoFieldById('edit-reset', 'reset');
 
     // Check results filtered by uuid.
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/submissions', ['search' => $submissions[0]->get('uuid')->value], t('Filter'));
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/submissions', ['search' => $submissions[0]->get('uuid')->value], 'Filter');
     $this->assertUrl('admin/structure/webform/manage/' . $webform->id() . '/results/submissions?search=' . $submissions[0]->get('uuid')->value);
     $this->assertRaw($submissions[0]->getElementData('first_name'));
     $this->assertNoRaw($submissions[1]->getElementData('first_name'));
     $this->assertNoRaw($submissions[2]->getElementData('first_name'));
 
     // Check results filtered by key(word).
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/submissions', ['search' => $submissions[0]->getElementData('first_name')], t('Filter'));
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/submissions', ['search' => $submissions[0]->getElementData('first_name')], 'Filter');
     $this->assertUrl('admin/structure/webform/manage/' . $webform->id() . '/results/submissions?search=' . $submissions[0]->getElementData('first_name'));
     $this->assertRaw($submissions[0]->getElementData('first_name'));
     $this->assertNoRaw($submissions[1]->getElementData('first_name'));
@@ -92,7 +92,7 @@ public function testResults() {
     $this->assertFieldById('edit-reset', 'Reset');
 
     // Check results filtered by state:starred.
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/submissions', ['state' => 'starred'], t('Filter'));
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/submissions', ['state' => 'starred'], 'Filter');
     $this->assertUrl('admin/structure/webform/manage/' . $webform->id() . '/results/submissions?state=starred');
     $this->assertRaw('<option value="starred" selected="selected">Starred [1]</option>');
     $this->assertNoRaw($submissions[0]->getElementData('first_name'));
@@ -101,7 +101,7 @@ public function testResults() {
     $this->assertFieldById('edit-reset', 'Reset');
 
     // Check results filtered by state:starred.
-    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/submissions', ['state' => 'locked'], t('Filter'));
+    $this->drupalPostForm('/admin/structure/webform/manage/' . $webform->id() . '/results/submissions', ['state' => 'locked'], 'Filter');
     $this->assertUrl('admin/structure/webform/manage/' . $webform->id() . '/results/submissions?state=locked');
     $this->assertRaw('<option value="locked" selected="selected">Locked [1]</option>');
     $this->assertNoRaw($submissions[0]->getElementData('first_name'));
diff --git a/web/modules/webform/tests/src/Functional/WebformSubmissionStorageTest.php b/web/modules/webform/tests/src/Functional/WebformSubmissionStorageTest.php
index d995e0abf8..388934edb5 100644
--- a/web/modules/webform/tests/src/Functional/WebformSubmissionStorageTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformSubmissionStorageTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform storage tests.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSubmissionStorageTest extends WebformBrowserTestBase {
 
@@ -82,9 +82,9 @@ public function testSubmissionStorage() {
 
     // Create drafts for user1 and user2.
     $this->drupalLogin($user1);
-    $this->postSubmission($webform, [], t('Save Draft'));
+    $this->postSubmission($webform, [], 'Save Draft');
     $this->drupalLogin($user2);
-    $this->postSubmission($webform, [], t('Save Draft'));
+    $this->postSubmission($webform, [], 'Save Draft');
 
     // Check totals remains the same with drafts.
     $this->assertEqual($storage->getTotal($webform), 6);
diff --git a/web/modules/webform/tests/src/Functional/WebformSubmissionTest.php b/web/modules/webform/tests/src/Functional/WebformSubmissionTest.php
index 33bc137510..baff32bb52 100644
--- a/web/modules/webform/tests/src/Functional/WebformSubmissionTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformSubmissionTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform submission entity.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSubmissionTest extends WebformBrowserTestBase {
 
@@ -44,7 +44,7 @@ public function testWebformSubmission() {
     /**************************************************************************/
 
     // Check create submission.
-    $this->assert($webform_submission instanceof WebformSubmission, '$webform_submission instanceof WebformSubmission');
+    $this->assertInstanceOf(WebformSubmission::class, $webform_submission);
 
     // Check get webform.
     $this->assertEqual($webform_submission->getWebform()->id(), $webform->id());
@@ -116,7 +116,7 @@ public function testDuplicate() {
     $this->assertRaw('Duplicate Contact: Submission #' . $webform_submission->serial());
 
     // Duplicate submission.
-    $this->drupalPostForm("admin/structure/webform/manage/contact/submission/$sid/duplicate", ['subject' => '{Duplicate Subject}'], t('Send message'));
+    $this->drupalPostForm("admin/structure/webform/manage/contact/submission/$sid/duplicate", ['subject' => '{Duplicate Subject}'], 'Send message');
     $duplicate_sid = $this->getLastSubmissionId($webform);
     /** @var \Drupal\webform\WebformSubmissionInterface $duplicate_submission */
     $duplicate_submission = WebformSubmission::load($duplicate_sid);
diff --git a/web/modules/webform/tests/src/Functional/WebformSubmissionTokenUpdateTest.php b/web/modules/webform/tests/src/Functional/WebformSubmissionTokenUpdateTest.php
index 9ae7cd5f22..d13c388465 100644
--- a/web/modules/webform/tests/src/Functional/WebformSubmissionTokenUpdateTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformSubmissionTokenUpdateTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for updating webform submission using tokenized URL.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSubmissionTokenUpdateTest extends WebformBrowserTestBase {
 
diff --git a/web/modules/webform/tests/src/Functional/WebformSubmissionViewTest.php b/web/modules/webform/tests/src/Functional/WebformSubmissionViewTest.php
index 57838d9cfe..47d829087d 100644
--- a/web/modules/webform/tests/src/Functional/WebformSubmissionViewTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformSubmissionViewTest.php
@@ -10,7 +10,7 @@
 /**
  * Tests for webform submission view as HTML, YAML, and plain text.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSubmissionViewTest extends WebformBrowserTestBase {
 
@@ -31,7 +31,7 @@ class WebformSubmissionViewTest extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Create filters.
diff --git a/web/modules/webform/tests/src/Functional/WebformSubmissionViewsAccessTest.php b/web/modules/webform/tests/src/Functional/WebformSubmissionViewsAccessTest.php
index 93cb61c754..eddb82b687 100644
--- a/web/modules/webform/tests/src/Functional/WebformSubmissionViewsAccessTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformSubmissionViewsAccessTest.php
@@ -2,7 +2,6 @@
 
 namespace Drupal\Tests\webform\Functional;
 
-use Drupal\Tests\BrowserTestBase;
 use Drupal\Tests\webform\Traits\WebformSubmissionViewAccessTrait;
 use Drupal\user\Entity\User;
 use Drupal\webform\Entity\Webform;
@@ -14,7 +13,7 @@
  *
  * @group webform_browser
  */
-class WebformSubmissionViewsAccessTest extends BrowserTestBase {
+class WebformSubmissionViewsAccessTest extends WebformBrowserTestBase {
 
   use WebformSubmissionViewAccessTrait;
 
diff --git a/web/modules/webform/tests/src/Functional/WebformSubmissionViewsTest.php b/web/modules/webform/tests/src/Functional/WebformSubmissionViewsTest.php
index 55ff126f66..f68f8f421b 100644
--- a/web/modules/webform/tests/src/Functional/WebformSubmissionViewsTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformSubmissionViewsTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform submission views integration.
  *
- * @group Webform
+ * @group webform
  */
 class WebformSubmissionViewsTest extends WebformBrowserTestBase {
 
@@ -137,8 +137,8 @@ public function testSubmissionViews() {
     $webform = Webform::load('test_submission_views');
     $this->postSubmission($webform);
     $this->postSubmission($webform);
-    $this->postSubmission($webform, [], t('Save Draft'));
-    $this->postSubmission($webform, [], t('Save Draft'));
+    $this->postSubmission($webform, [], 'Save Draft');
+    $this->postSubmission($webform, [], 'Save Draft');
 
     // Check webform submissions views.
     $this->drupalGet('/admin/structure/webform/manage/test_submission_views/results/submissions');
diff --git a/web/modules/webform/tests/src/Functional/WebformThirdPartySettingsTest.php b/web/modules/webform/tests/src/Functional/WebformThirdPartySettingsTest.php
index 3a6b0cb752..b11b71c33a 100644
--- a/web/modules/webform/tests/src/Functional/WebformThirdPartySettingsTest.php
+++ b/web/modules/webform/tests/src/Functional/WebformThirdPartySettingsTest.php
@@ -2,10 +2,12 @@
 
 namespace Drupal\Tests\webform\Functional;
 
+use Drupal\webform\Entity\Webform;
+
 /**
  * Tests for webform third party settings.
  *
- * @group Webform
+ * @group webform
  */
 class WebformThirdPartySettingsTest extends WebformBrowserTestBase {
 
@@ -20,8 +22,25 @@ class WebformThirdPartySettingsTest extends WebformBrowserTestBase {
    * Tests webform third party settings.
    */
   public function testThirdPartySettings() {
+    $webform = Webform::load('contact');
+
     $this->drupalLogin($this->rootUser);
 
+    /**************************************************************************/
+
+    // Check honeypot (custom) third party setting does not exist.
+    $this->assertNull($webform->getThirdPartySetting('honeypot', 'honeypot'));
+
+    // Add honeypot (custom) third party setting, even though the honeypot
+    // module is not installed.
+    $webform = $this->reloadWebform('contact');
+    $webform->setThirdPartySetting('honeypot', 'honeypot', TRUE);
+    $webform->save();
+
+    // Check honeypot (custom) third party setting.
+    $webform = $this->reloadWebform('contact');
+    $this->assertTrue($webform->getThirdPartySetting('honeypot', 'honeypot'));
+
     // Check 'Webform: Settings' shows no modules installed.
     $this->drupalGet('/admin/structure/webform/config');
     $this->assertRaw('There are no third party settings available.');
@@ -33,7 +52,7 @@ public function testThirdPartySettings() {
     // Install test third party settings module.
     $this->drupalPostForm('admin/modules', [
       'modules[webform_test_third_party_settings][enable]' => TRUE,
-    ], t('Install'));
+    ], 'Install');
 
     // Check 'Webform: Settings' shows no modules installed.
     $this->drupalGet('/admin/structure/webform/config');
@@ -47,7 +66,7 @@ public function testThirdPartySettings() {
     $edit = [
       'third_party_settings[webform_test_third_party_settings][message]' => 'Message for all webforms',
     ];
-    $this->drupalPostForm('/admin/structure/webform/config', $edit, t('Save configuration'));
+    $this->drupalPostForm('/admin/structure/webform/config', $edit, 'Save configuration');
     $this->drupalGet('/webform/contact');
     $this->assertRaw('Message for all webforms');
 
@@ -61,15 +80,19 @@ public function testThirdPartySettings() {
     $edit = [
       'third_party_settings[webform_test_third_party_settings][message]' => 'Message for only this webform',
     ];
-    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, t('Save'));
+    $this->drupalPostForm('/admin/structure/webform/manage/contact/settings', $edit, 'Save');
     $this->drupalGet('/webform/contact');
     $this->assertRaw('Message for only this webform');
 
+    // Check honeypot (custom) third party setting still exists.
+    $webform = $this->reloadWebform('contact');
+    $this->assertTrue($webform->getThirdPartySetting('honeypot', 'honeypot'));
+
     // Uninstall test third party settings module.
     $this->drupalPostForm('admin/modules/uninstall', [
       'uninstall[webform_test_third_party_settings]' => TRUE,
-    ], t('Uninstall'));
-    $this->drupalPostForm(NULL, [], t('Uninstall'));
+    ], 'Uninstall');
+    $this->drupalPostForm(NULL, [], 'Uninstall');
 
     // Check webform.
     $this->drupalGet('/webform/contact');
diff --git a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardAccessTest.php b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardAccessTest.php
index db7951decd..96bc5af9b8 100644
--- a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardAccessTest.php
+++ b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardAccessTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform wizard with access controls for pages.
  *
- * @group Webform
+ * @group webform
  */
 class WebformWizardAccessTest extends WebformWizardTestBase {
 
@@ -32,8 +32,8 @@ public function testConditionalWizard() {
     $this->assertNoRaw('<b>Private</b>');
 
     // Generate an anonymous submission.
-    $this->drupalPostForm('/webform/test_form_wizard_access', [], t('Next Page >'));
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm('/webform/test_form_wizard_access', [], 'Next >');
+    $this->drupalPostForm(NULL, [], 'Submit');
     $sid = $this->getLastSubmissionId($webform);
 
     // Check anonymous user can only view 'All' and 'Anonymous' submission data.
@@ -61,9 +61,9 @@ public function testConditionalWizard() {
     $this->assertRaw('<b>Private</b>');
 
     // Generate an authenticated submission.
-    $this->drupalPostForm('/webform/test_form_wizard_access', [], t('Next Page >'));
-    $this->drupalPostForm(NULL, [], t('Next Page >'));
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm('/webform/test_form_wizard_access', [], 'Next >');
+    $this->drupalPostForm(NULL, [], 'Next >');
+    $this->drupalPostForm(NULL, [], 'Submit');
     $sid = $this->getLastSubmissionId($webform);
 
     // Check authenticated user can view 'All', 'Authenticated', and 'Private' form pages.
diff --git a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardAdvancedTest.php b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardAdvancedTest.php
index 7343d35183..72b08bc888 100644
--- a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardAdvancedTest.php
+++ b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardAdvancedTest.php
@@ -4,11 +4,12 @@
 
 use Drupal\webform\Entity\Webform;
 use Drupal\Core\Serialization\Yaml;
+use Drupal\webform\WebformInterface;
 
 /**
  * Tests for webform advanced wizard.
  *
- * @group Webform
+ * @group webform
  */
 class WebformWizardAdvancedTest extends WebformWizardTestBase {
 
@@ -28,15 +29,15 @@ public function testAdvancedWizard() {
     // Get initial wizard start page (Your Information).
     $this->drupalGet('/webform/test_form_wizard_advanced');
     // Check progress bar is set to 'Your Information'.
-    $this->assertPattern('#<li data-webform-page="information" class="webform-progress-bar__page webform-progress-bar__page--current">\s+<b>Your Information</b><span></span></li>#');
+    $this->assertPattern('#<li data-webform-page="information" class="webform-progress-bar__page webform-progress-bar__page--current"><b>Your Information</b><span></span></li>#');
     // Check progress pages.
-    $this->assertRaw('Page 1 of 5');
+    $this->assertRaw('1 of 5');
     // Check progress percentage.
-    $this->assertRaw('(0%)');
+    $this->assertText('(0%)');
     // Check draft button does not exist.
     $this->assertNoFieldById('edit-draft', 'Save Draft');
     // Check next button does exist.
-    $this->assertFieldById('edit-wizard-next', 'Next Page >');
+    $this->assertFieldById('edit-wizard-next', 'Next >');
     // Check first name field does exist.
     $this->assertFieldById('edit-first-name', 'John');
 
@@ -48,21 +49,21 @@ public function testAdvancedWizard() {
     $edit = [
       'first_name' => 'Jane',
     ];
-    $this->drupalPostForm('/webform/test_form_wizard_advanced', $edit, t('Next Page >'));
+    $this->drupalPostForm('/webform/test_form_wizard_advanced', $edit, 'Next >');
     // Check progress bar is set to 'Contact Information'.
-    $this->assertPattern('#<li data-webform-page="information" class="webform-progress-bar__page webform-progress-bar__page--done">\s+<b>Your Information</b><span></span></li>#');
-    $this->assertPattern('#<li data-webform-page="contact" class="webform-progress-bar__page webform-progress-bar__page--current">\s+<b>Contact Information</b></li>#');
+    $this->assertPattern('#<li data-webform-page="information" class="webform-progress-bar__page webform-progress-bar__page--done"><b>Your Information</b><span></span></li>#');
+    $this->assertPattern('#<li data-webform-page="contact" class="webform-progress-bar__page webform-progress-bar__page--current"><b>Contact Information</b></li>#');
     // Check progress pages.
-    $this->assertRaw('Page 2 of 5');
+    $this->assertRaw('2 of 5');
     // Check progress percentage.
-    $this->assertRaw('(25%)');
+    $this->assertText('(25%)');
 
     // Check draft button does exist.
     $this->assertFieldById('edit-draft', 'Save Draft');
     // Check previous button does exist.
-    $this->assertFieldById('edit-wizard-prev', '< Previous Page');
+    $this->assertFieldById('edit-wizard-prev', '< Previous');
     // Check next button does exist.
-    $this->assertFieldById('edit-wizard-next', 'Next Page >');
+    $this->assertFieldById('edit-wizard-next', 'Next >');
     // Check email field does exist.
     $this->assertFieldById('edit-email', 'johnsmith@example.com');
 
@@ -71,17 +72,17 @@ public function testAdvancedWizard() {
     $edit = [
       'email' => 'janesmith@example.com',
     ];
-    $this->drupalPostForm(NULL, $edit, t('< Previous Page'));
+    $this->drupalPostForm(NULL, $edit, '< Previous');
     // Check progress bar is set to 'Your Information'.
-    $this->assertPattern('#<li data-webform-page="information" class="webform-progress-bar__page webform-progress-bar__page--current">\s+<b>Your Information</b><span></span></li>#');
+    $this->assertPattern('#<li data-webform-page="information" class="webform-progress-bar__page webform-progress-bar__page--current"><b>Your Information</b><span></span></li>#');
     // Check nosave class.
     $this->assertRaw('js-webform-unsaved');
     // Check no nosave attributes.
     $this->assertNoRaw('data-webform-unsaved');
     // Check progress pages.
-    $this->assertRaw('Page 1 of 5');
+    $this->assertRaw('1 of 5');
     // Check progress percentage.
-    $this->assertRaw('(0%)');
+    $this->assertText('(0%)');
 
     // Check first name set to Jane.
     $this->assertFieldById('edit-first-name', 'Jane');
@@ -92,14 +93,14 @@ public function testAdvancedWizard() {
     $edit = [
       'gender' => 'Female',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Save Draft'));
+    $this->drupalPostForm(NULL, $edit, 'Save Draft');
     // Check first name set to Jane.
     $this->assertFieldById('edit-first-name', 'Jane');
     // Check gender is now set to Female.
     $this->assertFieldChecked('edit-gender-female');
 
     // Move to next page (Contact Information).
-    $this->drupalPostForm('/webform/test_form_wizard_advanced', [], t('Next Page >'));
+    $this->drupalPostForm('/webform/test_form_wizard_advanced', [], 'Next >');
     // Check nosave class.
     $this->assertRaw('js-webform-unsaved');
     // Check nosave attributes.
@@ -107,9 +108,9 @@ public function testAdvancedWizard() {
     // Check progress bar is set to 'Contact Information'.
     $this->assertCurrentPage('Contact Information', 'contact');
     // Check progress pages.
-    $this->assertRaw('Page 2 of 5');
+    $this->assertRaw('2 of 5');
     // Check progress percentage.
-    $this->assertRaw('(25%)');
+    $this->assertText('(25%)');
 
     // Check email field is now janesmith@example.com.
     $this->assertFieldById('edit-email', 'janesmith@example.com');
@@ -118,18 +119,18 @@ public function testAdvancedWizard() {
     $edit = [
       'phone' => '111-111-1111',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Save Draft'));
+    $this->drupalPostForm(NULL, $edit, 'Save Draft');
     // Complete reload the webform.
     $this->drupalGet('/webform/test_form_wizard_advanced');
     // Check progress bar is still set to 'Contact Information'.
     $this->assertCurrentPage('Contact Information', 'contact');
 
     // Move to last page (Your Feedback).
-    $this->drupalPostForm(NULL, [], t('Next Page >'));
+    $this->drupalPostForm(NULL, [], 'Next >');
     // Check progress bar is set to 'Your Feedback'.
     $this->assertCurrentPage('Your Feedback', 'feedback');
     // Check previous button does exist.
-    $this->assertFieldById('edit-wizard-prev', '< Previous Page');
+    $this->assertFieldById('edit-wizard-prev', '< Previous');
     // Check next button is labeled 'Preview'.
     $this->assertFieldById('edit-preview-next', 'Preview');
     // Check submit button does exist.
@@ -139,13 +140,13 @@ public function testAdvancedWizard() {
     $edit = [
       'comments' => 'This is working fine.',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Preview'));
+    $this->drupalPostForm(NULL, $edit, 'Preview');
     // Check progress bar is set to 'Preview'.
-    $this->assertCurrentPage('Preview', 'webform_preview');
+    $this->assertCurrentPage('Preview', WebformInterface::PAGE_PREVIEW);
     // Check progress pages.
-    $this->assertRaw('Page 4 of 5');
+    $this->assertRaw('4 of 5');
     // Check progress percentage.
-    $this->assertRaw('(75%)');
+    $this->assertText('(75%)');
 
     // Check preview values.
     $this->assertRaw('<label>First Name</label>');
@@ -162,13 +163,13 @@ public function testAdvancedWizard() {
     $this->assertRaw('This is working fine.');
 
     // Submit the webform.
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm(NULL, [], 'Submit');
     // Check progress bar is set to 'Complete'.
-    $this->assertCurrentPage('Complete', 'webform_confirmation');
+    $this->assertCurrentPage('Complete', WebformInterface::PAGE_CONFIRMATION);
     // Check progress pages.
-    $this->assertRaw('Page 5 of 5');
+    $this->assertRaw('5 of 5');
     // Check progress percentage.
-    $this->assertRaw('(100%)');
+    $this->assertText('(100%)');
 
     /* Custom wizard settings (using advanced wizard) */
 
@@ -179,7 +180,7 @@ public function testAdvancedWizard() {
       ->set('settings.default_wizard_next_button_label', '{global wizard next}')
       ->set('settings.default_wizard_prev_button_label', '{global wizard previous}')
       ->save();
-    $this->drupalPostForm('/webform/test_form_wizard_advanced', [], t('{global wizard next}'));
+    $this->drupalPostForm('/webform/test_form_wizard_advanced', [], '{global wizard next}');
 
     // Check progress bar.
     $this->assertRaw('class="webform-progress-bar"');
@@ -199,7 +200,7 @@ public function testAdvancedWizard() {
     $webform->save();
 
     // Check webform next and previous button labels.
-    $this->drupalPostForm('/webform/test_form_wizard_advanced', [], t('{webform wizard next}'));
+    $this->drupalPostForm('/webform/test_form_wizard_advanced', [], '{webform wizard next}');
     // Check previous button.
     $this->assertFieldById('edit-actions-wizard-prev', '{webform wizard previous}');
     // Check next button.
@@ -211,7 +212,7 @@ public function testAdvancedWizard() {
     $elements['contact']['#prev_button_label'] = '{elements wizard previous}';
     $webform->set('elements', Yaml::encode($elements));
     $webform->save();
-    $this->drupalPostForm('/webform/test_form_wizard_advanced', [], t('{webform wizard next}'));
+    $this->drupalPostForm('/webform/test_form_wizard_advanced', [], '{webform wizard next}');
 
     // Check previous button.
     $this->assertFieldById('edit-actions-wizard-prev', '{elements wizard previous}');
@@ -230,9 +231,9 @@ public function testAdvancedWizard() {
     // Check no progress bar.
     $this->assertNoRaw('class="webform-progress-bar"');
     // Check progress pages.
-    $this->assertRaw('Page 1 of 5');
+    $this->assertRaw('1 of 5');
     // Check progress percentage.
-    $this->assertRaw('(0%)');
+    $this->assertText('(0%)');
 
     // Check global complete labels.
     $webform->setSettings([
diff --git a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardBasicTest.php b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardBasicTest.php
index 4997a8f7a6..9683db370a 100644
--- a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardBasicTest.php
+++ b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardBasicTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform basic wizard.
  *
- * @group Webform
+ * @group webform
  */
 class WebformWizardBasicTest extends WebformWizardTestBase {
 
@@ -26,16 +26,16 @@ public function testBasicWizard() {
 
     // Create a wizard submission.
     $wizard_webform = Webform::load('test_form_wizard_basic');
-    $this->drupalPostForm('/webform/test_form_wizard_basic', [], t('Next Page >'));
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm('/webform/test_form_wizard_basic', [], 'Next >');
+    $this->drupalPostForm(NULL, [], 'Submit');
     $sid = $this->getLastSubmissionId($wizard_webform);
 
     // Check confirmation message for wizard form.
     $this->drupalGet("admin/structure/webform/manage/test_form_wizard_basic/submission/$sid/edit");
     $this->assertCurrentPage('Page 1', 'page_1');
-    $this->drupalPostForm(NULL, [], t('Next Page >'));
+    $this->drupalPostForm(NULL, [], 'Next >');
     $this->assertCurrentPage('Page 2', 'page_2');
-    $this->drupalPostForm(NULL, [], t('Save'));
+    $this->drupalPostForm(NULL, [], 'Save');
     $this->assertRaw('Submission updated in <em class="placeholder">Test: Webform: Wizard basic</em>.');
     $this->assertCurrentPage('Page 1', 'page_1');
 
@@ -67,17 +67,17 @@ public function testBasicWizard() {
     $this->assertRaw('data-webform-wizard-page="page_2" data-drupal-selector="edit-wizard-next"');
 
     // Check next and previous page.
-    $this->drupalPostForm('/webform/test_form_wizard_basic', [], t('Next Page >'));
+    $this->drupalPostForm('/webform/test_form_wizard_basic', [], 'Next >');
     $this->assertRaw('data-webform-wizard-current-page="page_2"');
     $this->assertRaw('data-webform-wizard-page="page_1" data-drupal-selector="edit-wizard-prev"');
     $this->assertRaw('data-webform-wizard-page="webform_preview" data-drupal-selector="edit-preview-next"');
 
-    $this->drupalPostForm(NULL, [], t('Preview'));
+    $this->drupalPostForm(NULL, [], 'Preview');
     $this->assertRaw('data-webform-wizard-current-page="webform_preview"');
     $this->assertRaw('data-webform-wizard-page="page_2" data-drupal-selector="edit-preview-prev"');
     $this->assertRaw('data-webform-wizard-page="webform_confirmation" data-drupal-selector="edit-submit"');
 
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm(NULL, [], 'Submit');
     $this->assertRaw('data-webform-wizard-current-page="webform_confirmation"');
 
     // Enable tracking by index.
@@ -88,17 +88,17 @@ public function testBasicWizard() {
     $this->assertRaw('data-webform-wizard-page="2" data-drupal-selector="edit-wizard-next"');
 
     // Check next and previous page.
-    $this->drupalPostForm('/webform/test_form_wizard_basic', [], t('Next Page >'));
+    $this->drupalPostForm('/webform/test_form_wizard_basic', [], 'Next >');
     $this->assertRaw('data-webform-wizard-current-page="2"');
     $this->assertRaw('data-webform-wizard-page="1" data-drupal-selector="edit-wizard-prev"');
     $this->assertRaw('data-webform-wizard-page="3" data-drupal-selector="edit-preview-next"');
 
-    $this->drupalPostForm(NULL, [], t('Preview'));
+    $this->drupalPostForm(NULL, [], 'Preview');
     $this->assertRaw('data-webform-wizard-current-page="3"');
     $this->assertRaw('data-webform-wizard-page="2" data-drupal-selector="edit-preview-prev"');
     $this->assertRaw('data-webform-wizard-page="4" data-drupal-selector="edit-submit"');
 
-    $this->drupalPostForm(NULL, [], t('Submit'));
+    $this->drupalPostForm(NULL, [], 'Submit');
     $this->assertRaw('data-webform-wizard-current-page="4"');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardConditionalTest.php b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardConditionalTest.php
index 842159fc03..93bf19ee67 100644
--- a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardConditionalTest.php
+++ b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardConditionalTest.php
@@ -3,11 +3,12 @@
 namespace Drupal\Tests\webform\Functional\Wizard;
 
 use Drupal\webform\Entity\Webform;
+use Drupal\webform\WebformInterface;
 
 /**
  * Tests for webform conditional wizard.
  *
- * @group Webform
+ * @group webform
  */
 class WebformWizardConditionalTest extends WebformWizardTestBase {
 
@@ -31,25 +32,25 @@ public function testConditionalWizard() {
       'trigger_pages[page_3]' => FALSE,
       'trigger_pages[page_5]' => FALSE,
     ];
-    $this->drupalPostForm('/webform/test_form_wizard_conditional', $edit, 'Next Page >');
+    $this->drupalPostForm('/webform/test_form_wizard_conditional', $edit, 'Next >');
     $this->assertCurrentPage('Page 2', 'page_2');
-    $this->drupalPostForm(NULL, [], t('Next Page >'));
+    $this->drupalPostForm(NULL, [], 'Next >');
     $this->assertCurrentPage('Page 4', 'page_4');
-    $this->drupalPostForm(NULL, [], t('Submit'));
-    $this->assertCurrentPage('Complete', 'webform_confirmation');
+    $this->drupalPostForm(NULL, [], 'Submit');
+    $this->assertCurrentPage('Complete', WebformInterface::PAGE_CONFIRMATION);
     $sid = $this->getLastSubmissionId($webform);
-    $this->assert(!empty($sid));
+    $this->assertNotEmpty($sid);
 
     // Check hiding all pages and skipping to complete.
     $edit = [
       'trigger_none' => TRUE,
     ];
-    $this->drupalPostForm('/webform/test_form_wizard_conditional', $edit, 'Next Page >');
+    $this->drupalPostForm('/webform/test_form_wizard_conditional', $edit, 'Next >');
     $this->assertRaw('<div class="webform-progress">');
     $this->assertRaw('New submission added to Test: Webform: Wizard conditional.');
-    $this->assertCurrentPage('Complete', 'webform_confirmation');
+    $this->assertCurrentPage('Complete', WebformInterface::PAGE_CONFIRMATION);
     $sid = $this->getLastSubmissionId($webform);
-    $this->assert(!empty($sid));
+    $this->assertNotEmpty($sid);
 
     // Enable preview.
     $webform->setSetting('preview', 1);
@@ -59,8 +60,8 @@ public function testConditionalWizard() {
     $edit = [
       'trigger_none' => TRUE,
     ];
-    $this->drupalPostForm('/webform/test_form_wizard_conditional', $edit, 'Next Page >');
-    $this->assertCurrentPage('Preview', 'webform_preview');
+    $this->drupalPostForm('/webform/test_form_wizard_conditional', $edit, 'Next >');
+    $this->assertCurrentPage('Preview', WebformInterface::PAGE_PREVIEW);
 
     // Disable preview and include confirmation in progress page.
     $webform->setSettings(['preview' => 0, 'wizard_confirmation' => FALSE]);
@@ -72,7 +73,7 @@ public function testConditionalWizard() {
     $edit = [
       'trigger_none' => TRUE,
     ];
-    $this->drupalPostForm('/webform/test_form_wizard_conditional', $edit, 'Next Page >');
+    $this->drupalPostForm('/webform/test_form_wizard_conditional', $edit, 'Next >');
     $this->assertNoRaw('<div class="webform-progress">');
     $this->assertRaw('New submission added to Test: Webform: Wizard conditional.');
     $last_sid = $this->getLastSubmissionId($webform);
@@ -89,7 +90,7 @@ public function testConditionalWizard() {
       'trigger_pages[page_3]' => FALSE,
       'trigger_pages[page_5]' => FALSE,
     ];
-    $this->drupalPostForm('/webform/test_form_wizard_conditional', $edit, 'Next Page >');
+    $this->drupalPostForm('/webform/test_form_wizard_conditional', $edit, 'Next >');
 
     // Assert the progress bar no longer includes page 5.
     $this->assertNoPattern('|<li data-webform-page="5" class="webform-progress-bar__page">\s+<b>Page 5</b>|');
diff --git a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardCustomTest.php b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardCustomTest.php
index 1c2e73957c..0fe5d56b52 100644
--- a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardCustomTest.php
+++ b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardCustomTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform custom wizard.
  *
- * @group Webform
+ * @group webform
  */
 class WebformWizardCustomTest extends WebformWizardTestBase {
 
@@ -32,11 +32,11 @@ public function testCustomWizard() {
     $this->assertCurrentPage('Wizard page #1', 'wizard_1');
 
     // Check next page is #2.
-    $this->drupalPostForm('/webform/test_form_wizard_custom', [], 'Next Page >');
+    $this->drupalPostForm('/webform/test_form_wizard_custom', [], 'Next >');
     $this->assertCurrentPage('Wizard page #2', 'wizard_2');
 
     // Check previous page is #1.
-    $this->drupalPostForm(NULL, [], '< Previous Page');
+    $this->drupalPostForm(NULL, [], '< Previous');
     $this->assertCurrentPage('Wizard page #1', 'wizard_1');
 
     // Hide pages #3 and #4.
@@ -49,21 +49,21 @@ public function testCustomWizard() {
       'pages[wizard_6]' => TRUE,
       'pages[wizard_7]' => TRUE,
     ];
-    $this->drupalPostForm(NULL, $edit, 'Next Page >');
+    $this->drupalPostForm(NULL, $edit, 'Next >');
 
     // Check next page is #2.
     $this->assertCurrentPage('Wizard page #2', 'wizard_2');
 
     // Check next page is #5.
-    $this->drupalPostForm(NULL, [], 'Next Page >');
+    $this->drupalPostForm(NULL, [], 'Next >');
     $this->assertCurrentPage('Wizard page #5', 'wizard_5');
 
     // Check previous page is #2.
-    $this->drupalPostForm(NULL, [], '< Previous Page');
+    $this->drupalPostForm(NULL, [], '< Previous');
     $this->assertCurrentPage('Wizard page #2', 'wizard_2');
 
     // Check previous page is #1.
-    $this->drupalPostForm(NULL, [], '< Previous Page');
+    $this->drupalPostForm(NULL, [], '< Previous');
     $this->assertCurrentPage('Wizard page #1', 'wizard_1');
   }
 
diff --git a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardLinksTest.php b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardLinksTest.php
index 5e8a06b9db..3791af5958 100644
--- a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardLinksTest.php
+++ b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardLinksTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform wizard progress and preview links.
  *
- * @group Webform
+ * @group webform
  */
 class WebformWizardLinksTest extends WebformWizardTestBase {
 
@@ -29,20 +29,20 @@ public function testWizardLinks() {
     // Check that first page has no links.
     $this->drupalGet('/webform/test_form_wizard_links');
     $this->assertCssSelect('.webform-wizard-pages-links');
-    $this->assertNoFieldByName('webform_wizard_page-page_1', t('Edit'));
-    $this->assertNoFieldByName('webform_wizard_page-page_2', t('Edit'));
+    $this->assertNoFieldByName('webform_wizard_page-page_1', 'Edit');
+    $this->assertNoFieldByName('webform_wizard_page-page_2', 'Edit');
 
     // Check that second page links to first page.
-    $this->drupalPostForm('/webform/test_form_wizard_links', [], t('Next Page >'));
+    $this->drupalPostForm('/webform/test_form_wizard_links', [], 'Next >');
     $this->assertCssSelect('.webform-wizard-pages-links');
-    $this->assertFieldByName('webform_wizard_page-page_1', t('Edit'));
-    $this->assertNoFieldByName('webform_wizard_page-page_2', t('Edit'));
+    $this->assertFieldByName('webform_wizard_page-page_1', 'Edit');
+    $this->assertNoFieldByName('webform_wizard_page-page_2', 'Edit');
 
     // Check that preview links to first and second page.
-    $this->drupalPostForm('/webform/test_form_wizard_links', [], t('Preview'));
+    $this->drupalPostForm('/webform/test_form_wizard_links', [], 'Preview');
     $this->assertCssSelect('.webform-wizard-pages-links');
-    $this->assertFieldByName('webform_wizard_page-page_1', t('Edit'));
-    $this->assertFieldByName('webform_wizard_page-page_2', t('Edit'));
+    $this->assertFieldByName('webform_wizard_page-page_1', 'Edit');
+    $this->assertFieldByName('webform_wizard_page-page_2', 'Edit');
 
     // Check that preview links are not wrapper in .form-actions.
     $this->assertNoCssSelect('.webform-wizard-pages-links.form-actions');
diff --git a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardTestBase.php b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardTestBase.php
index 9640f53536..b56546101e 100644
--- a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardTestBase.php
+++ b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardTestBase.php
@@ -12,7 +12,7 @@ abstract class WebformWizardTestBase extends WebformBrowserTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     // Exclude Progress tracker so that the default progress bar is displayed.
@@ -31,7 +31,7 @@ public function setUp() {
    *   The name (key) of the current page.
    */
   protected function assertCurrentPage($title, $page) {
-    $this->assertPattern('|<li data-webform-page="' . $page . '" class="webform-progress-bar__page webform-progress-bar__page--current">\s+<b>' . $title . '</b>|');
+    $this->assertPattern('|<li data-webform-page="' . $page . '" class="webform-progress-bar__page webform-progress-bar__page--current"><b>' . $title . '</b>|');
   }
 
 }
diff --git a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardValidateTest.php b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardValidateTest.php
index 5d911790cf..8cc1e2daab 100644
--- a/web/modules/webform/tests/src/Functional/Wizard/WebformWizardValidateTest.php
+++ b/web/modules/webform/tests/src/Functional/Wizard/WebformWizardValidateTest.php
@@ -5,7 +5,7 @@
 /**
  * Tests for webform wizard validation.
  *
- * @group Webform
+ * @group webform
  */
 class WebformWizardValidateTest extends WebformWizardTestBase {
 
@@ -34,7 +34,7 @@ public function testWizardValidate() {
     /**************************************************************************/
 
     // Check validation errors.
-    $this->drupalPostForm('/webform/test_form_wizard_validate', [], t('Next Page >'));
+    $this->drupalPostForm('/webform/test_form_wizard_validate', [], 'Next >');
     $this->assertRaw('wizard_1_textfield field is required.');
     $this->assertRaw('wizard_1_select_other field is required.');
     $this->assertRaw('wizard_1_datelist field is required.');
@@ -49,7 +49,7 @@ public function testWizardValidate() {
       'wizard_1_datelist[items][0][_item_][hour]' => '1',
       'wizard_1_datelist[items][0][_item_][minute]' => '10',
     ];
-    $this->drupalPostForm('/webform/test_form_wizard_validate', $edit, t('Next Page >'));
+    $this->drupalPostForm('/webform/test_form_wizard_validate', $edit, 'Next >');
     $this->assertRaw("wizard_1_textfield: '{wizard_1_textfield}'
 wizard_1_select_other: one
 wizard_1_datelist:
@@ -68,7 +68,7 @@ public function testWizardValidate() {
       'wizard_2_datelist[items][0][_item_][hour]' => '2',
       'wizard_2_datelist[items][0][_item_][minute]' => '20',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Next Page >'));
+    $this->drupalPostForm(NULL, $edit, 'Next >');
     $this->assertRaw("wizard_1_textfield: '{wizard_1_textfield}'
 wizard_1_select_other: one
 wizard_1_datelist:
@@ -83,7 +83,7 @@ public function testWizardValidate() {
     /**************************************************************************/
 
     // Check validation errors.
-    $this->drupalPostForm('/webform/test_form_wizard_validate_comp', [], t('Next Page >'));
+    $this->drupalPostForm('/webform/test_form_wizard_validate_comp', [], 'Next >');
     // $this->assertRaw('The <em class="placeholder">datelist</em> date is required.');
     $this->assertRaw('textfield field is required.');
 
@@ -108,7 +108,7 @@ public function testWizardValidate() {
       'wizard_1_test_composite_multiple[items][0][_item_][datelist][hour]' => '1',
       'wizard_1_test_composite_multiple[items][0][_item_][datelist][minute]' => '10',
     ];
-    $this->drupalPostForm('/webform/test_form_wizard_validate_comp', $edit, t('Next Page >'));
+    $this->drupalPostForm('/webform/test_form_wizard_validate_comp', $edit, 'Next >');
     $this->assertRaw("wizard_1_custom_composite:
   - datelist: '2001-01-01T01:10:00+1100'
     textfield: '{wizard_1_custom_composite_textfield}'
@@ -167,7 +167,7 @@ public function testWizardValidate() {
       'wizard_2_test_composite_multiple[items][0][_item_][datelist][hour]' => '2',
       'wizard_2_test_composite_multiple[items][0][_item_][datelist][minute]' => '20',
     ];
-    $this->drupalPostForm(NULL, $edit, t('Next Page >'));
+    $this->drupalPostForm(NULL, $edit, 'Next >');
 
     $raw = "wizard_1_custom_composite:
   - datelist: '2001-01-01T01:10:00+1100'
@@ -239,13 +239,13 @@ public function testWizardValidate() {
 
     // Make sure navigating back and next through the
     // previous pages does not lose any data.
-    $this->drupalPostForm(NULL, [], t('< Previous Page'));
+    $this->drupalPostForm(NULL, [], '< Previous');
     $this->assertRaw($raw);
-    $this->drupalPostForm(NULL, [], t('< Previous Page'));
+    $this->drupalPostForm(NULL, [], '< Previous');
     $this->assertRaw($raw);
-    $this->drupalPostForm(NULL, [], t('Next Page >'));
+    $this->drupalPostForm(NULL, [], 'Next >');
     $this->assertRaw($raw);
-    $this->drupalPostForm(NULL, [], t('Next Page >'));
+    $this->drupalPostForm(NULL, [], 'Next >');
     $this->assertRaw($raw);
   }
 
diff --git a/web/modules/webform/tests/src/FunctionalJavascript/Element/WebformElementCheckboxesJavaScriptTest.php b/web/modules/webform/tests/src/FunctionalJavascript/Element/WebformElementCheckboxesJavaScriptTest.php
new file mode 100644
index 0000000000..7eba773e9e
--- /dev/null
+++ b/web/modules/webform/tests/src/FunctionalJavascript/Element/WebformElementCheckboxesJavaScriptTest.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace Drupal\Tests\webform\FunctionalJavascript\Element;
+
+use Drupal\Tests\webform\FunctionalJavascript\WebformWebDriverTestBase;
+
+/**
+ * Tests webform checkboxes element.
+ *
+ * @group webform_javascript
+ */
+class WebformElementCheckboxesJavaScriptTest extends WebformWebDriverTestBase {
+
+  /**
+   * Webforms to load.
+   *
+   * @var array
+   */
+  protected static $testWebforms = [
+    'test_element_checkboxes_all_none',
+  ];
+
+  /**
+   * Tests check all or none of the above.
+   */
+  public function testCheckboxesAllNone() {
+    $session = $this->getSession();
+    $assert_session = $this->assertSession();
+
+    /**************************************************************************/
+
+    $this->drupalGet('/webform/test_element_checkboxes_all_none');
+
+    // Check that check all is toggled on when all the checkboxes.
+    $assert_session->checkboxNotChecked('edit-checkboxes-all-all');
+    $this->click('#edit-checkboxes-all-one');
+    $this->click('#edit-checkboxes-all-two');
+    $this->click('#edit-checkboxes-all-three');
+    $assert_session->checkboxChecked('edit-checkboxes-all-all');
+
+    // Check that the 'all' checkbox is unchecked when any checkbox is unchecked.
+    $this->click('#edit-checkboxes-all-three');
+    $assert_session->checkboxNotChecked('edit-checkboxes-all-all');
+
+    // Check that all checkboxes are checked when checking 'all'.
+    $assert_session->checkboxNotChecked('edit-checkboxes-all-three');
+    $this->click('#edit-checkboxes-all-all');
+    $assert_session->checkboxChecked('edit-checkboxes-all-three');
+
+    // Check that checking 'none' disables all checkboxes.
+    $this->click('#edit-checkboxes-none-none');
+    $assert_session->fieldDisabled('edit-checkboxes-none-one');
+    $assert_session->checkboxNotChecked('edit-checkboxes-none-one');
+    $assert_session->fieldDisabled('edit-checkboxes-none-two');
+    $assert_session->checkboxNotChecked('edit-checkboxes-none-two');
+    $assert_session->fieldDisabled('edit-checkboxes-none-three');
+    $assert_session->checkboxNotChecked('edit-checkboxes-none-three');
+
+    // Check that unchecking 'none' enables all checkboxes.
+    $this->click('#edit-checkboxes-none-none');
+    $assert_session->fieldEnabled('edit-checkboxes-none-one');
+    $assert_session->fieldEnabled('edit-checkboxes-none-two');
+    $assert_session->fieldEnabled('edit-checkboxes-none-three');
+
+    // Check the 'all' and 'none' work together.
+    $this->click('#edit-checkboxes-both-none');
+    $assert_session->fieldDisabled('edit-checkboxes-both-one');
+    $assert_session->checkboxNotChecked('edit-checkboxes-both-one');
+    $assert_session->fieldDisabled('edit-checkboxes-both-two');
+    $assert_session->checkboxNotChecked('edit-checkboxes-both-two');
+    $assert_session->fieldDisabled('edit-checkboxes-both-three');
+    $assert_session->checkboxNotChecked('edit-checkboxes-both-three');
+    $assert_session->fieldDisabled('edit-checkboxes-both-all');
+    $assert_session->checkboxNotChecked('edit-checkboxes-both-all');
+
+    $this->click('#edit-checkboxes-both-none');
+    $this->click('#edit-checkboxes-both-all');
+    $assert_session->checkboxChecked('edit-checkboxes-both-one');
+    $assert_session->checkboxChecked('edit-checkboxes-both-two');
+    $assert_session->checkboxChecked('edit-checkboxes-both-three');
+    $assert_session->checkboxChecked('edit-checkboxes-both-all');
+  }
+
+}
diff --git a/web/modules/webform/tests/src/FunctionalJavascript/Settings/WebformSettingsAjaxJavaScriptTest.php b/web/modules/webform/tests/src/FunctionalJavascript/Settings/WebformSettingsAjaxJavaScriptTest.php
index da9eb293f8..f7cf0c6a97 100644
--- a/web/modules/webform/tests/src/FunctionalJavascript/Settings/WebformSettingsAjaxJavaScriptTest.php
+++ b/web/modules/webform/tests/src/FunctionalJavascript/Settings/WebformSettingsAjaxJavaScriptTest.php
@@ -6,7 +6,7 @@
 use Drupal\webform\Entity\Webform;
 
 /**
- * Tests webform JavasScript.
+ * Tests webform JavaScript.
  *
  * @group webform_javascript
  */
@@ -41,21 +41,21 @@ public function testAjax() {
     $webform_ajax = Webform::load('test_ajax');
 
     // Validate form.
-    $this->drupalPostForm($webform_ajax->toUrl(), ['textfield' => ''], t('Submit'));
+    $this->drupalPostForm($webform_ajax->toUrl(), ['textfield' => ''], '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'));
+    $this->drupalPostForm($webform_ajax->toUrl(), ['textfield' => 'test value'], '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'));
+    $this->drupalPostForm($webform_ajax->toUrl(), ['textfield' => 'test value'], 'Submit');
     $assert_session->waitForElement('css', '.messages--status');
 
     // Check submit message.
@@ -75,7 +75,7 @@ public function testAjax() {
     $webform_ajax_confirmation_inline = Webform::load('test_ajax_confirmation_inline');
 
     // Submit form.
-    $this->drupalPostForm($webform_ajax_confirmation_inline->toUrl(), [], t('Submit'));
+    $this->drupalPostForm($webform_ajax_confirmation_inline->toUrl(), [], 'Submit');
     $assert_session->waitForElement('css', '.messages--status');
     $assert_session->waitForText('This is a custom inline confirmation message.');
 
@@ -97,7 +97,7 @@ public function testAjax() {
     $webform_ajax_confirmation_message = Webform::load('test_ajax_confirmation_message');
 
     // Submit form.
-    $this->drupalPostForm($webform_ajax_confirmation_message->toUrl(), [], t('Submit'));
+    $this->drupalPostForm($webform_ajax_confirmation_message->toUrl(), [], 'Submit');
     $assert_session->waitForElement('css', '.messages--status');
 
     // Check confirmation message.
@@ -111,7 +111,7 @@ public function testAjax() {
     $webform_ajax_confirmation_modal = Webform::load('test_ajax_confirmation_modal');
 
     // Submit form.
-    $this->drupalPostForm($webform_ajax_confirmation_modal->toUrl(), [], t('Submit'));
+    $this->drupalPostForm($webform_ajax_confirmation_modal->toUrl(), [], 'Submit');
     $assert_session->waitForElementVisible('css', '.ui-dialog.webform-confirmation-modal');
 
     // Check confirmation modal.
@@ -124,7 +124,7 @@ public function testAjax() {
     $webform_ajax_confirmation_page = Webform::load('test_ajax_confirmation_page');
 
     // Submit form.
-    $this->drupalPostForm($webform_ajax_confirmation_page->toUrl(), [], t('Submit'));
+    $this->drupalPostForm($webform_ajax_confirmation_page->toUrl(), [], 'Submit');
     $assert_session->waitForLink('Back to form');
 
     // Check confirmation page message.
@@ -137,7 +137,7 @@ public function testAjax() {
     $webform_ajax_confirmation_url = Webform::load('test_ajax_confirmation_url');
 
     // Submit form.
-    $this->drupalPostForm($webform_ajax_confirmation_url->toUrl(), [], t('Submit'));
+    $this->drupalPostForm($webform_ajax_confirmation_url->toUrl(), [], 'Submit');
     $assert_session->waitForElement('css', '.path-front');
 
     // Check current page is <front>.
@@ -150,7 +150,7 @@ public function testAjax() {
     $webform_ajax_confirmation_url_msg = Webform::load('test_ajax_confirmation_url_msg');
 
     // Submit form.
-    $this->drupalPostForm($webform_ajax_confirmation_url_msg->toUrl(), [], t('Submit'));
+    $this->drupalPostForm($webform_ajax_confirmation_url_msg->toUrl(), [], 'Submit');
     $assert_session->waitForElement('css', '.path-front');
 
     // Check current page is <front>.
diff --git a/web/modules/webform/tests/src/FunctionalJavascript/States/WebformStatesCustomJavaScriptTest.php b/web/modules/webform/tests/src/FunctionalJavascript/States/WebformStatesCustomJavaScriptTest.php
index 81a0526d8f..1fe3c6c9ea 100644
--- a/web/modules/webform/tests/src/FunctionalJavascript/States/WebformStatesCustomJavaScriptTest.php
+++ b/web/modules/webform/tests/src/FunctionalJavascript/States/WebformStatesCustomJavaScriptTest.php
@@ -7,7 +7,7 @@
 /**
  * Tests for webform submission conditions (#states) validator.
  *
- * @group Webform
+ * @group webform_javascript
  */
 class WebformStatesCustomJavaScriptTest extends WebformWebDriverTestBase {
 
diff --git a/web/modules/webform/tests/src/FunctionalJavascript/WebformWebDriverTestBase.php b/web/modules/webform/tests/src/FunctionalJavascript/WebformWebDriverTestBase.php
index 479d2d8e1d..91ab85f4a5 100644
--- a/web/modules/webform/tests/src/FunctionalJavascript/WebformWebDriverTestBase.php
+++ b/web/modules/webform/tests/src/FunctionalJavascript/WebformWebDriverTestBase.php
@@ -16,6 +16,14 @@ abstract class WebformWebDriverTestBase extends WebDriverTestBase {
   use WebformBrowserTestTrait;
   use WebformAssertLegacyTrait;
 
+  /**
+   * Set default theme to classy.
+   *
+   * @var string
+   * @see https://www.drupal.org/node/3083055
+   */
+  protected $defaultTheme = 'classy';
+
   /**
    * Modules to enable.
    *
@@ -33,7 +41,7 @@ abstract class WebformWebDriverTestBase extends WebDriverTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
     $this->loadWebforms(static::$testWebforms);
   }
@@ -41,7 +49,7 @@ public function setUp() {
   /**
    * {@inheritdoc}
    */
-  public function tearDown() {
+  protected function tearDown() {
     $this->purgeSubmissions();
     parent::tearDown();
   }
diff --git a/web/modules/webform/tests/src/FunctionalJavascript/Wizard/WebformWizardBasicJavaScriptTest.php b/web/modules/webform/tests/src/FunctionalJavascript/Wizard/WebformWizardBasicJavaScriptTest.php
index 27bd632ad7..7e667ab247 100644
--- a/web/modules/webform/tests/src/FunctionalJavascript/Wizard/WebformWizardBasicJavaScriptTest.php
+++ b/web/modules/webform/tests/src/FunctionalJavascript/Wizard/WebformWizardBasicJavaScriptTest.php
@@ -8,7 +8,7 @@
 /**
  * Tests for webform basic wizard.
  *
- * @group Webform
+ * @group webform_javascript
  */
 class WebformWizardBasicJavaScriptTest extends WebformWebDriverTestBase {
 
@@ -23,8 +23,6 @@ class WebformWizardBasicJavaScriptTest extends WebformWebDriverTestBase {
    * Test webform basic wizard.
    */
   public function testBasicWizard() {
-    global $base_path;
-
     $session = $this->getSession();
     $page = $session->getPage();
     $assert_session = $this->assertSession();
diff --git a/web/modules/webform/tests/src/Kernel/Breadcrumb/WebformBreadcrumbBuilderTest.php b/web/modules/webform/tests/src/Kernel/Breadcrumb/WebformBreadcrumbBuilderTest.php
index c770616449..7b93a3405d 100644
--- a/web/modules/webform/tests/src/Kernel/Breadcrumb/WebformBreadcrumbBuilderTest.php
+++ b/web/modules/webform/tests/src/Kernel/Breadcrumb/WebformBreadcrumbBuilderTest.php
@@ -28,7 +28,7 @@ class WebformBreadcrumbBuilderTest extends UnitTestCase {
   protected $moduleHandler;
 
   /**
-   * The Webform request handler.
+   * The webform request handler.
    *
    * @var \Drupal\webform\WebformRequestInterface
    */
@@ -42,7 +42,7 @@ class WebformBreadcrumbBuilderTest extends UnitTestCase {
   protected $translationManager;
 
   /**
-   * The Webform breadcrumb builder.
+   * The webform breadcrumb builder.
    *
    * @var \Drupal\webform\Breadcrumb\WebformBreadcrumbBuilder
    */
@@ -145,25 +145,6 @@ protected function setUp() {
   // Below test is passing locally but failing on Drupal.org.
   /****************************************************************************/
 
-  /**
-   * Tests WebformBreadcrumbBuilder::__construct().
-   *
-   * @covers ::__construct
-   */
-  /*
-  public function testConstructor() {
-    // Reflect upon our properties, except for config which is a special case.
-    $property_names = [
-      'moduleHandler' => $this->moduleHandler,
-      'requestHandler' => $this->requestHandler,
-      'stringTranslation' => $this->translationManager,
-    ];
-    foreach ($property_names as $property_name => $property_value) {
-      $this->assertAttributeEquals($property_value, $property_name, $this->breadcrumbBuilder);
-    }
-  }
-  */
-
   /**
    * Tests WebformBreadcrumbBuilder::applies().
    *
@@ -232,7 +213,7 @@ public function providerTestApplies() {
   public function testType($expected, $route_name = NULL, array $parameter_map = []) {
     $route_match = $this->getMockRouteMatch($route_name, $parameter_map);
     $this->breadcrumbBuilder->applies($route_match);
-    $this->assertAttributeEquals($expected, 'type', $this->breadcrumbBuilder);
+    $this->assertEquals($expected, $this->breadcrumbBuilder->getType());
   }
 
   /**
@@ -335,7 +316,7 @@ public function testBuildSourceEntityUserResults() {
     $webform_submission_access->expects($this->any())
       ->method('access')
       ->will($this->returnCallback(function ($operation) {
-        return ($operation == 'view_own');
+        return ($operation === 'view_own');
       }));
     $route_match = $this->getMockRouteMatch('entity.node.webform_submission.canonical', [
       ['webform_submission', $webform_submission_access],
diff --git a/web/modules/webform/tests/src/Kernel/Entity/WebformEntityTest.php b/web/modules/webform/tests/src/Kernel/Entity/WebformEntityTest.php
index 7b8d6cf879..be69d088f9 100644
--- a/web/modules/webform/tests/src/Kernel/Entity/WebformEntityTest.php
+++ b/web/modules/webform/tests/src/Kernel/Entity/WebformEntityTest.php
@@ -21,16 +21,13 @@ class WebformEntityTest extends KernelTestBase {
    *
    * @var array
    */
-  public static $modules = ['system', 'path', 'webform', 'user', 'field'];
+  public static $modules = ['system', 'path', 'path_alias', 'webform', 'user', 'field'];
 
   /**
    * Tests some of the methods.
    */
   public function testWebformMethods() {
-    // @todo Remove once Drupal 8.8.x is only supported.
-    if (floatval(\Drupal::VERSION) >= 8.8) {
-      $this->installEntitySchema('path_alias');
-    }
+    $this->installEntitySchema('path_alias');
     $this->installSchema('webform', ['webform']);
     $this->installConfig('webform');
 
@@ -198,7 +195,7 @@ public function testWebformMethods() {
     $webform->setElements($elements);
 
     // Check that elements are serialized to YAML.
-    $this->assertTrue($webform->getElementsRaw(), WebformYaml::encode($elements));
+    $this->assertEquals($webform->getElementsRaw(), WebformYaml::encode($elements));
 
     // Check elements decoded and flattened.
     $flattened_elements = [
@@ -282,7 +279,7 @@ public function testWebformMethods() {
 
     // Check invalid elements.
     $webform->set('elements', 'invalid')->save();
-    $this->assertFalse($webform->getElementsInitialized());
+    $this->assertEquals([], $webform->getElementsInitialized());
 
     /**************************************************************************/
     // Wizard pages.
@@ -301,30 +298,30 @@ public function testWebformMethods() {
 
     // Check get wizard pages.
     $wizard_pages = [
-      'page_1' => ['#title' => 'Page 1', '#access' => TRUE],
-      'page_2' => ['#title' => 'Page 2', '#access' => TRUE],
-      'page_3' => ['#title' => 'Page 3', '#access' => TRUE],
-      'webform_confirmation' => ['#title' => 'Complete', '#access' => TRUE],
+      'page_1' => ['#title' => 'Page 1', '#type' => 'page', '#access' => TRUE],
+      'page_2' => ['#title' => 'Page 2', '#type' => 'page', '#access' => TRUE],
+      'page_3' => ['#title' => 'Page 3', '#type' => 'page', '#access' => TRUE],
+      'webform_confirmation' => ['#title' => 'Complete', '#type' => 'page', '#access' => TRUE],
     ];
     $this->assertEquals($webform->getPages(), $wizard_pages);
 
     // Check get wizard pages with preview.
     $webform->setSetting('preview', TRUE)->save();
     $wizard_pages = [
-      'page_1' => ['#title' => 'Page 1', '#access' => TRUE],
-      'page_2' => ['#title' => 'Page 2', '#access' => TRUE],
-      'page_3' => ['#title' => 'Page 3', '#access' => TRUE],
-      'webform_preview' => ['#title' => 'Preview', '#access' => TRUE],
-      'webform_confirmation' => ['#title' => 'Complete', '#access' => TRUE],
+      'page_1' => ['#title' => 'Page 1', '#type' => 'page', '#access' => TRUE],
+      'page_2' => ['#title' => 'Page 2', '#type' => 'page', '#access' => TRUE],
+      'page_3' => ['#title' => 'Page 3', '#type' => 'page', '#access' => TRUE],
+      'webform_preview' => ['#title' => 'Preview', '#type' => 'page', '#access' => TRUE],
+      'webform_confirmation' => ['#title' => 'Complete', '#type' => 'page', '#access' => TRUE],
     ];
     $this->assertEquals($webform->getPages(), $wizard_pages);
 
     // Check get wizard pages with preview with disable pages.
     $webform->setSetting('preview', TRUE)->save();
     $wizard_pages = [
-      'webform_start' => ['#title' => 'Start', '#access' => TRUE],
-      'webform_preview' => ['#title' => 'Preview', '#access' => TRUE],
-      'webform_confirmation' => ['#title' => 'Complete', '#access' => TRUE],
+      'webform_start' => ['#title' => 'Start', '#type' => 'page', '#access' => TRUE],
+      'webform_preview' => ['#title' => 'Preview', '#type' => 'page', '#access' => TRUE],
+      'webform_confirmation' => ['#title' => 'Complete', '#type' => 'page', '#access' => TRUE],
     ];
     $this->assertEquals($webform->getPages(TRUE), $wizard_pages);
 
@@ -338,23 +335,14 @@ public function testWebformMethods() {
    * Test paths.
    */
   public function testPaths() {
-    // @todo Remove once Drupal 8.8.x is only supported.
-    if (floatval(\Drupal::VERSION) >= 8.8) {
-      $this->installEntitySchema('path_alias');
-    }
+    $this->installEntitySchema('path_alias');
     $this->installSchema('webform', ['webform']);
     $this->installConfig('webform');
 
     /** @var \Drupal\webform\WebformInterface $webform */
     $webform = Webform::create(['id' => 'webform_test']);
     $webform->save();
-    // @todo Remove once Drupal 8.8.x is only supported.
-    if (floatval(\Drupal::VERSION) >= 8.8) {
-      $aliases = \Drupal::database()->query('SELECT path, alias FROM {path_alias}')->fetchAllKeyed();
-    }
-    else {
-      $aliases = \Drupal::database()->query('SELECT source, alias FROM {url_alias}')->fetchAllKeyed();
-    }
+    $aliases = \Drupal::database()->query('SELECT path, alias FROM {path_alias}')->fetchAllKeyed();
     $this->assertEquals($aliases['/webform/webform_test'], '/form/webform-test');
     $this->assertEquals($aliases['/webform/webform_test/confirmation'], '/form/webform-test/confirmation');
     $this->assertEquals($aliases['/webform/webform_test/submissions'], '/form/webform-test/submissions');
@@ -364,10 +352,7 @@ public function testPaths() {
    * Test elements CRUD operations.
    */
   public function testElementsCrud() {
-    // @todo Remove once Drupal 8.8.x is only supported.
-    if (floatval(\Drupal::VERSION) >= 8.8) {
-      $this->installEntitySchema('path_alias');
-    }
+    $this->installEntitySchema('path_alias');
     $this->installSchema('webform', ['webform']);
     $this->installEntitySchema('webform_submission');
 
diff --git a/web/modules/webform/tests/src/Kernel/Entity/WebformSubmissionEntityTest.php b/web/modules/webform/tests/src/Kernel/Entity/WebformSubmissionEntityTest.php
index c3033b55fb..4a44d73b7c 100644
--- a/web/modules/webform/tests/src/Kernel/Entity/WebformSubmissionEntityTest.php
+++ b/web/modules/webform/tests/src/Kernel/Entity/WebformSubmissionEntityTest.php
@@ -24,7 +24,7 @@ class WebformSubmissionEntityTest extends KernelTestBase {
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
 
     $this->installSchema('webform', ['webform']);
diff --git a/web/modules/webform/tests/src/Kernel/WebformConditionTest.php b/web/modules/webform/tests/src/Kernel/WebformConditionTest.php
index cff3edcaad..c58b04c473 100644
--- a/web/modules/webform/tests/src/Kernel/WebformConditionTest.php
+++ b/web/modules/webform/tests/src/Kernel/WebformConditionTest.php
@@ -26,7 +26,7 @@ class WebformConditionTest extends EntityKernelTestBase {
   public function testConditions() {
     $this->installSchema('webform', ['webform']);
 
-    $manager = $this->container->get('plugin.manager.condition', $this->container->get('container.namespaces'));
+    $manager = $this->container->get('plugin.manager.condition');
     $this->createUser();
 
     // Get some nodes of various types to check against.
diff --git a/web/modules/webform/tests/src/Kernel/WebformEntityElementsValidationTest.php b/web/modules/webform/tests/src/Kernel/WebformEntityElementsValidationTest.php
index 8b1ad0f7eb..df268b8235 100644
--- a/web/modules/webform/tests/src/Kernel/WebformEntityElementsValidationTest.php
+++ b/web/modules/webform/tests/src/Kernel/WebformEntityElementsValidationTest.php
@@ -178,6 +178,17 @@ public function testValidate() {
         ],
       ],
 
+      // Check validate pages.
+      [
+        'getElementsRaw' => "page:
+  '#type': webform_wizard_page
+card:
+  '#type': webform_card",
+        'messages' => [
+          'Pages and cards cannot be used in the same webform. Please remove or convert the pages/cards to the same element type.',
+        ],
+      ],
+
 /*
       // Check validate rendering.
       [
diff --git a/web/modules/webform/tests/src/Kernel/WebformSubmissionStorageTest.php b/web/modules/webform/tests/src/Kernel/WebformSubmissionStorageTest.php
index 83347112bc..68b8867d43 100644
--- a/web/modules/webform/tests/src/Kernel/WebformSubmissionStorageTest.php
+++ b/web/modules/webform/tests/src/Kernel/WebformSubmissionStorageTest.php
@@ -19,17 +19,14 @@ class WebformSubmissionStorageTest extends KernelTestBase {
    *
    * @var array
    */
-  public static $modules = ['system', 'user', 'path', 'field', 'webform'];
+  public static $modules = ['system', 'user', 'path', 'path_alias', 'field', 'webform'];
 
   /**
    * {@inheritdoc}
    */
-  public function setUp() {
+  protected function setUp() {
     parent::setUp();
-    // @todo Remove once Drupal 8.8.x is only supported.
-    if (floatval(\Drupal::VERSION) >= 8.8) {
-      $this->installEntitySchema('path_alias');
-    }
+    $this->installEntitySchema('path_alias');
     $this->installSchema('webform', ['webform']);
     $this->installConfig('webform');
     $this->installEntitySchema('webform_submission');
@@ -107,7 +104,7 @@ public function testPurge($webform_purging, $webform_submissions_definition, $pu
       $result[$submission->serial()] = $submission;
     }
     foreach ($purged as $sequence_id) {
-      $this->assertFalse(isset($result[$sequence_id]), 'Webform submission with sequence ' . $sequence_id . ' is purged.');
+      $this->assertArrayNotHasKey($sequence_id, $result, 'Webform submission with sequence ' . $sequence_id . ' is purged.');
     }
     $this->assertEquals(count($webform_submissions_definition) - count($purged), count($result), 'Remaining webform submissions are not purged.');
   }
diff --git a/web/modules/webform/tests/src/Traits/WebformAssertLegacyTrait.php b/web/modules/webform/tests/src/Traits/WebformAssertLegacyTrait.php
index 3705cbcc2a..4c8fa6ac52 100644
--- a/web/modules/webform/tests/src/Traits/WebformAssertLegacyTrait.php
+++ b/web/modules/webform/tests/src/Traits/WebformAssertLegacyTrait.php
@@ -308,7 +308,7 @@ protected function assertRaw($raw) {
     $actual = $this->getRawContent();
     $message = sprintf('The string "%s" was not found anywhere in the HTML response of the current page.', $raw);
 
-    $this->assert(strpos($actual, (string) $raw) !== false, $message);
+    $this->assertNotSame(strpos($actual, (string) $raw), false, $message);
   }
 
   /**
@@ -323,7 +323,7 @@ protected function assertNoRaw($raw) {
     $actual = $this->getRawContent();
     $message = sprintf('The string "%s" was not found anywhere in the HTML response of the current page.', $raw);
 
-    $this->assert(strpos($actual, (string) $raw) === false, $message);
+    $this->assertSame(strpos($actual, (string) $raw), false, $message);
   }
 
   /**
diff --git a/web/modules/webform/tests/src/Traits/WebformBrowserTestTrait.php b/web/modules/webform/tests/src/Traits/WebformBrowserTestTrait.php
index b29ea53bea..bcf10a9ab1 100644
--- a/web/modules/webform/tests/src/Traits/WebformBrowserTestTrait.php
+++ b/web/modules/webform/tests/src/Traits/WebformBrowserTestTrait.php
@@ -40,7 +40,7 @@ protected function placeBlocks() {
    */
   protected function placeWebformBlocks($module_name) {
     $config_directory = drupal_get_path('module', 'webform') . '/tests/modules/' . $module_name . '/config';
-    $config_files = file_scan_directory($config_directory, '/block\..*/');
+    $config_files = \Drupal::service('file_system')->scanDirectory($config_directory, '/block\..*/');
     foreach ($config_files as $config_file) {
       $data = Yaml::decode(file_get_contents($config_file->uri));
       $plugin_id = $data['plugin'];
@@ -425,7 +425,7 @@ protected function assertCssSelect($selector, $message = '') {
     if (!$message) {
       $message = new FormattableMarkup('Found @selector', ['@selector' => $selector]);
     }
-    $this->assertTrue(!empty($element), $message);
+    $this->assertNotEmpty($element, $message);
   }
 
   /**
@@ -433,7 +433,31 @@ protected function assertCssSelect($selector, $message = '') {
    */
   protected function assertNoCssSelect($selector, $message = '') {
     $element = $this->cssSelect($selector);
-    $this->assertTrue(empty($element), $message);
+    $this->assertEmpty($element, $message);
+  }
+
+  /**
+   * Asserts that the element with the given CSS selector is visible.
+   *
+   * @param string $css_selector
+   *   The CSS selector identifying the element to check.
+   * @param string $message
+   *   Optional message to show alongside the assertion.
+   */
+  protected function assertElementVisible($css_selector, $message = '') {
+    $this->assertTrue($this->getSession()->getDriver()->isVisible($this->cssSelectToXpath($css_selector)), $message);
+  }
+
+  /**
+   * Asserts that the element with the given CSS selector is not visible.
+   *
+   * @param string $css_selector
+   *   The CSS selector identifying the element to check.
+   * @param string $message
+   *   Optional message to show alongside the assertion.
+   */
+  protected function assertElementNotVisible($css_selector, $message = '') {
+    $this->assertFalse($this->getSession()->getDriver()->isVisible($this->cssSelectToXpath($css_selector)), $message);
   }
 
   /****************************************************************************/
diff --git a/web/modules/webform/tests/src/Unit/Access/WebformSubmissionAccessTest.php b/web/modules/webform/tests/src/Unit/Access/WebformSubmissionAccessTest.php
index 459afc2264..056c4dc1f4 100644
--- a/web/modules/webform/tests/src/Unit/Access/WebformSubmissionAccessTest.php
+++ b/web/modules/webform/tests/src/Unit/Access/WebformSubmissionAccessTest.php
@@ -62,8 +62,8 @@ public function testWebformSubmissionAccess() {
     // Mock webform wizard.
     $webform_wizard = $this->createMock('Drupal\webform\WebformInterface');
     $webform_wizard->expects($this->any())
-      ->method('hasWizardPages')
-      ->will($this->returnValue(TRUE));
+      ->method('getElementsRaw')
+      ->will($this->returnValue("'#type': webform_wizard_page"));
 
     // Mock webform wizard submission.
     $webform_wizard_submission = $this->createMock('Drupal\webform\WebformSubmissionInterface');
diff --git a/web/modules/webform/tests/src/Unit/Utility/WebformElementHelperTest.php b/web/modules/webform/tests/src/Unit/Utility/WebformElementHelperTest.php
index edcb8441bf..5759d07665 100644
--- a/web/modules/webform/tests/src/Unit/Utility/WebformElementHelperTest.php
+++ b/web/modules/webform/tests/src/Unit/Utility/WebformElementHelperTest.php
@@ -85,9 +85,10 @@ public function providerGetIgnoredProperties() {
       ['#tree' => TRUE, '#value' => 'text', '#element_validate' => 'some_function'],
       ['#tree' => '#tree', '#element_validate' => '#element_validate'],
     ];
-    // Ignore #subelement__tree and #subelement__element_validate.
+    // Ignore #subelement__tree and #subelement__element_validate,
+    // but not '#subelement__weight'.
     $tests[] = [
-      ['#subelement__tree' => TRUE, '#value' => 'text', '#subelement__element_validate' => 'some_function'],
+      ['#subelement__tree' => TRUE, '#value' => 'text', '#subelement__element_validate' => 'some_function', '#subelement__weight' => 0],
       ['#subelement__tree' => '#subelement__tree', '#subelement__element_validate' => '#subelement__element_validate'],
     ];
     return $tests;
@@ -131,7 +132,7 @@ public function providerRemoveIgnoredProperties() {
       ['#tree' => TRUE, '#value' => 'text', '#element_validate' => 'some_function'],
       ['#value' => 'text'],
     ];
-    // Remove #ajax: string
+    // Remove #ajax: string.
     $tests[] = [
       ['#ajax' => 'some_function'],
       [],
@@ -144,8 +145,8 @@ public function providerRemoveIgnoredProperties() {
     ];
     // Remove #subelement__tree and #subelement__element_validate.
     $tests[] = [
-      ['#subelement__tree' => TRUE, '#value' => 'text', '#subelement__element_validate' => 'some_function'],
-      ['#value' => 'text'],
+      ['#subelement__tree' => TRUE, '#value' => 'text', '#subelement__element_validate' => 'some_function', '#subelement__equal_stepwise_validate' => TRUE],
+      ['#value' => 'text', '#subelement__equal_stepwise_validate' => TRUE],
     ];
     // Remove random nested #element_validate.
     $tests[] = [
@@ -153,8 +154,8 @@ public function providerRemoveIgnoredProperties() {
       ['random' => []],
     ];
     $tests[] = [
-      ['#prefix' => ['#markup' => 'some_markup', '#element_validate' => 'some_function']],
-      ['#prefix' => ['#markup' => 'some_markup']],
+      ['#prefix' => ['#markup' => 'some_markup', '#element_validate' => 'some_function', '#equal_stepwise_validate' => TRUE]],
+      ['#prefix' => ['#markup' => 'some_markup', '#equal_stepwise_validate' => TRUE]],
     ];
     // Remove any *_validate(s) and *_callback(s).
     $tests[] = [
@@ -165,6 +166,11 @@ public function providerRemoveIgnoredProperties() {
       ['random' => ['#some_random_callbacks' => 'some_function']],
       ['random' => []],
     ];
+    // Remove #weight but not subelement__weight.
+    $tests[] = [
+      ['#weight' => 1, '#subelement__weight' => 1],
+      ['#subelement__weight' => 1],
+    ];
     return $tests;
   }
 
@@ -245,7 +251,7 @@ public function providerHasProperty() {
       [
         [['#required' => 'value'], '#required', 'value'],
         TRUE,
-        '#required == value',
+        '#required === value',
       ],
       [
         [['nested' => ['#required' => TRUE]], '#required', NULL],
@@ -255,7 +261,7 @@ public function providerHasProperty() {
       [
         [['nested' => ['#required' => 'value']], '#required', 'value'],
         TRUE,
-        'nested #required == value',
+        'nested #required === value',
       ],
 
     ];
diff --git a/web/modules/webform/tests/src/Unit/Utility/WebformYamlTest.php b/web/modules/webform/tests/src/Unit/Utility/WebformYamlTest.php
index e2dd02be05..07ce41e73c 100644
--- a/web/modules/webform/tests/src/Unit/Utility/WebformYamlTest.php
+++ b/web/modules/webform/tests/src/Unit/Utility/WebformYamlTest.php
@@ -65,4 +65,66 @@ public function providerTidy() {
     return $tests;
   }
 
+  /**
+   * Tests WebformYaml tidy with WebformYaml::decode().
+   *
+   * @param string $yaml
+   *   The string to run through WebformYaml::decode().
+   * @param string $expected
+   *   The expected result from calling the function.
+   *
+   * @see WebformYaml::decode()
+   *
+   * @dataProvider providerDecode
+   */
+  public function testDecode($yaml, $expected) {
+    $result = WebformYaml::decode($yaml);
+    $this->assertEquals($expected, $result);
+  }
+
+  /**
+   * Data provider for testDecode().
+   *
+   * @see testDecode()
+   */
+  public function providerDecode() {
+    $tests[] = [
+      "simple: value",
+      ['simple' => 'value'],
+    ];
+    $tests[] = [
+      "returns: |\n  line 1\n  line 2",
+      ['returns' => "line 1\nline 2"],
+    ];
+    $tests[] = [
+      "'one two': |\n  line 1\n  line 2",
+      ['one two' => "line 1\nline 2"],
+    ];
+    $tests[] = [
+      "array:\n  - one\n  - two",
+      ['array' => ['one', 'two']],
+    ];
+    $tests[] = [
+      "- one: One\n- two: Two",
+      [['one' => 'One'], ['two' => 'Two']],
+    ];
+    $tests[] = [
+      FALSE,
+      [],
+    ];
+    $tests[] = [
+      NULL,
+      [],
+    ];
+    $tests[] = [
+      [],
+      [],
+    ];
+    $tests[] = [
+      0,
+      [],
+    ];
+    return $tests;
+  }
+
 }
diff --git a/web/modules/webform/tests/src/Unit/WebformMessageManagerTest.php b/web/modules/webform/tests/src/Unit/WebformMessageManagerTest.php
index 45fea9b0af..1619af52c3 100644
--- a/web/modules/webform/tests/src/Unit/WebformMessageManagerTest.php
+++ b/web/modules/webform/tests/src/Unit/WebformMessageManagerTest.php
@@ -138,7 +138,7 @@ public function testMessageManager() {
     $result = $message_manager->get(WebformMessageManagerInterface::DRAFT_PENDING_SINGLE);
     $this->assertEquals($expected, $result);
 
-    // Check [none] for multiple message returns an empty string..
+    // Check [none] for multiple message returns an empty string.
     $result = $message_manager->get(WebformMessageManagerInterface::DRAFT_PENDING_MULTIPLE);
     $this->assertFalse($result);
   }
diff --git a/web/modules/webform/tests/themes/webform_test_bartik/webform_test_bartik.info.yml b/web/modules/webform/tests/themes/webform_test_bartik/webform_test_bartik.info.yml
index 906938f818..e71d2497a7 100644
--- a/web/modules/webform/tests/themes/webform_test_bartik/webform_test_bartik.info.yml
+++ b/web/modules/webform/tests/themes/webform_test_bartik/webform_test_bartik.info.yml
@@ -1,11 +1,11 @@
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 type: theme
 base theme: bartik
-name: 'Webform Test Bartik'
-description: 'Test Webform Bartik integration.'
-package: 'Webform Test'
+name: 'Webform Bartik test'
+description: 'Support theme for webform Bartik integration testing.'
+package: 'Webform Testing'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/third_party_settings/webform.antibot.inc b/web/modules/webform/third_party_settings/webform.antibot.inc
index 040085561d..14db7cf0db 100644
--- a/web/modules/webform/third_party_settings/webform.antibot.inc
+++ b/web/modules/webform/third_party_settings/webform.antibot.inc
@@ -59,10 +59,11 @@ function _webform_antibot_form(array &$form, FormStateInterface $form_state, $an
     '#return_value' => TRUE,
   ];
 
-  if ($antibot_state != WEBFORM_ANTIBOT_NEUTRAL) {
+  $antibot_state = (int) $antibot_state;
+  if ($antibot_state !== WEBFORM_ANTIBOT_NEUTRAL) {
     $form['third_party_settings']['antibot']['antibot']['#attributes']['disabled'] = 'disabled';
     $form_state->set('antibot_disabled', TRUE);
-    if ($antibot_state == WEBFORM_ANTIBOT_ENABLED_WEBFORM) {
+    if ($antibot_state === WEBFORM_ANTIBOT_ENABLED_WEBFORM) {
       $form['third_party_settings']['antibot']['antibot']['#default_value'] = 1;
       $form['third_party_settings']['antibot']['antibot']['#description'] = t('<a href=":href_webform">Antibot protection</a> is enabled for all webforms.', $t_args);
     }
diff --git a/web/modules/webform/third_party_settings/webform.honeypot.inc b/web/modules/webform/third_party_settings/webform.honeypot.inc
index a5ece36917..4c9e90cd90 100644
--- a/web/modules/webform/third_party_settings/webform.honeypot.inc
+++ b/web/modules/webform/third_party_settings/webform.honeypot.inc
@@ -74,14 +74,14 @@ function _webform_honeypot_form(array &$form, FormStateInterface $form_state, $h
     '#return_value' => TRUE,
   ];
 
-  if ($honeypot_state != WEBFORM_HONEYPOT_NEUTRAL) {
+  if ($honeypot_state !== WEBFORM_HONEYPOT_NEUTRAL) {
     $form['third_party_settings']['honeypot']['honeypot']['#attributes']['disabled'] = 'disabled';
     $form_state->set('honeypot_disabled', TRUE);
-    if ($honeypot_state == WEBFORM_HONEYPOT_ENABLED_ALL) {
+    if ($honeypot_state === WEBFORM_HONEYPOT_ENABLED_ALL) {
       $form['third_party_settings']['honeypot']['honeypot']['#default_value'] = 1;
       $form['third_party_settings']['honeypot']['honeypot']['#description'] = t('<a href=":href_honeypot">Honeypot protection</a> is enabled for all webforms.', $t_args);
     }
-    elseif ($honeypot_state == WEBFORM_HONEYPOT_ENABLED_WEBFORM) {
+    elseif ($honeypot_state === WEBFORM_HONEYPOT_ENABLED_WEBFORM) {
       $form['third_party_settings']['honeypot']['honeypot']['#default_value'] = 1;
       $form['third_party_settings']['honeypot']['honeypot']['#description'] = t('<a href=":href_webform">Honeypot protection</a> is enabled for all webforms.', $t_args);
     }
@@ -96,14 +96,14 @@ function _webform_honeypot_form(array &$form, FormStateInterface $form_state, $h
     '#return_value' => TRUE,
   ];
 
-  if ($time_restriction_state != WEBFORM_HONEYPOT_NEUTRAL) {
+  if ($time_restriction_state !== WEBFORM_HONEYPOT_NEUTRAL) {
     $form['third_party_settings']['honeypot']['time_restriction']['#attributes']['disabled'] = 'disabled';
     $form_state->set('time_restriction_disabled', TRUE);
-    if ($time_restriction_state == WEBFORM_HONEYPOT_DISABLED_ALL) {
+    if ($time_restriction_state === WEBFORM_HONEYPOT_DISABLED_ALL) {
       $form['third_party_settings']['honeypot']['time_restriction']['#default_value'] = 0;
       $form['third_party_settings']['honeypot']['time_restriction']['#description'] = t('<a href=":href_honeypot">Time limit</a> is disabled for all webforms.', $t_args);
     }
-    elseif ($time_restriction_state == WEBFORM_HONEYPOT_ENABLED_WEBFORM) {
+    elseif ($time_restriction_state === WEBFORM_HONEYPOT_ENABLED_WEBFORM) {
       $form['third_party_settings']['honeypot']['time_restriction']['#default_value'] = 1;
       $form['third_party_settings']['honeypot']['time_restriction']['#description'] = t('<a href=":href_webform">Time limit</a> is enabled for all webforms.', $t_args);
     }
@@ -140,11 +140,12 @@ function honeypot_webform_admin_third_party_settings_form_alter(&$form, FormStat
   /** @var \Drupal\webform\WebformThirdPartySettingsManagerInterface $third_party_settings_manager */
   $third_party_settings_manager = \Drupal::service('webform.third_party_settings_manager');
 
-  $honeypot = $third_party_settings_manager->getThirdPartySetting('honeypot', 'honeypot');
+  $honeypot = (int) $third_party_settings_manager->getThirdPartySetting('honeypot', 'honeypot');
   $honeypot_state = \Drupal::config('honeypot.settings')->get('protect_all_forms') ? WEBFORM_HONEYPOT_ENABLED_ALL : WEBFORM_HONEYPOT_NEUTRAL;
+  $honeypot_time_limit = (int) \Drupal::config('honeypot.settings')->get('time_limit');
 
-  $time_restriction = $third_party_settings_manager->getThirdPartySetting('honeypot', 'time_restriction');
-  $time_restriction_state = (\Drupal::config('honeypot.settings')->get('time_limit') == 0) ? WEBFORM_HONEYPOT_DISABLED_ALL : WEBFORM_HONEYPOT_NEUTRAL;
+  $time_restriction = (int) $third_party_settings_manager->getThirdPartySetting('honeypot', 'time_restriction');
+  $time_restriction_state = ($honeypot_time_limit === 0) ? WEBFORM_HONEYPOT_DISABLED_ALL : WEBFORM_HONEYPOT_NEUTRAL;
 
   _webform_honeypot_form(
     $form,
@@ -167,7 +168,7 @@ function honeypot_webform_third_party_settings_form_alter(&$form, FormStateInter
   /** @var \Drupal\webform\WebformInterface $webform */
   $webform = $form_state->getFormObject()->getEntity();
 
-  $honeypot = $webform->getThirdPartySetting('honeypot', 'honeypot');
+  $honeypot = (int) $webform->getThirdPartySetting('honeypot', 'honeypot');
   if (\Drupal::config('honeypot.settings')->get('protect_all_forms')) {
     $honeypot_state = WEBFORM_HONEYPOT_ENABLED_ALL;
   }
@@ -178,8 +179,9 @@ function honeypot_webform_third_party_settings_form_alter(&$form, FormStateInter
     $honeypot_state = WEBFORM_HONEYPOT_NEUTRAL;
   }
 
-  $time_restriction = $webform->getThirdPartySetting('honeypot', 'time_restriction');
-  if (\Drupal::config('honeypot.settings')->get('time_limit') == 0) {
+  $time_restriction = (int) $webform->getThirdPartySetting('honeypot', 'time_restriction');
+  $honeypot_time_limit = (int) \Drupal::config('honeypot.settings')->get('time_limit');
+  if ($honeypot_time_limit === 0) {
     $time_restriction_state = WEBFORM_HONEYPOT_DISABLED_ALL;
   }
   elseif ($third_party_settings_manager->getThirdPartySetting('honeypot', 'time_restriction')) {
@@ -220,13 +222,13 @@ function honeypot_webform_submission_form_alter(&$form, FormStateInterface $form
 
   $options = [];
 
-  $honeypot = $third_party_settings_manager->getThirdPartySetting('honeypot', 'honeypot') ?:
+  $honeypot = (int) $third_party_settings_manager->getThirdPartySetting('honeypot', 'honeypot') ?:
     $webform->getThirdPartySetting('honeypot', 'honeypot');
   if ($honeypot) {
     $options[] = 'honeypot';
   }
 
-  $time_restriction = $third_party_settings_manager->getThirdPartySetting('honeypot', 'time_restriction') ?:
+  $time_restriction = (int) $third_party_settings_manager->getThirdPartySetting('honeypot', 'time_restriction') ?:
     $webform->getThirdPartySetting('honeypot', 'time_restriction');
   if ($time_restriction) {
     $options[] = 'time_restriction';
diff --git a/web/modules/webform/third_party_settings/webform.maillog.inc b/web/modules/webform/third_party_settings/webform.maillog.inc
index 54dc333498..10af83dd48 100644
--- a/web/modules/webform/third_party_settings/webform.maillog.inc
+++ b/web/modules/webform/third_party_settings/webform.maillog.inc
@@ -16,7 +16,7 @@
  */
 function maillog_webform_submission_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
   // Never display Maillog message via CLI.
-  if (PHP_SAPI == 'cli') {
+  if (PHP_SAPI === 'cli') {
     return;
   }
 
diff --git a/web/modules/webform/webform.info.yml b/web/modules/webform/webform.info.yml
index 867a961091..b8b2b2e8ad 100644
--- a/web/modules/webform/webform.info.yml
+++ b/web/modules/webform/webform.info.yml
@@ -2,13 +2,13 @@ name: Webform
 type: module
 description: 'Enables the creation of webforms and questionnaires.'
 package: Webform
-core_version_requirement: ^8.7.7 || ^9
+core_version_requirement: ^8.8
 configure: entity.webform.collection
 dependencies:
   - 'drupal:field'
   - 'drupal:user'
 
-# Information added by Drupal.org packaging script on 2020-05-13
-version: '8.x-5.12'
+# Information added by Drupal.org packaging script on 2020-06-24
+version: '8.x-5.18'
 project: 'webform'
-datestamp: 1589372290
+datestamp: 1593034091
diff --git a/web/modules/webform/webform.libraries.yml b/web/modules/webform/webform.libraries.yml
index df15df09b9..f71e976608 100644
--- a/web/modules/webform/webform.libraries.yml
+++ b/web/modules/webform/webform.libraries.yml
@@ -990,14 +990,14 @@ libraries.choices:
 
 libraries.codemirror.text:
   remote: https://github.com/codemirror/codemirror
-  version: &webform_codemirror_version '5.51.0'
+  version: &webform_codemirror_version '5.53.2'
   license: &webform_codemirror_license
     name: MIT
     url: http://codemirror.net/LICENSE
     gpl-compatible: true
   cdn: &webform_codemirror_cdn
-    /libraries/codemirror/lib/: https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.51.0/
-    /libraries/codemirror/: https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.51.0/
+    /libraries/codemirror/lib/: https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.53.2/
+    /libraries/codemirror/: https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.53.2/
   css:
     component:
       /libraries/codemirror/lib/codemirror.css: {}
@@ -1076,13 +1076,13 @@ libraries.codemirror.twig:
 
 libraries.algolia.places:
   remote: https://github.com/algolia/places
-  version: '1.17.1'
+  version: '1.18.2'
   license:
     name: MIT
     url: https://github.com/algolia/places/blob/master/LICENSE
     gpl-compatible: true
   cdn:
-    /libraries/algolia.places/dist/cdn/: https://cdn.jsdelivr.net/npm/places.js@1.17.1/dist/cdn/
+    /libraries/algolia.places/dist/cdn/: https://cdn.jsdelivr.net/npm/places.js@1.18.2/dist/cdn/
   js:
     /libraries/algolia.places/dist/cdn/places.js: {}
 
@@ -1138,13 +1138,13 @@ libraries.jquery.rateit:
 
 libraries.jquery.select2:
   remote: https://select2.github.io/
-  version: '4.0.12'
+  version: '4.0.13'
   license:
     name: MIT
     url: http://opensource.org/licenses/mit-license.php
     gpl-compatible: true
   cdn:
-    /libraries/jquery.select2/dist/: https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.12/
+    /libraries/jquery.select2/dist/: https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/
   css:
     component:
       /libraries/jquery.select2/dist/css/select2.min.css: { minified: true }
@@ -1172,13 +1172,13 @@ libraries.jquery.chosen:
 
 libraries.jquery.textcounter:
   remote: https://github.com/ractoon/jQuery-Text-Counter
-  version: '0.8.0'
+  version: '0.9.0'
   license:
     name: MIT
     url: http://opensource.org/licenses/mit-license.php
     gpl-compatible: true
   cdn:
-    /libraries/jquery.textcounter/: https://cdn.jsdelivr.net/gh/ractoon/jQuery-Text-Counter@0.8.0/
+    /libraries/jquery.textcounter/: https://cdn.jsdelivr.net/gh/ractoon/jQuery-Text-Counter@0.9.0/
   js:
     /libraries/jquery.textcounter/textcounter.min.js: { minified: true }
   dependencies:
@@ -1186,13 +1186,13 @@ libraries.jquery.textcounter:
 
 libraries.jquery.timepicker:
   remote: https://github.com/jonthornton/jquery-timepicker
-  version: '1.13.0'
+  version: '1.13.10'
   license:
     name: MIT
     url: http://opensource.org/licenses/mit-license.php
     gpl-compatible: true
   cdn:
-    /libraries/jquery.timepicker/: https://cdn.jsdelivr.net/gh/jonthornton/jquery-timepicker@1.13.0/
+    /libraries/jquery.timepicker/: https://cdn.jsdelivr.net/gh/jonthornton/jquery-timepicker@1.13.10/
   css:
     component:
       /libraries/jquery.timepicker/jquery.timepicker.min.css: { minified: true }
diff --git a/web/modules/webform/webform.module b/web/modules/webform/webform.module
index b5f1f52eb5..3f17cedf03 100644
--- a/web/modules/webform/webform.module
+++ b/web/modules/webform/webform.module
@@ -5,10 +5,8 @@
  * Enables the creation of webforms and questionnaires.
  */
 
-use Drupal\Component\Utility\Unicode;
 use Drupal\Component\Serialization\Json;
 use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Breadcrumb\Breadcrumb;
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
 use Drupal\Core\Render\Element;
@@ -23,8 +21,8 @@
 use Drupal\webform\Entity\WebformSubmission;
 use Drupal\webform\Plugin\WebformElement\ManagedFile;
 use Drupal\webform\Utility\Mail;
-use Drupal\webform\Utility\WebformArrayHelper;
 use Drupal\webform\Utility\WebformElementHelper;
+use Drupal\webform\Utility\WebformFormHelper;
 use Drupal\webform\Utility\WebformOptionsHelper;
 use Drupal\webform\WebformInterface;
 
@@ -49,7 +47,7 @@ function webform_help($route_name, RouteMatchInterface $route_match) {
 
   /** @var \Drupal\webform\WebformHelpManagerInterface $help_manager */
   $help_manager = \Drupal::service('webform.help_manager');
-  if ($route_name == 'help.page.webform') {
+  if ($route_name === 'help.page.webform') {
     $build = $help_manager->buildIndex();
   }
   else {
@@ -261,7 +259,7 @@ function webform_menu_local_tasks_alter(&$data, $route_name, RefinableCacheableD
     }
   }
 
-  // Allow webform query string parameters to be transfered
+  // Allow webform query string parameters to be transferred
   // from canonical to test URL.
   $route_names = [
     'entity.webform.canonical', 'entity.webform.test_form',
@@ -286,45 +284,13 @@ function webform_menu_local_tasks_alter(&$data, $route_name, RefinableCacheableD
  * Implements hook_module_implements_alter().
  */
 function webform_module_implements_alter(&$implementations, $hook) {
-  if ($hook == 'form_alter') {
+  if ($hook === 'form_alter') {
     $implementation = $implementations['webform'];
     unset($implementations['webform']);
     $implementations['webform'] = $implementation;
   }
 }
 
-/**
- * Implements hook_system_breadcrumb_alter().
- */
-function webform_system_breadcrumb_alter(Breadcrumb &$breadcrumb, RouteMatchInterface $route_match, array $context) {
-  // Prevent 'Route required in Drupal\Core\Url::fromRouteMatch()' errors.
-  // @see \Drupal\Core\Url::fromRouteMatch
-  if (!$route_match->getRouteObject()) {
-    return;
-  }
-
-  // Remove 'Webforms' prefix from breadcrumb links generated path breadcrumbs.
-  // @see \Drupal\system\PathBasedBreadcrumbBuilder
-  $path = Url::fromRouteMatch($route_match)->toString();
-  if (strpos($path, '/admin/structure/webform/config/') !== FALSE) {
-    $links = $breadcrumb->getLinks();
-    foreach ($links as $link) {
-      $text = $link->getText();
-      if (strpos($text, ((string) t('Webforms')) . ' ') == 0) {
-        $text = str_replace(((string) t('Webforms')) . ': ', '', $text);
-        $link->setText(Unicode::ucfirst($text));
-      }
-    }
-  }
-
-  // Fix 'Help' breadcrumb text.
-  if ($route_match->getRouteName() == 'webform.help.video') {
-    $links = $breadcrumb->getLinks();
-    $link = end($links);
-    $link->setText(t('Webforms'));
-  }
-}
-
 /**
  * Implements hook_token_info_alter().
  */
@@ -345,7 +311,7 @@ function webform_token_info_alter(&$data) {
   $more = _webform_token_render_more(t('Learn about token suffixes'), $token_suffixes);
   foreach ($data['types'] as $type => &$info) {
     if (strpos($type, 'webform') === 0) {
-      if (!empty($info['description'] && isset($info['description']))) {
+      if (isset($info['description']) && !empty($info['description'])) {
         $description = $info['description'] . $more;
       }
       else {
@@ -587,7 +553,16 @@ function _webform_page_attachments(array &$attachments) {
 
   // Attach variant randomization JavaScript.
   $route_name = \Drupal::routeMatch()->getRouteName();
-  if (in_array($route_name, ['entity.webform.canonical', 'entity.webform.test_form', 'entity.node.canonical', 'entity.node.webform.test_form'])) {
+  $route_names = [
+    'entity.webform.canonical',
+    'entity.webform.test_form',
+    'entity.node.canonical',
+    'entity.node.webform.test_form',
+    // Webform Share module routes.
+    'entity.webform.share_page',
+    'entity.webform.share_page.javascript',
+  ];
+  if (in_array($route_name, $route_names)) {
     $variants = [];
     $element_keys = $webform->getElementsVariant();
     foreach ($element_keys as $element_key) {
@@ -623,7 +598,7 @@ function _webform_page_attachments(array &$attachments) {
   }
   if (search !== location.search) {
     location.replace(location.pathname + search);
-  } 
+  }
 })();
 "),
           '#weight' => 1000,
@@ -642,7 +617,7 @@ function _webform_page_attachments(array &$attachments) {
  */
 function webform_file_access(FileInterface $file, $operation, AccountInterface $account) {
   // Block access to temporary anonymous private file uploads.
-  if ($operation == 'download' && $file->isTemporary() && $file->getOwnerId() == 0 && strpos($file->getFileUri(), 'private://webform/') === 0) {
+  if ($operation === 'download' && $file->isTemporary() && (int) $file->getOwnerId() === 0 && strpos($file->getFileUri(), 'private://webform/') === 0) {
     return AccessResult::forbidden();
   }
   return AccessResult::neutral();
@@ -765,19 +740,11 @@ function webform_webform_access_rules() {
  * @param string $key
  *   The element property to add the states attribute to.
  *
- * @see drupal_process_states()
+ * @deprecated Scheduled for removal in Webform 8.x-6.x
+ *   Use \Drupal\Core\Form\FormHelper::processStates instead.
  */
 function webform_process_states(array &$elements, $key = '#attributes') {
-  if (empty($elements['#states'])) {
-    return;
-  }
-
-  $elements['#attached']['library'][] = 'core/drupal.states';
-  $elements[$key]['data-drupal-states'] = Json::encode($elements['#states']);
-  // Make sure to include target class for this container.
-  if (empty($elements[$key]['class']) || !WebformArrayHelper::inArray(['js-form-item', 'js-form-submit', 'js-form-wrapper'], $elements[$key]['class'])) {
-    $elements[$key]['class'][] = 'js-form-item';
-  }
+  WebformFormHelper::processStates($elements, $key);
 }
 
 /******************************************************************************/
@@ -815,7 +782,7 @@ function webform_process_options(&$element, FormStateInterface $form_state, &$co
 
   // Description display.
   if (!empty($element['#options_description_display'])) {
-    $description_property_name = ($element['#options_description_display'] == 'help') ? '#help' : '#description';
+    $description_property_name = ($element['#options_description_display'] === 'help') ? '#help' : '#description';
     foreach (Element::children($element) as $key) {
       $title = (string) $element[$key]['#title'];
       // Check for -- delimiter.
@@ -831,7 +798,7 @@ function webform_process_options(&$element, FormStateInterface $form_state, &$co
   }
 
   // Display as buttons.
-  if (!empty($element['#options_display']) && $element['#options_display'] === 'buttons') {
+  if (!empty($element['#options_display']) && strpos($element['#options_display'], 'buttons') === 0) {
     foreach (Element::children($element) as $key) {
       // Add wrapper which is needed to make flexbox work with tables.
       $element[$key]['#prefix'] = '<div class="webform-options-display-buttons-wrapper">';
diff --git a/web/modules/webform/webform.routing.yml b/web/modules/webform/webform.routing.yml
index 32f110d4da..377381c991 100644
--- a/web/modules/webform/webform.routing.yml
+++ b/web/modules/webform/webform.routing.yml
@@ -823,6 +823,17 @@ entity.webform.variant.test_form:
     _entity_access: 'webform.update'
     _custom_access: '\Drupal\webform\Access\WebformVariantAccess::checkVariantSettingsAccess'
 
+entity.webform.variant.share_form:
+  path: '/admin/structure/webform/manage/{webform}/variants/share'
+  defaults:
+    _form: '\Drupal\webform\Form\WebformVariantViewForm'
+    _title: 'Share webform variants'
+    operation: 'share'
+  requirements:
+    _permission: 'edit webform variants'
+    _entity_access: 'webform.update'
+    _custom_access: '\Drupal\webform\Access\WebformVariantAccess::checkVariantSettingsAccess'
+
 # Plugins.
 
 webform.reports_plugins.elements:
diff --git a/web/modules/webform/webform.services.yml b/web/modules/webform/webform.services.yml
index 9da2bf8eeb..313d08e700 100644
--- a/web/modules/webform/webform.services.yml
+++ b/web/modules/webform/webform.services.yml
@@ -123,6 +123,7 @@ services:
 
   webform.route_subscriber:
     class: Drupal\webform\Routing\WebformRouteSubscriber
+    arguments: ['@module_handler']
     tags:
       - { name: event_subscriber }
 
diff --git a/web/modules/webform/webform.tokens.inc b/web/modules/webform/webform.tokens.inc
index fcb3bc0d63..ef0f635112 100644
--- a/web/modules/webform/webform.tokens.inc
+++ b/web/modules/webform/webform.tokens.inc
@@ -424,12 +424,12 @@ function webform_tokens($type, $tokens, array $data, array $options, BubbleableM
   }
 
   $replacements = [];
-  if ($type == 'webform_role' && !empty($data['webform_role'])) {
+  if ($type === 'webform_role' && !empty($data['webform_role'])) {
     $roles = $data['webform_role'];
     $any_role = in_array('authenticated', $roles) ? TRUE : FALSE;
     foreach ($tokens as $role_name => $original) {
       if ($any_role || in_array($role_name, $roles)) {
-        if ($role_name == 'authenticated') {
+        if ($role_name === 'authenticated') {
           // Get all active authenticated users.
           $query = \Drupal::database()->select('users_field_data', 'u');
           $query->fields('u', ['mail']);
@@ -455,7 +455,7 @@ function webform_tokens($type, $tokens, array $data, array $options, BubbleableM
     }
 
   }
-  elseif ($type == 'webform_submission' && !empty($data['webform_submission'])) {
+  elseif ($type === 'webform_submission' && !empty($data['webform_submission'])) {
     /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
     $element_manager = \Drupal::service('plugin.manager.webform.element');
 
@@ -758,7 +758,7 @@ function webform_tokens($type, $tokens, array $data, array $options, BubbleableM
     }
 
   }
-  elseif ($type == 'webform' && !empty($data['webform'])) {
+  elseif ($type === 'webform' && !empty($data['webform'])) {
 
     /** @var \Drupal\webform\WebformInterface $webform */
     $webform = $data['webform'];
@@ -832,7 +832,7 @@ function webform_tokens($type, $tokens, array $data, array $options, BubbleableM
         $key_exists = NULL;
         $value = NestedArray::getValue($webform_handler, $parents, $key_exists);
         // A handler response is always considered safe markup.
-        $replacements[$original] = ($key_exists) ? Markup::create($value) : $original;
+        $replacements[$original] = ($key_exists && is_scalar($value)) ? Markup::create($value) : $original;
       }
     }
 
@@ -894,7 +894,7 @@ function _webform_token_get_submission_value($value_token, array $options, Webfo
   $element_key = array_shift($keys);
 
   // Build HTML values.
-  if ($element_key == 'html' && empty($keys)) {
+  if ($element_key === 'html' && empty($keys)) {
     $options['html'] = TRUE;
     return _webform_token_get_submission_values($options, $webform_submission);
   }
@@ -966,7 +966,7 @@ function _webform_token_get_submission_value($value_token, array $options, Webfo
   /****************************************************************************/
 
   // Set entity reference chaining.
-  if ($keys && $keys[0] == 'entity' && $element_plugin instanceof WebformElementEntityReferenceInterface) {
+  if ($keys && $keys[0] === 'entity' && $element_plugin instanceof WebformElementEntityReferenceInterface) {
     // Remove entity from keys.
     array_shift($keys);
 
-- 
GitLab