From e33b8875f9ae277b56fd42cbbc9aacfe67ea727c Mon Sep 17 00:00:00 2001
From: Alexander Nitsche <typo3@alexandernitsche.com>
Date: Fri, 20 Aug 2021 00:07:42 +0200
Subject: [PATCH] [BUGFIX] Reactivate preset actions in current EXT:impexp

This is a regression introduced with #94772 that causes all actions
related to export presets to fail because the controller checks $_GET
instead of $_POST for incoming preset action parameters.

Reduced redundancy in EXT:impexp acceptance tests by introducing
AbstractCest::selectInContextMenu() for basic context menu handling
and moving waitForAjaxRequestToFinish() to the central AbstractCest.
In addition, the declarations of local variables have been bundled.

Resolves: #94938
Releases: master
Change-Id: I13f506d9c32b09b13034388908d710c284885f56
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/70684
Tested-by: core-ci <typo3@b13.com>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
---
 .../Backend/Impexp/AbstractCest.php           |  22 ++-
 .../Acceptance/Backend/Impexp/ExportCest.php  | 130 ++++++++++--------
 .../Acceptance/Backend/Impexp/ImportCest.php  |  74 ++--------
 .../Acceptance/Backend/Impexp/UsersCest.php   |  48 ++-----
 .../Classes/Controller/ExportController.php   |   2 +-
 5 files changed, 120 insertions(+), 156 deletions(-)

