Skip to content

Commit d560bae

Browse files
authored
Merge pull request #229 from magento-obsessive-owls/cms-team-1-delivery
[Owls] Regression Delivery
2 parents e8da8ad + 7635f6e commit d560bae

File tree

80 files changed

+821
-157
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+821
-157
lines changed

app/code/Magento/PageBuilder/Plugin/Filter/TemplatePlugin.php

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
*/
1313
class TemplatePlugin
1414
{
15-
const DATA_BACKGROUND_IMAGE = 'data-background-images';
15+
const BACKGROUND_IMAGE_PATTERN = '/data-background-images/si';
16+
17+
const HTML_CONTENT_TYPE_PATTERN = '/data-content-type="html"/si';
1618

1719
/**
1820
* @var \Magento\Framework\View\ConfigInterface
@@ -29,16 +31,24 @@ class TemplatePlugin
2931
*/
3032
private $domDocument;
3133

34+
/**
35+
* @var \Magento\Framework\Math\Random
36+
*/
37+
private $mathRandom;
38+
3239
/**
3340
* @param \Psr\Log\LoggerInterface $logger
3441
* @param \Magento\Framework\View\ConfigInterface $viewConfig
42+
* @param \Magento\Framework\Math\Random $mathRandom
3543
*/
3644
public function __construct(
3745
\Psr\Log\LoggerInterface $logger,
38-
\Magento\Framework\View\ConfigInterface $viewConfig
46+
\Magento\Framework\View\ConfigInterface $viewConfig,
47+
\Magento\Framework\Math\Random $mathRandom
3948
) {
4049
$this->logger = $logger;
4150
$this->viewConfig = $viewConfig;
51+
$this->mathRandom = $mathRandom;
4252
}
4353

4454
/**
@@ -55,15 +65,15 @@ public function afterFilter(\Magento\Framework\Filter\Template $subject, string
5565
$this->domDocument = false;
5666

5767
// Validate if the filtered result requires background image processing
58-
if (strpos($result, self::DATA_BACKGROUND_IMAGE) !== false) {
68+
if (preg_match(self::BACKGROUND_IMAGE_PATTERN, $result)) {
5969
$document = $this->getDomDocument($result);
6070
$this->generateBackgroundImageStyles($document);
6171
}
6272

6373
// Process any HTML content types, they need to be decoded on the front-end
64-
if (strpos($result, 'data-content-type="html"') !== false) {
74+
if (preg_match(self::HTML_CONTENT_TYPE_PATTERN, $result)) {
6575
$document = $this->getDomDocument($result);
66-
$this->decodeHtmlContentTypes($document);
76+
$uniqueNodeNameToDecodedOuterHtmlMap = $this->generateDecodedHtmlPlaceholderMappingInDocument($document);
6777
}
6878

6979
// If a document was retrieved we've modified the output so need to retrieve it from within the document
@@ -75,7 +85,21 @@ public function afterFilter(\Magento\Framework\Filter\Template $subject, string
7585
$matches
7686
);
7787

78-
return !empty($matches) ? $matches[1] : $result;
88+
if (!empty($matches)) {
89+
$docHtml = $matches[1];
90+
91+
if (isset($uniqueNodeNameToDecodedOuterHtmlMap)) {
92+
foreach ($uniqueNodeNameToDecodedOuterHtmlMap as $uniqueNodeName => $decodedOuterHtml) {
93+
$docHtml = str_replace(
94+
'<' . $uniqueNodeName . '>' . '</' . $uniqueNodeName . '>',
95+
$decodedOuterHtml,
96+
$docHtml
97+
);
98+
}
99+
}
100+
101+
$result = $docHtml;
102+
}
79103
}
80104

81105
return $result;
@@ -129,31 +153,48 @@ function ($errorNumber, $errorString) {
129153
}
130154

131155
/**
132-
* Decode the contents of any HTML content types for the store front
156+
* Convert encoded HTML content types to placeholders and generate decoded outer html map for future replacement
133157
*
134158
* @param \DOMDocument $document
159+
* @return array - map of unique node name to decoded html
135160
*/
136-
private function decodeHtmlContentTypes(\DOMDocument $document): void
161+
private function generateDecodedHtmlPlaceholderMappingInDocument(\DOMDocument $document): array
137162
{
138163
$xpath = new \DOMXPath($document);
139-
$nodes = $xpath->query('//*[@data-content-type="html" and not(@data-decoded="true")]');
140-
foreach ($nodes as $node) {
141-
if (strlen(trim($node->nodeValue)) > 0) {
142-
/* @var \DOMElement $node */
143-
$fragment = $document->createDocumentFragment();
144-
$fragment->appendXML($node->nodeValue);
145-
// Store a decoded attribute on the element so we don't double decode
146-
$node->setAttribute("data-decoded", "true");
147-
$node->nodeValue = "";
148-
149-
// If the HTML code in the content type is invalid it may throw
150-
try {
151-
$node->appendChild($fragment);
152-
} catch (\Exception $e) {
153-
$this->logger->critical($e);
154-
}
164+
165+
// construct xpath query to fetch top-level ancestor html content type nodes
166+
/** @var $htmlContentTypeNodes \DOMNode[] */
167+
$htmlContentTypeNodes = $xpath->query(
168+
'//*[@data-content-type="html" and not(@data-decoded="true")]' .
169+
'[not(ancestor::*[@data-content-type="html"])]'
170+
);
171+
172+
$uniqueNodeNameToDecodedOuterHtmlMap = [];
173+
174+
foreach ($htmlContentTypeNodes as $htmlContentTypeNode) {
175+
// Set decoded attribute on all encoded html content types so we don't double decode;
176+
$htmlContentTypeNode->setAttribute('data-decoded', 'true');
177+
178+
// if nothing exists inside the node, continue
179+
if (!strlen(trim($htmlContentTypeNode->nodeValue))) {
180+
continue;
155181
}
182+
183+
$preDecodedOuterHtml = $document->saveHTML($htmlContentTypeNode);
184+
$decodedOuterHtml = html_entity_decode($preDecodedOuterHtml);
185+
186+
// generate unique node name element to replace with decoded html contents at end of processing;
187+
// goal is to create a document as few times as possible to prevent inadvertent parsing of contents as html
188+
// by the dom library
189+
$uniqueNodeName = $this->mathRandom->getRandomString(32, $this->mathRandom::CHARS_LOWERS);
190+
191+
$uniqueNode = new \DOMElement($uniqueNodeName);
192+
$htmlContentTypeNode->parentNode->replaceChild($uniqueNode, $htmlContentTypeNode);
193+
194+
$uniqueNodeNameToDecodedOuterHtmlMap[$uniqueNodeName] = $decodedOuterHtml;
156195
}
196+
197+
return $uniqueNodeNameToDecodedOuterHtmlMap;
157198
}
158199

159200
/**
@@ -164,10 +205,10 @@ private function decodeHtmlContentTypes(\DOMDocument $document): void
164205
private function generateBackgroundImageStyles(\DOMDocument $document) : void
165206
{
166207
$xpath = new \DOMXPath($document);
167-
$nodes = $xpath->query('//*[@' . self:: DATA_BACKGROUND_IMAGE . ']');
208+
$nodes = $xpath->query('//*[@data-background-images]');
168209
foreach ($nodes as $node) {
169210
/* @var \DOMElement $node */
170-
$backgroundImages = $node->attributes->getNamedItem(self:: DATA_BACKGROUND_IMAGE);
211+
$backgroundImages = $node->attributes->getNamedItem('data-background-images');
171212
if ($backgroundImages->nodeValue !== '') {
172213
$elementClass = uniqid('background-image-');
173214
$images = json_decode(stripslashes($backgroundImages->nodeValue), true);

app/code/Magento/PageBuilder/Test/Mftf/ActionGroup/AdminActionGroup.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,25 @@
88

99
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1010
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="navigateToCMSPage">
12+
<!-- This goes in CE repo -->
13+
<arguments>
14+
<argument name="CMSPage"/>
15+
</arguments>
16+
<amOnPage url="{{CmsPagesPage.url}}" stepKey="navigateToCMSPagesGrid"/>
17+
<waitForPageLoad stepKey="waitForPageLoad1"/>
18+
<conditionalClick selector="{{CmsPagesPageActionsSection.clearAllButton}}" dependentSelector="{{CmsPagesPageActionsSection.activeFilters}}" visible="true" stepKey="clickToResetFilter"/>
19+
<waitForPageLoad stepKey="waitForGridLoad"/>
20+
<conditionalClick selector="//div[contains(@data-role, 'grid-wrapper')]/table/thead/tr/th/span[contains(text(), 'ID')]" dependentSelector="//span[contains(text(), 'ID')]/parent::th[not(contains(@class, '_descend'))]/parent::tr/parent::thead/parent::table/parent::div[contains(@data-role, 'grid-wrapper')]" visible="true" stepKey="clickToAttemptSortByIdDescending"/>
21+
<waitForPageLoad stepKey="waitForFirstIdSortDescendingToFinish"/>
22+
<!-- Conditional Click again in case it goes from default state to ascending on first click -->
23+
<conditionalClick selector="//div[contains(@data-role, 'grid-wrapper')]/table/thead/tr/th/span[contains(text(), 'ID')]" dependentSelector="//span[contains(text(), 'ID')]/parent::th[not(contains(@class, '_descend'))]/parent::tr/parent::thead/parent::table/parent::div[contains(@data-role, 'grid-wrapper')]" visible="true" stepKey="secondClickToAttemptSortByIdDescending"/>
24+
<waitForPageLoad stepKey="waitForSecondIdSortDescendingToFinish"/>
25+
<click selector="{{CmsPagesPageActionsSection.select(CMSPage.identifier)}}" stepKey="clickSelectCreatedCMSPage"/>
26+
<click selector="{{CmsPagesPageActionsSection.edit(CMSPage.identifier)}}" stepKey="navigateToCreatedCMSPage"/>
27+
<waitForPageLoad stepKey="waitForPageLoad2"/>
28+
<seeElement selector="{{CmsNewPagePageContentSection.header}}" stepKey="seeContentSectionHeaderForPage"/>
29+
</actionGroup>
1130
<actionGroup name="navigateToAPageWithPageBuilder">
1231
<waitForPageLoad stepKey="waitForDashboardPageLoad"/>
1332
<amOnPage url="{{CmsPagesPage.url}}/new" stepKey="amOnPageBuilderPage"/>

app/code/Magento/PageBuilder/Test/Mftf/ActionGroup/ContentTypeButtonActionGroup.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
<comment userInput="inlineEditButton" stepKey="comment"/>
3434
<waitForElementVisible selector="{{ButtonItemOnStage.base(index)}}" stepKey="waitForButton"/>
3535
<waitForElementVisible selector="{{ButtonItemOnStage.editableButtonItemElement(index)}}" stepKey="waitForButtonEditable"/>
36-
<fillField selector="{{ButtonItemOnStage.editableButtonItemElement(index)}}" userInput="{{text.value}}" stepKey="enterButtonText"/>
36+
<pressKey selector="{{ButtonItemOnStage.editableButtonItemElement(index)}}" userInput="{{text.value}}" stepKey="enterButtonText"/>
3737
<waitForPageLoad stepKey="waitForPageLoad"/>
3838
<seeElement selector="{{ButtonItemOnStage.buttonItemText(index, text.value)}}" stepKey="seeButtonText"/>
3939
<click selector="{{pageBuilderArea}}{{PageBuilderPanel.searchPanel}}" stepKey="unFocusLiveEdit"/>

app/code/Magento/PageBuilder/Test/Mftf/Data/SlideData.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
<data key="fieldName">slide_name</data>
2828
<data key="value">Slide 2 Name</data>
2929
</entity>
30+
<entity name="PageBuilderSlideItemSlideName_Slide3" type="pagebuilder_slide_item_slide_name_property">
31+
<data key="name">Name</data>
32+
<data key="section">appearance_fieldset</data>
33+
<data key="fieldName">slide_name</data>
34+
<data key="value">Slide 3 Name</data>
35+
</entity>
3036
<entity name="PageBuilderSlideItemSlideName_HtmlCode" type="pagebuilder_slide_item_slide_name_property">
3137
<data key="name">Name</data>
3238
<data key="section">appearance_fieldset</data>
@@ -232,6 +238,12 @@
232238
<data key="fieldName">content</data>
233239
<data key="value">Slide 2 Content</data>
234240
</entity>
241+
<entity name="PageBuilderSlideItemContent_Slide3" type="pagebuilder_slide_item_content_property">
242+
<data key="name">Content</data>
243+
<data key="section">general</data>
244+
<data key="fieldName">content</data>
245+
<data key="value">Slide 3 Content</data>
246+
</entity>
235247
<entity name="PageBuilderSlideItemMessage_Empty" type="pagebuilder_slide_item_message_property">
236248
<data key="name">Message Text</data>
237249
<data key="section">contents</data>

app/code/Magento/PageBuilder/Test/Mftf/Section/CatalogSection.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,8 @@
2121
<element name="related" type="button" selector=".block.related"/>
2222
<element name="upsell" type="button" selector=".block.upsell"/>
2323
</section>
24+
<section name="CategoryContentSection">
25+
<!-- This goes in CE repo -->
26+
<element name="descriptionTextArea" type="text" selector="#category_form_description"/>
27+
</section>
2428
</sections>

app/code/Magento/PageBuilder/Test/Mftf/Test/AdminCatalogProductPageBuilder.xml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,4 +1298,75 @@
12981298
<seeElement selector="{{HeadingOnStorefront.headingType(PageBuilderHeadingTypeProperty_H1.value, '1')}}" stepKey="seeHeadingStyleStorefront"/>
12991299
<seeElement selector="{{HeadingOnStorefront.headingText(PageBuilderHeadingTypeProperty_H1.value, PageBuilderHeadingTextProperty.value, '1')}}" stepKey="seeHeadingTextStorefront"/>
13001300
</test>
1301+
<test name="HtmlAddToCatalogProduct">
1302+
<annotations>
1303+
<features value="PageBuilder"/>
1304+
<stories value="Catalog Products"/>
1305+
<title value="HTML code add to catalog product"/>
1306+
<description value="Verify adding HTML code to catalog product is rendered correctly"/>
1307+
<severity value="CRITICAL"/>
1308+
<useCaseId value="MC-14970"/>
1309+
<testCaseId value="MC-14976"/>
1310+
<group value="pagebuilder"/>
1311+
<group value="pagebuilder-html"/>
1312+
<group value="pagebuilder-column"/>
1313+
<group value="pagebuilder-catalog-product"/>
1314+
</annotations>
1315+
<before>
1316+
<createData entity="_defaultCategory" stepKey="createPreReqCategory"/>
1317+
<createData entity="_defaultProduct" stepKey="createProduct">
1318+
<requiredEntity createDataKey="createPreReqCategory"/>
1319+
</createData>
1320+
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
1321+
<actionGroup ref="navigateToCreatedProductEditPage" stepKey="navigateToCreatedProductEditPage">
1322+
<argument name="product" value="$$createProduct$$"/>
1323+
</actionGroup>
1324+
<actionGroup ref="expandAdminProductSection" stepKey="expandAdminProductSection"/>
1325+
<actionGroup ref="openPageBuilderForAttribute" stepKey="openPageBuilderForDescription"/>
1326+
</before>
1327+
<after>
1328+
<deleteData createDataKey="createProduct" stepKey="deleteCreatedProduct"/>
1329+
<deleteData createDataKey="createPreReqCategory" stepKey="deleteCreatedCategory"/>
1330+
<actionGroup ref="NavigateToAndResetProductGridToDefaultView" stepKey="NavigateToAndResetProductGridToDefaultView"/>
1331+
<actionGroup ref="logout" stepKey="logout"/>
1332+
</after>
1333+
<actionGroup ref="expandPageBuilderPanelMenuSection" stepKey="expandMenuSectionMedia">
1334+
<argument name="contentType" value="PageBuilderHtmlContentType"/>
1335+
</actionGroup>
1336+
<actionGroup ref="dragContentTypeToStage" stepKey="dragHtmlIntoStage">
1337+
<argument name="contentType" value="PageBuilderHtmlContentType"/>
1338+
</actionGroup>
1339+
<actionGroup ref="openPageBuilderEditPanel" stepKey="openEditAfterDrop">
1340+
<argument name="contentType" value="PageBuilderHtmlContentType"/>
1341+
</actionGroup>
1342+
<!-- Update Edit Panel -->
1343+
<comment userInput="Update Edit Panel" stepKey="commentEdit"/>
1344+
<actionGroup ref="fillSlideOutPanelTextArea" stepKey="enterHtmlContent">
1345+
<argument name="property" value="PageBuilderHtmlPropertyButton"/>
1346+
</actionGroup>
1347+
<actionGroup ref="saveEditPanelSettingsFullScreen" stepKey="saveEditFormForSlide"/>
1348+
<!-- Validate Stage -->
1349+
<comment userInput="Validate Stage" stepKey="commentValidateStage"/>
1350+
<waitForElementVisible selector="{{HtmlOnStage.base('1')}}" stepKey="waitForHtmlBaseStage"/>
1351+
<seeElement selector="{{HtmlOnStage.html('1', PageBuilderHtmlPropertyButton.selector)}}" stepKey="seeHtmlOnStage"/>
1352+
<!-- Save Product -->
1353+
<comment userInput="Save Product" stepKey="commentSaveProduct"/>
1354+
<actionGroup ref="exitPageBuilderFullScreen" stepKey="exitPageBuilderFullScreen"/>
1355+
<actionGroup ref="saveProductForm" stepKey="saveProduct"/>
1356+
<waitForPageLoad stepKey="waitForPageLoadSaveProduct"/>
1357+
<actionGroup ref="expandAdminProductSection" stepKey="expandAdminProductSection"/>
1358+
<actionGroup ref="openPageBuilderForAttribute" stepKey="openPageBuilderForDescription"/>
1359+
<!-- Validate Stage After Save -->
1360+
<comment userInput="Validate Stage After Save" stepKey="commentValidateStageAfterSave"/>
1361+
<waitForElementVisible selector="{{HtmlOnStage.base('1')}}" stepKey="waitForHtmlBaseStageAfterSave"/>
1362+
<seeElement selector="{{HtmlOnStage.html('1', PageBuilderHtmlPropertyButton.selector)}}" stepKey="seeHtmlOnStageAfterSave"/>
1363+
<!-- Validate Storefront -->
1364+
<comment userInput="Validate Storefront" stepKey="commentValidateStorefront"/>
1365+
<actionGroup ref="navigateToStorefrontForCreatedPage" stepKey="navigateToProductStorefront">
1366+
<argument name="page" value="$$createProduct.name$$.html"/>
1367+
</actionGroup>
1368+
<scrollTo selector="{{StorefrontProductInfoMainSection.productDescription}}" stepKey="scrollToProductDescription"/>
1369+
<waitForElementVisible selector="{{HtmlOnStorefront.base('1')}}" stepKey="waitForHtmlBaseStageStorefront"/>
1370+
<seeElement selector="{{HtmlOnStorefront.html('1', PageBuilderHtmlPropertyButton.selectorOnFrontend)}}" stepKey="seeHtmlOnStorefront"/>
1371+
</test>
13011372
</tests>

app/code/Magento/PageBuilder/Test/Mftf/Test/AdminDisablePageBuilderCMSBlockTests.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,12 @@
8181
<actionGroup ref="logout" stepKey="logout"/>
8282
</after>
8383
<seeElement selector="{{PageBuilderStage.stageWrapper}}" stepKey="seeElementPageBuilderStage"/>
84+
<dontSeeElementInDOM selector="{{CmsNewBlockBlockBasicFieldsSection.content_textarea}}" stepKey="dontSeeContentAreaInDOM"/>
8485
<magentoCLI command="config:set cms/pagebuilder/enabled 0" stepKey="disablePageBuilder"/>
8586
<actionGroup ref="navigateToCreatedCMSBlockPage" stepKey="navigateToCreatedCMSBlockPage">
8687
<argument name="CMSBlockPage" value="$$createPreReqBlock$$"/>
8788
</actionGroup>
89+
<seeElementInDOM selector="{{CmsNewBlockBlockBasicFieldsSection.content_textarea}}" stepKey="seeContentAreaInDOM"/>
8890
<dontSeeElementInDOM selector="{{PageBuilderStage.stageWrapper}}" stepKey="dontSeePageBuilderStage"/>
8991
</test>
9092
</tests>

app/code/Magento/PageBuilder/Test/Mftf/Test/AdminDisablePageBuilderCMSPageTests.xml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,4 +111,41 @@
111111
<magentoCLI command="config:set cms/pagebuilder/enabled 1" stepKey="enablePageBuilder" after="disableWYSIWYG"/>
112112
</after>
113113
</test>
114+
<test name="PageBuilderCmsPageDisablePageBuilder">
115+
<annotations>
116+
<features value="PageBuilder"/>
117+
<stories value="CMS Page"/>
118+
<title value="Verify PageBuilder does not appear when disabled in CMS Page"/>
119+
<description value="This test is intended to ensure that PageBuilder does not appear when disabled for CMS Page."/>
120+
<severity value="CRITICAL"/>
121+
<useCaseId value="MC-5773"/>
122+
<testCaseId value="MC-14965"/>
123+
<group value="pagebuilder"/>
124+
<group value="pagebuilder-disable"/>
125+
<group value="pagebuilder-cms-page"/>
126+
</annotations>
127+
<before>
128+
<createData entity="_emptyCmsPage" stepKey="createCMSPage"/>
129+
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
130+
<actionGroup ref="navigateToCMSPage" stepKey="navigateToCMSPage">
131+
<argument name="CMSPage" value="$$createCMSPage$$"/>
132+
</actionGroup>
133+
<actionGroup ref="switchToPageBuilderStage" stepKey="switchToPageBuilderStage"/>
134+
</before>
135+
<after>
136+
<magentoCLI command="config:set cms/pagebuilder/enabled 1" stepKey="enablePageBuilder"/>
137+
<deleteData createDataKey="createCMSPage" stepKey="deleteCMSPage"/>
138+
<actionGroup ref="logout" stepKey="logout"/>
139+
</after>
140+
<seeElement selector="{{PageBuilderStage.stageWrapper}}" stepKey="seeElementPageBuilderStage"/>
141+
<dontSeeElementInDOM selector="{{CmsNewPagePageContentSection.content}}" stepKey="dontSeeContentAreaInDOM"/>
142+
<magentoCLI command="config:set cms/pagebuilder/enabled 0" stepKey="disablePageBuilder"/>
143+
<actionGroup ref="navigateToCMSPage" stepKey="navigateToCMSPage">
144+
<argument name="CMSPage" value="$$createCMSPage$$"/>
145+
</actionGroup>
146+
<conditionalClick selector="{{CmsNewPagePageContentSection.header}}" dependentSelector="{{CmsNewPagePageContentSection.header}}._show" visible="false" stepKey="expandSection"/>
147+
<waitForPageLoad time="30" stepKey="waitForStageToLoad"/>
148+
<seeElementInDOM selector="{{CmsNewPagePageContentSection.content}}" stepKey="seeContentAreaInDOM"/>
149+
<dontSeeElementInDOM selector="{{PageBuilderStage.stageWrapper}}" stepKey="dontSeePageBuilderStage"/>
150+
</test>
114151
</tests>

0 commit comments

Comments
 (0)