diff --git a/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/AbstractCest.php b/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/AbstractCest.php
index 49dcd0d01efe..d4e11db95dc3 100644
--- a/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/AbstractCest.php
+++ b/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/AbstractCest.php
@@ -22,11 +22,29 @@ use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\PageTree;
 
 /**
  * Common test helper functions
- *
- * @todo: only used once, inline to consuming class?
  */
 abstract class AbstractCest
 {
+    protected string $contextMenuMore = 'li.list-group-item-submenu';
+    protected string $contextMenuExport = '[data-callback-action=exportT3d]';
+    protected string $contextMenuImport = '[data-callback-action=importT3d]';
+
+    protected function selectInContextMenu(BackendTester $I, array $path): void
+    {
+        foreach ($path as $depth => $selector) {
+            $contextMenuId = sprintf('#contentMenu%d', $depth);
+            $I->waitForElementVisible($contextMenuId, 5);
+            $I->click($selector, $contextMenuId);
+        }
+    }
+
+    protected function waitForAjaxRequestToFinish(BackendTester $I): void
+    {
+        $I->waitForJS('return $.active == 0;', 10);
+        // sometimes rendering is still slower that ajax being finished.
+        $I->wait(0.5);
+    }
+
     protected function setPageAccess(BackendTester $I, PageTree $pageTree, array $pagePath, int $userGroupId, int $recursionLevel = 1): void
     {
         $I->switchToMainFrame();
diff --git a/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/ExportCest.php b/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/ExportCest.php
index dd9938f44fd8..236ec263e1c3 100644
--- a/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/ExportCest.php
+++ b/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/ExportCest.php
@@ -19,12 +19,13 @@ namespace TYPO3\CMS\Core\Tests\Acceptance\Backend\Impexp;
 
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Tests\Acceptance\Support\BackendTester;
+use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\ModalDialog;
 use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\PageTree;
 
 /**
  * Various export related tests
  */
-class ExportCest
+class ExportCest extends AbstractCest
 {
     /**
      * Absolute path to files that must be removed
@@ -77,22 +78,17 @@ class ExportCest
      */
     public function exportPageAndRecordsDisplaysTitleOfSelectedPageInModuleHeader(BackendTester $I): void
     {
-        $contextMenuMore = '#contentMenu0 li.list-group-item-submenu';
-        $contextMenuExport = '#contentMenu1 li.list-group-item[data-callback-action=exportT3d]';
         $selectedPageTitle = 'elements t3editor';
         $selectedPageIcon = '//*[text()=\'' . $selectedPageTitle . '\']/../*[contains(@class, \'node-icon-container\')]';
+        $buttonUpdate = '.btn[value=Update]';
 
         $I->click($selectedPageIcon);
-        $I->waitForElementVisible($contextMenuMore, 5);
-        $I->click($contextMenuMore);
-        $I->waitForElementVisible($contextMenuExport, 5);
-        $I->click($contextMenuExport);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuExport]);
         $I->switchToContentFrame();
         $I->waitForText($selectedPageTitle);
         $I->waitForElementNotVisible('#nprogress');
         $I->see($selectedPageTitle, $this->inModuleHeader);
 
-        $buttonUpdate = '.btn[value=Update]';
         $I->click($buttonUpdate, $this->inTabConfiguration);
         $this->waitForAjaxRequestToFinish($I);
         $I->see($selectedPageTitle, $this->inModuleHeader);
@@ -108,6 +104,9 @@ class ExportCest
         $rootPageTitle = 'New TYPO3 site';
         $tablePageTitle = 'elements t3editor';
         $tableTitle = 'Form engine elements - t3editor';
+        $listModuleHeader = '.module-docheader';
+        $listModuleBtnExport = 'a[title="Export"]';
+        $buttonUpdate = '.btn[value=Update]';
 
         $pageTree->openPath([$tablePageTitle]);
         $I->switchToContentFrame();
@@ -116,16 +115,12 @@ class ExportCest
         $I->waitForElementNotVisible('#nprogress');
         $I->click($tableTitle);
 
-        $listModuleHeader = '.module-docheader';
-        $listModuleBtnExport = 'a[title="Export"]';
-
         $I->waitForElementVisible($listModuleHeader . ' ' . $listModuleBtnExport, 5);
         $I->click($listModuleBtnExport, $listModuleHeader);
         $I->waitForElementVisible($this->inTabConfiguration, 5);
         $I->see($rootPageTitle, $this->inModuleHeader);
         $I->dontSee($tablePageTitle, $this->inModuleHeader);
 
-        $buttonUpdate = '.btn[value=Update]';
         $I->click($buttonUpdate, $this->inTabConfiguration);
         $this->waitForAjaxRequestToFinish($I);
         $I->see($rootPageTitle, $this->inModuleHeader);
@@ -139,12 +134,11 @@ class ExportCest
      */
     public function exportRecordDisplaysTitleOfRootPageInModuleHeader(BackendTester $I, PageTree $pageTree): void
     {
-        $contextMenuMore = '#contentMenu0 li.list-group-item-submenu';
-        $contextMenuExport = '#contentMenu1 li.list-group-item[data-callback-action=exportT3d]';
         $rootPageTitle = 'New TYPO3 site';
         $recordPageTitle = 'elements t3editor';
         $recordTable = '#recordlist-tx_styleguide_elements_t3editor';
         $recordIcon = 'tr:first-child a.t3js-contextmenutrigger';
+        $buttonUpdate = '.btn[value=Update]';
 
         $pageTree->openPath([$recordPageTitle]);
         $I->switchToContentFrame();
@@ -152,21 +146,68 @@ class ExportCest
         $I->waitForText($recordPageTitle);
         $I->waitForElementNotVisible('#nprogress');
         $I->click($recordIcon, $recordTable);
-        $I->waitForElementVisible($contextMenuMore, 5);
-        $I->click($contextMenuMore);
-        $I->waitForElementVisible($contextMenuExport, 5);
-        $I->click($contextMenuExport);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuExport]);
         $I->waitForElementVisible($this->inTabConfiguration, 5);
         $I->see($rootPageTitle, $this->inModuleHeader);
         $I->dontSee($recordPageTitle, $this->inModuleHeader);
 
-        $buttonUpdate = '.btn[value=Update]';
         $I->click($buttonUpdate, $this->inTabConfiguration);
         $this->waitForAjaxRequestToFinish($I);
         $I->see($rootPageTitle, $this->inModuleHeader);
         $I->dontSee($recordPageTitle, $this->inModuleHeader);
     }
 
+    public function saveAndDeletePresetSucceeds(BackendTester $I, ModalDialog $modalDialog): void
+    {
+        $pageTitle = 'staticdata';
+        $exportPageTitle = 'Export pagetree configuration';
+        $pageIcon = '//*[text()=\'' . $pageTitle . '\']/../*[contains(@class, \'node-icon-container\')]';
+        $tabExport = 'a[href="#export-filepreset"]';
+        $contentExport = '#export-filepreset';
+        $presetTitle = 'My First Preset';
+        $inputPresetTitle = 'input[name="tx_impexp[preset][title]"]';
+        $buttonSavePreset = 'button[name="preset[save]"]';
+        $buttonDeletePreset = 'button[name="preset[delete]"]';
+        $selectPreset = 'select[name="preset[select]"]';
+
+        $I->click($pageIcon);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuExport]);
+        $I->switchToContentFrame();
+        $I->waitForText($exportPageTitle);
+        $I->waitForElementNotVisible('#nprogress');
+
+        $I->click($tabExport, $this->inModuleTabs);
+        $I->waitForElementVisible($contentExport, 5);
+        $I->fillField($this->inModuleTabsBody . ' ' . $inputPresetTitle, $presetTitle);
+        $I->click($buttonSavePreset, $this->inModuleTabsBody);
+
+        // don't use $modalDialog->clickButtonInDialog due to too low timeout
+        $modalDialog->canSeeDialog();
+        $I->click('OK', ModalDialog::$openedModalButtonContainerSelector);
+        $I->waitForElementNotVisible(ModalDialog::$openedModalSelector, 30);
+        $this->waitForAjaxRequestToFinish($I);
+
+        $I->switchToContentFrame();
+        $I->canSeeElement($this->inFlashMessages . ' .alert.alert-info');
+        $I->canSee(sprintf('New preset "%s" is created', $presetTitle), $this->inFlashMessages . ' .alert.alert-info .alert-message');
+
+        $I->click($tabExport, $this->inModuleTabs);
+        $I->waitForElementVisible($contentExport, 5);
+        $I->selectOption($this->inModuleTabsBody . ' ' . $selectPreset, $presetTitle);
+        $I->click($buttonDeletePreset, $this->inModuleTabsBody);
+
+        // don't use $modalDialog->clickButtonInDialog due to too low timeout
+        $modalDialog->canSeeDialog();
+        $I->click('OK', ModalDialog::$openedModalButtonContainerSelector);
+        $I->waitForElementNotVisible(ModalDialog::$openedModalSelector, 30);
+        $this->waitForAjaxRequestToFinish($I);
+
+        $I->switchToContentFrame();
+        $I->canSeeElement($this->inFlashMessages . ' .alert.alert-info');
+        $flashMessage = $I->grabTextFrom($this->inFlashMessages . ' .alert.alert-info .alert-message');
+        $I->assertMatchesRegularExpression('/Preset #[0-9]+ deleted!/', $flashMessage);
+    }
+
     /**
      * @param BackendTester $I
      *
@@ -179,22 +220,16 @@ class ExportCest
         $pageTitle = 'staticdata';
         $exportPageTitle = 'Export pagetree configuration';
         $pageIcon = '//*[text()=\'' . $pageTitle . '\']/../*[contains(@class, \'node-icon-container\')]';
-        $contextMenuMore = '#contentMenu0 li.list-group-item-submenu';
-        $contextMenuExport = '#contentMenu1 li.list-group-item[data-callback-action=exportT3d]';
-
-        $I->click($pageIcon);
-        $I->waitForElementVisible($contextMenuMore, 5);
-        $I->click($contextMenuMore);
-        $I->waitForElementVisible($contextMenuExport, 5);
-        $I->click($contextMenuExport);
-
         $tabExport = 'a[href="#export-filepreset"]';
         $contentExport = '#export-filepreset';
         $buttonSaveToFile = 'tx_impexp[save_export]';
 
+        $I->click($pageIcon);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuExport]);
         $I->switchToContentFrame();
         $I->waitForText($exportPageTitle);
         $I->waitForElementNotVisible('#nprogress');
+
         $I->cantSee('No tree exported - only tables on the page.', $this->inModuleTabsBody);
         $I->see('Inside pagetree', $this->inModulePreview);
         $I->dontSee('Outside pagetree', $this->inModulePreview);
@@ -224,24 +259,22 @@ class ExportCest
         $rootPage = '.node.identifier-0_0 .node-name';
         $rootPageTitle = 'New TYPO3 site';
         $sysLanguageTableTitle = 'Website Language';
+        $listModuleHeader = '.module-docheader';
+        $listModuleBtnExport = 'a[title="Export"]';
+        $tabExport = 'a[href="#export-filepreset"]';
+        $contentExport = '#export-filepreset';
+        $buttonSaveToFile = 'tx_impexp[save_export]';
 
         $I->canSeeElement($rootPage);
         $I->click($rootPage);
         $I->switchToContentFrame();
         $I->waitForText($rootPageTitle);
         $I->waitForElementNotVisible('#nprogress');
-        $I->click($sysLanguageTableTitle);
-
-        $listModuleHeader = '.module-docheader';
-        $listModuleBtnExport = 'a[title="Export"]';
 
+        $I->click($sysLanguageTableTitle);
         $I->waitForElementVisible($listModuleHeader . ' ' . $listModuleBtnExport, 5);
         $I->click($listModuleBtnExport, $listModuleHeader);
 
-        $tabExport = 'a[href="#export-filepreset"]';
-        $contentExport = '#export-filepreset';
-        $buttonSaveToFile = 'tx_impexp[save_export]';
-
         $I->waitForElementVisible($tabExport, 5);
         $I->canSee('No tree exported - only tables on the page.', $this->inModuleTabsBody);
         $I->canSee('Export tables from pages', $this->inModuleTabsBody);
@@ -274,8 +307,9 @@ class ExportCest
         $rootPageTitle = 'New TYPO3 site';
         $sysLanguageTable = '#recordlist-sys_language';
         $sysLanguageIcon = 'tr:first-child a.t3js-contextmenutrigger';
-        $contextMenuMore = '#contentMenu0 li.list-group-item-submenu';
-        $contextMenuExport = '#contentMenu1 li.list-group-item[data-callback-action=exportT3d]';
+        $tabExport = 'a[href="#export-filepreset"]';
+        $contentExport = '#export-filepreset';
+        $buttonSaveToFile = 'tx_impexp[save_export]';
 
         // select root page in list module
         $I->canSeeElement($rootPage);
@@ -284,15 +318,7 @@ class ExportCest
         $I->waitForText($rootPageTitle);
         $I->waitForElementNotVisible('#nprogress');
         $I->click($sysLanguageIcon, $sysLanguageTable);
-        $I->waitForElementVisible($contextMenuMore, 5);
-        $I->click($contextMenuMore);
-        $I->waitForText('Export');
-        $I->waitForElementVisible($contextMenuExport, 5);
-        $I->click($contextMenuExport);
-
-        $tabExport = 'a[href="#export-filepreset"]';
-        $contentExport = '#export-filepreset';
-        $buttonSaveToFile = 'tx_impexp[save_export]';
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuExport]);
 
         $I->waitForElementVisible($tabExport, 5);
         $I->canSee('No tree exported - only tables on the page.', $this->inModuleTabsBody);
@@ -312,14 +338,4 @@ class ExportCest
 
         $this->testFilesToDelete[] = $saveFilePath;
     }
-
-    /**
-     * @param BackendTester $I
-     */
-    protected function waitForAjaxRequestToFinish(BackendTester $I): void
-    {
-        $I->waitForJS('return $.active == 0;', 10);
-        // sometimes rendering is still slower that ajax being finished.
-        $I->wait(0.5);
-    }
 }
diff --git a/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/ImportCest.php b/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/ImportCest.php
index ab40303436b2..46ec239eed7c 100644
--- a/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/ImportCest.php
+++ b/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/ImportCest.php
@@ -25,7 +25,7 @@ use TYPO3\CMS\Core\Tests\Acceptance\Support\Helper\PageTree;
 /**
  * Various import related tests
  */
-class ImportCest
+class ImportCest extends AbstractCest
 {
     /**
      * Absolute path to files that must be removed
@@ -42,8 +42,6 @@ class ImportCest
     protected $inTabImport = '#import-import';
     protected $inFlashMessages = '.typo3-messages';
 
-    protected $contextMenuMore = '#contentMenu0 li.list-group-item-submenu';
-    protected $contextMenuImport = '#contentMenu1 li.list-group-item[data-callback-action=importT3d]';
     protected $tabUpload = 'a[href="#import-upload"]';
     protected $tabMessages = 'a[href="#import-errors"]';
     protected $inputUploadFile = 'input[type=file]';
@@ -90,11 +88,9 @@ class ImportCest
     {
         $pageInPageTreeTitle = 'elements t3editor';
         $pageInPageTreeIcon = '//*[text()=\'' . $pageInPageTreeTitle . '\']/../*[contains(@class, \'node-icon-container\')]';
+
         $I->click($pageInPageTreeIcon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->see($pageInPageTreeTitle, $this->inModuleHeader);
 
@@ -107,15 +103,10 @@ class ImportCest
     {
         $page1Title = 'styleguide TCA demo';
         $page1Icon = '//*[text()=\'' . $page1Title . '\']/../*[contains(@class, \'node-icon-container\')]';
-
-        $I->click($page1Icon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
-
         $fixtureFilePath = 'Acceptance/Backend/Impexp/Fixtures/404_page_and_records.xml';
 
+        $I->click($page1Icon);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->waitForElementVisible($this->tabUpload);
         $I->click($this->tabUpload, $this->inModuleTabs);
@@ -163,15 +154,10 @@ class ImportCest
     {
         $page1Title = 'styleguide TCA demo';
         $page1Icon = '//*[text()=\'' . $page1Title . '\']/../*[contains(@class, \'node-icon-container\')]';
-
-        $I->click($page1Icon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
-
         $fixtureFilePath = 'Acceptance/Backend/Impexp/Fixtures/unsupported.json';
 
+        $I->click($page1Icon);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->waitForElementVisible($this->tabUpload);
         $I->click($this->tabUpload, $this->inModuleTabs);
@@ -198,6 +184,7 @@ class ImportCest
         $sysCategoryTable = '#recordlist-sys_category';
         $page1Title = 'styleguide TCA demo';
         $page1Icon = '//*[text()=\'' . $page1Title . '\']/../*[contains(@class, \'node-icon-container\')]';
+        $fixtureFilePath = 'Acceptance/Backend/Impexp/Fixtures/sys_category_table_with_bootstrap_package.xml';
 
         $I->switchToContentFrame();
         $I->waitForText($page1Title);
@@ -205,13 +192,7 @@ class ImportCest
         $I->switchToMainFrame();
 
         $I->click($page1Icon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
-
-        $fixtureFilePath = 'Acceptance/Backend/Impexp/Fixtures/sys_category_table_with_bootstrap_package.xml';
-
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->waitForElementVisible($this->tabUpload);
         $I->click($this->tabUpload, $this->inModuleTabs);
@@ -254,15 +235,10 @@ class ImportCest
 
         $page1Title = 'styleguide TCA demo';
         $page1Icon = '//*[text()=\'' . $page1Title . '\']/../*[contains(@class, \'node-icon-container\')]';
-
-        $I->click($page1Icon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
-
         $fixtureFilePath = 'Acceptance/Backend/Impexp/Fixtures/404_page_and_records.xml';
 
+        $I->click($page1Icon);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->waitForElementVisible($this->tabUpload);
         $I->click($this->tabUpload, $this->inModuleTabs);
@@ -303,6 +279,7 @@ class ImportCest
         $sysCategoryTable = '#recordlist-sys_category';
         $page1Title = 'styleguide TCA demo';
         $page1Icon = '//*[text()=\'' . $page1Title . '\']/../*[contains(@class, \'node-icon-container\')]';
+        $fixtureFilePath = 'Acceptance/Backend/Impexp/Fixtures/sys_category_table.xml';
 
         $I->switchToContentFrame();
         $I->waitForText($page1Title);
@@ -310,13 +287,7 @@ class ImportCest
         $I->switchToMainFrame();
 
         $I->click($page1Icon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
-
-        $fixtureFilePath = 'Acceptance/Backend/Impexp/Fixtures/sys_category_table.xml';
-
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->waitForElementVisible($this->tabUpload);
         $I->click($this->tabUpload, $this->inModuleTabs);
@@ -360,6 +331,7 @@ class ImportCest
         $sysCategoryTable = '#recordlist-sys_category';
         $page1Title = 'styleguide TCA demo';
         $page1Icon = '//*[text()=\'' . $page1Title . '\']/../*[contains(@class, \'node-icon-container\')]';
+        $fixtureFilePath = 'Acceptance/Backend/Impexp/Fixtures/sys_category_record.xml';
 
         $I->switchToContentFrame();
         $I->waitForText($page1Title);
@@ -367,13 +339,7 @@ class ImportCest
         $I->switchToMainFrame();
 
         $I->click($page1Icon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
-
-        $fixtureFilePath = 'Acceptance/Backend/Impexp/Fixtures/sys_category_record.xml';
-
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->waitForElementVisible($this->tabUpload);
         $I->click($this->tabUpload, $this->inModuleTabs);
@@ -402,14 +368,4 @@ class ImportCest
         $sysCategoryRecordsNew = array_diff($sysCategoryRecords, $sysCategoryRecordsBefore);
         $I->assertCount(1, $sysCategoryRecordsNew);
     }
-
-    /**
-     * @param BackendTester $I
-     */
-    protected function waitForAjaxRequestToFinish(BackendTester $I): void
-    {
-        $I->waitForJS('return $.active == 0;', 10);
-        // sometimes rendering is still slower that ajax being finished.
-        $I->wait(0.5);
-    }
 }
diff --git a/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/UsersCest.php b/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/UsersCest.php
index 0ce533febbd9..2cbaac099716 100644
--- a/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/UsersCest.php
+++ b/typo3/sysext/core/Tests/Acceptance/Backend/Impexp/UsersCest.php
@@ -32,9 +32,6 @@ class UsersCest extends AbstractCest
 
     protected $buttonUser = '#typo3-cms-backend-backend-toolbaritems-usertoolbaritem';
     protected $buttonLogout = '#typo3-cms-backend-backend-toolbaritems-usertoolbaritem button.btn.btn-danger';
-    protected $contextMenuMore = '#contentMenu0 li.list-group-item-submenu';
-    protected $contextMenuExport = '#contentMenu1 li.list-group-item[data-callback-action=exportT3d]';
-    protected $contextMenuImport = '#contentMenu1 li.list-group-item[data-callback-action=importT3d]';
     protected $buttonViewPage = 'span[data-identifier="actions-view-page"]';
     protected $tabUpload = 'a[href="#import-upload"]';
     protected $checkboxForceAllUids = 'input#checkForce_all_UIDS';
@@ -66,9 +63,8 @@ class UsersCest extends AbstractCest
         $I->useExistingSession('editor');
 
         $I->click($selectedPageIcon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuExport, 5);
+        $this->selectInContextMenu($I, [$this->contextMenuMore]);
+        $I->waitForElementVisible('#contentMenu1', 5);
         $I->seeElement($this->contextMenuExport);
         $I->dontSeeElement($this->contextMenuImport);
 
@@ -89,9 +85,8 @@ class UsersCest extends AbstractCest
         $I->useExistingSession('editor');
 
         $I->click($selectedPageIcon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuExport, 5);
+        $this->selectInContextMenu($I, [$this->contextMenuMore]);
+        $I->waitForElementVisible('#contentMenu1', 5);
         $I->seeElement($this->contextMenuExport);
         $I->seeElement($this->contextMenuImport);
 
@@ -110,20 +105,14 @@ class UsersCest extends AbstractCest
         $importPageSectionTitle = 'Select file to import';
 
         $I->click($selectedPageIcon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->seeElement($this->checkboxForceAllUids);
 
         $I->useExistingSession('editor');
 
         $I->click($selectedPageIcon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->waitForText($importPageSectionTitle);
         $I->dontSeeElement($this->checkboxForceAllUids);
@@ -143,10 +132,7 @@ class UsersCest extends AbstractCest
         $importPageSectionTitle = 'Select file to import';
 
         $I->click($selectedPageIcon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->see('From path:', $this->inModuleTabsBody);
         $I->seeElement($this->inModuleTabs . ' ' . $this->tabUpload);
@@ -154,10 +140,7 @@ class UsersCest extends AbstractCest
         $I->useExistingSession('editor');
 
         $I->click($selectedPageIcon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuImport, 5);
-        $I->click($this->contextMenuImport);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->waitForText($importPageSectionTitle);
         $I->dontSee('From path:', $this->inModuleTabsBody);
@@ -182,10 +165,7 @@ class UsersCest extends AbstractCest
         $importPageSectionTitle = 'Select file to import';
 
         $I->click($this->inPageTree . ' .node.identifier-0_0 .node-icon-container');
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuExport, 5);
-        $I->click($this->contextMenuImport);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->waitForText($importPageSectionTitle);
         $I->dontSeeElement($this->inModuleHeader . ' ' . $this->buttonViewPage);
@@ -194,10 +174,7 @@ class UsersCest extends AbstractCest
 
         $I->click('List');
         $I->click($selectedPageIcon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuExport, 5);
-        $I->click($this->contextMenuImport);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->seeElement($this->inModuleHeader . ' ' . $this->buttonViewPage);
 
@@ -207,10 +184,7 @@ class UsersCest extends AbstractCest
         $I->useExistingSession('editor');
 
         $I->click($selectedPageIcon);
-        $I->waitForElementVisible($this->contextMenuMore, 5);
-        $I->click($this->contextMenuMore);
-        $I->waitForElementVisible($this->contextMenuExport, 5);
-        $I->click($this->contextMenuImport);
+        $this->selectInContextMenu($I, [$this->contextMenuMore, $this->contextMenuImport]);
         $I->switchToContentFrame();
         $I->seeElement($this->inModuleHeader . ' ' . $this->buttonViewPage);
 
diff --git a/typo3/sysext/impexp/Classes/Controller/ExportController.php b/typo3/sysext/impexp/Classes/Controller/ExportController.php
index 2700f3b992be..73bf7a8e6312 100644
--- a/typo3/sysext/impexp/Classes/Controller/ExportController.php
+++ b/typo3/sysext/impexp/Classes/Controller/ExportController.php
@@ -99,7 +99,7 @@ class ExportController extends ImportExportController
         parent::main($request);
 
         // Input data
-        $presetAction = $request->getQueryParams()['preset'] ?? [];
+        $presetAction = $request->getParsedBody()['preset'] ?? [];
         $inData = $request->getParsedBody()['tx_impexp'] ?? $request->getQueryParams()['tx_impexp'] ?? [];
         $inData = $this->preprocessInputData($inData);
 
-- 
GitLab