Compare commits
23
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53e9774de9 | ||
|
|
0b1ac1288f | ||
|
|
0124156012 | ||
|
|
24cae76612 | ||
|
|
3162a3a812 | ||
|
|
2b186026e2 | ||
|
|
a6faa00a7d | ||
|
|
694f715e1c | ||
|
|
cdb7a78b11 | ||
|
|
2558c4389c | ||
|
|
5d74dfbba4 | ||
|
|
ac910a1e65 | ||
|
|
352f72c2e0 | ||
|
|
a3ee6bd624 | ||
|
|
e26a0aee6e | ||
|
|
97a851a868 | ||
|
|
97b3075cc3 | ||
|
|
6f7efb9650 | ||
|
|
0fdedd19ff | ||
|
|
ad98d2ef31 | ||
|
|
983ffaabb0 | ||
|
|
6f1ab3575c | ||
|
|
036ce04198 |
File diff suppressed because it is too large
Load Diff
@@ -549,6 +549,24 @@ export class DocumentApiHelper {
|
||||
return await this.create(document);
|
||||
}
|
||||
|
||||
async createDocumentWithMultipleVariantsAndNoValues(documentName: string, documentTypeId: string, cultureVariants: {isoCode: string, name: string}[]) {
|
||||
await this.ensureNameNotExists(documentName);
|
||||
|
||||
const document = new DocumentBuilder()
|
||||
.withDocumentTypeId(documentTypeId)
|
||||
.build();
|
||||
|
||||
for (const variant of cultureVariants) {
|
||||
document.variants.push({
|
||||
name: variant.name,
|
||||
culture: variant.isoCode,
|
||||
segment: null,
|
||||
});
|
||||
}
|
||||
|
||||
return await this.create(document);
|
||||
}
|
||||
|
||||
async createDocumentWithMultipleVariantsWithSharedProperty(documentName: string, documentTypeId: string, dataTypeAlias: string, dataTypeEditorAlias: string, cultureVariants: {isoCode: string, name: string}[], value) {
|
||||
await this.ensureNameNotExists(documentName);
|
||||
|
||||
|
||||
@@ -765,7 +765,7 @@ export class DocumentTypeApiHelper {
|
||||
return await this.create(documentType);
|
||||
}
|
||||
|
||||
async createElementTypeWithPropertyInTab(elementName: string, tabName: string = 'ContentTab', groupName: string = 'TestGroup', dataTypeName: string = 'Textstring', dataTypeId: string, isMandatory: boolean = false) {
|
||||
async createElementTypeWithPropertyInTab(elementName: string, tabName: string = 'ContentTab', groupName: string = 'TestGroup', dataTypeName: string = 'Textstring', dataTypeId: string, isMandatory: boolean = false, elementVariesByCulture: boolean = false, propertyVariesByCulture: boolean = false) {
|
||||
await this.ensureNameNotExists(elementName);
|
||||
|
||||
const crypto = require('crypto');
|
||||
@@ -777,6 +777,7 @@ export class DocumentTypeApiHelper {
|
||||
.withAlias(AliasHelper.toAlias(elementName))
|
||||
.withIsElement(true)
|
||||
.withAllowedInLibrary(true)
|
||||
.withVariesByCulture(elementVariesByCulture)
|
||||
.withIcon("icon-plugin")
|
||||
.addContainer()
|
||||
.withName(tabName)
|
||||
@@ -795,6 +796,7 @@ export class DocumentTypeApiHelper {
|
||||
.withName(dataTypeName)
|
||||
.withDataTypeId(dataTypeId)
|
||||
.withMandatory(isMandatory)
|
||||
.withVariesByCulture(propertyVariesByCulture)
|
||||
.done()
|
||||
.build();
|
||||
return await this.create(documentType);
|
||||
@@ -1275,4 +1277,111 @@ export class DocumentTypeApiHelper {
|
||||
|
||||
return await this.create(documentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a document type with a nested Block List structure for testing the
|
||||
* AllowEditInvariantFromNonDefault matrix.
|
||||
*
|
||||
* Structure created:
|
||||
* - Document Type (Vary by culture)
|
||||
* - Outer Block List property (variance per `variance.outerBlockList`)
|
||||
* -> Outer Block List Data Type
|
||||
* -> Outer Element Type (variance per `variance.outerElement`)
|
||||
* - Inner Block List property (variance per `variance.innerBlockList`)
|
||||
* -> Inner Block List Data Type
|
||||
* -> Inner Element Type (variance per `variance.innerElement`)
|
||||
* - Text property (variance per `variance.text`)
|
||||
*
|
||||
* Note: a property can only vary by culture when its containing type also varies.
|
||||
* The caller is responsible for passing a consistent combination
|
||||
* (e.g. when innerElement = false, text must also be false).
|
||||
*/
|
||||
async createDocumentTypeWithNestedBlockList(
|
||||
documentTypeName: string,
|
||||
outerBlockListDataTypeName: string,
|
||||
outerElementTypeName: string,
|
||||
innerBlockListDataTypeName: string,
|
||||
innerElementTypeName: string,
|
||||
textPropertyName: string,
|
||||
textDataTypeId: string,
|
||||
variance: {
|
||||
outerBlockList: boolean,
|
||||
outerElement: boolean,
|
||||
innerBlockList: boolean,
|
||||
innerElement: boolean,
|
||||
text: boolean,
|
||||
}
|
||||
) {
|
||||
// A property can only vary by culture when its containing element type also varies.
|
||||
if (variance.text && !variance.innerElement) {
|
||||
throw new Error('Invalid variance combination: "text" can only vary by culture when "innerElement" varies.');
|
||||
}
|
||||
if (variance.innerBlockList && !variance.outerElement) {
|
||||
throw new Error('Invalid variance combination: "innerBlockList" can only vary by culture when "outerElement" varies.');
|
||||
}
|
||||
|
||||
const crypto = require('crypto');
|
||||
await this.ensureNameNotExists(documentTypeName);
|
||||
await this.api.dataType.ensureNameNotExists(outerBlockListDataTypeName);
|
||||
await this.api.dataType.ensureNameNotExists(innerBlockListDataTypeName);
|
||||
|
||||
// 1. Inner Element Type (with Text property)
|
||||
const innerElementTypeId = await this.createElementTypeWithPropertyInTab(
|
||||
innerElementTypeName,
|
||||
undefined,
|
||||
undefined,
|
||||
textPropertyName,
|
||||
textDataTypeId,
|
||||
false,
|
||||
variance.innerElement,
|
||||
variance.text
|
||||
) as string;
|
||||
|
||||
// 2. Inner Block List Data Type
|
||||
const innerBlockListDataTypeId = await this.api.dataType.createBlockListDataTypeWithABlock(
|
||||
innerBlockListDataTypeName,
|
||||
innerElementTypeId
|
||||
) as string;
|
||||
|
||||
// 3. Outer Element Type (with Inner Block List property)
|
||||
const outerElementTypeId = await this.createElementTypeWithPropertyInTab(
|
||||
outerElementTypeName,
|
||||
undefined,
|
||||
undefined,
|
||||
innerBlockListDataTypeName,
|
||||
innerBlockListDataTypeId,
|
||||
false,
|
||||
variance.outerElement,
|
||||
variance.innerBlockList
|
||||
) as string;
|
||||
|
||||
// 4. Outer Block List Data Type
|
||||
const outerBlockListDataTypeId = await this.api.dataType.createBlockListDataTypeWithABlock(
|
||||
outerBlockListDataTypeName,
|
||||
outerElementTypeId
|
||||
) as string;
|
||||
|
||||
// 5. Document Type (Vary by culture) with Outer Block List property
|
||||
const documentTypeContainerId = crypto.randomUUID();
|
||||
const documentType = new DocumentTypeBuilder()
|
||||
.withName(documentTypeName)
|
||||
.withAlias(AliasHelper.toAlias(documentTypeName))
|
||||
.withAllowedAsRoot(true)
|
||||
.withVariesByCulture(true)
|
||||
.addContainer()
|
||||
.withName('Content')
|
||||
.withId(documentTypeContainerId)
|
||||
.withType('Group')
|
||||
.done()
|
||||
.addProperty()
|
||||
.withContainerId(documentTypeContainerId)
|
||||
.withAlias(AliasHelper.toAlias(outerBlockListDataTypeName))
|
||||
.withName(outerBlockListDataTypeName)
|
||||
.withDataTypeId(outerBlockListDataTypeId)
|
||||
.withVariesByCulture(variance.outerBlockList)
|
||||
.done()
|
||||
.build();
|
||||
|
||||
return await this.create(documentType);
|
||||
}
|
||||
}
|
||||
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
import {ConstantHelper, test} from '@umbraco/acceptance-test-helpers';
|
||||
|
||||
// Content
|
||||
const documentName = 'NestedBlockMatrixContent';
|
||||
const danishVariantName = 'NestedBlockMatrixContent DA';
|
||||
const englishTextValue = 'English nested block text';
|
||||
// Document type
|
||||
const documentTypeName = 'NestedBlockMatrixDocType';
|
||||
// Nested block structure
|
||||
const outerBlockListName = 'OuterBlockList';
|
||||
const outerElementTypeName = 'OuterElement';
|
||||
const innerBlockListName = 'InnerBlockList';
|
||||
const innerElementTypeName = 'InnerElement';
|
||||
const textPropertyName = 'BlockText';
|
||||
const textStringDataTypeName = 'Textstring';
|
||||
// Cultures
|
||||
const firstCulture = 'en-US';
|
||||
const secondCulture = 'da';
|
||||
const cultures = [
|
||||
{isoCode: firstCulture, name: documentName},
|
||||
{isoCode: secondCulture, name: danishVariantName},
|
||||
];
|
||||
// Data Type
|
||||
let textStringDataTypeId: string;
|
||||
|
||||
// 18 cases from the AllowEditInvariantFromNonDefault matrix (nested block editor).
|
||||
// Variance flags: true = Varies By Culture, false = Shared/Invariant.
|
||||
// Constraint: when innerElement = false, text must also be false.
|
||||
const matrixCases: ReadonlyArray<{
|
||||
outerBlockList: boolean;
|
||||
outerElement: boolean;
|
||||
innerBlockList: boolean;
|
||||
innerElement: boolean;
|
||||
text: boolean;
|
||||
daEditable: boolean;
|
||||
}> = [
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: true, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: true, innerElement: true, text: false, daEditable: true},
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: true, innerElement: false, text: false, daEditable: true},
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: false, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: false, innerElement: true, text: false, daEditable: true},
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: false, innerElement: false, text: false, daEditable: true},
|
||||
{outerBlockList: true, outerElement: false, innerBlockList: false, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: true, outerElement: false, innerBlockList: false, innerElement: true, text: false, daEditable: true},
|
||||
{outerBlockList: true, outerElement: false, innerBlockList: false, innerElement: false, text: false, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: true, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: true, innerElement: true, text: false, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: true, innerElement: false, text: false, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: false, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: false, innerElement: true, text: false, daEditable: false},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: false, innerElement: false, text: false, daEditable: false},
|
||||
{outerBlockList: false, outerElement: false, innerBlockList: false, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: false, outerElement: false, innerBlockList: false, innerElement: true, text: false, daEditable: false},
|
||||
{outerBlockList: false, outerElement: false, innerBlockList: false, innerElement: false, text: false, daEditable: false},
|
||||
];
|
||||
|
||||
const formatCombo = (tc: typeof matrixCases[number]): string =>
|
||||
`outer block list=${tc.outerBlockList ? 'Varies by culture' : 'Shared'}` +
|
||||
`, outer element=${tc.outerElement ? 'Varies by culture' : 'Shared'}` +
|
||||
`, inner block list=${tc.innerBlockList ? 'Varies by culture' : 'Shared'}` +
|
||||
`, inner element=${tc.innerElement ? 'Varies by culture' : 'Shared'}` +
|
||||
`, text=${tc.text ? 'Varies by culture' : 'Shared'}`;
|
||||
|
||||
test.beforeEach(async ({umbracoApi, umbracoUi}) => {
|
||||
await umbracoApi.language.createDanishLanguage();
|
||||
const textStringDataType = await umbracoApi.dataType.getByName(textStringDataTypeName);
|
||||
textStringDataTypeId = textStringDataType.id;
|
||||
await umbracoUi.goToBackOffice();
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(documentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(outerElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(innerElementTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(outerBlockListName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(innerBlockListName);
|
||||
await umbracoApi.language.ensureIsoCodeNotExists(secondCulture);
|
||||
});
|
||||
|
||||
for (const tc of matrixCases) {
|
||||
const expectedLabel = tc.daEditable ? 'can edit' : 'cannot edit';
|
||||
|
||||
test(`${expectedLabel} text property in non-default language (${formatCombo(tc)})`, async ({umbracoApi, umbracoUi}) => {
|
||||
test.slow();
|
||||
// Arrange
|
||||
const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithNestedBlockList(
|
||||
documentTypeName,
|
||||
outerBlockListName,
|
||||
outerElementTypeName,
|
||||
innerBlockListName,
|
||||
innerElementTypeName,
|
||||
textPropertyName,
|
||||
textStringDataTypeId,
|
||||
{
|
||||
outerBlockList: tc.outerBlockList,
|
||||
outerElement: tc.outerElement,
|
||||
innerBlockList: tc.innerBlockList,
|
||||
innerElement: tc.innerElement,
|
||||
text: tc.text,
|
||||
}
|
||||
);
|
||||
await umbracoApi.document.createDocumentWithMultipleVariantsAndNoValues(documentName, documentTypeId, cultures);
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(documentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.clickAddBlockElementButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(outerElementTypeName, true);
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(innerElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(innerElementTypeName, true);
|
||||
await umbracoUi.content.isBlockWorkspacePropertyEditable(innerElementTypeName, textPropertyName, true);
|
||||
await umbracoUi.content.enterTextstring(englishTextValue);
|
||||
await umbracoUi.content.clickCreateInModal(innerElementTypeName);
|
||||
await umbracoUi.content.clickCreateInModal(outerElementTypeName);
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
await umbracoUi.content.clickContainerSaveAndPublishButton();
|
||||
await umbracoUi.content.isSuccessNotificationVisible();
|
||||
await umbracoUi.content.switchLanguage(secondCulture);
|
||||
if (tc.outerBlockList) {
|
||||
// Outer block list varies → DA gets its own list, EN's block is not visible.
|
||||
// Add a fresh outer + inner block in DA to expose the inner text field.
|
||||
await umbracoUi.content.clickAddBlockElementButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(outerElementTypeName, true);
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(innerElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(innerElementTypeName, true);
|
||||
} else {
|
||||
// Outer block list is shared → the EN block is visible in DA. Open the
|
||||
// existing outer block, then the existing inner block within it.
|
||||
await umbracoUi.content.clickEditBlockListEntryWithName(outerElementTypeName);
|
||||
if (tc.innerBlockList) {
|
||||
// Inner block list varies → DA gets its own inner block, EN's inner block is not visible.
|
||||
// Add a fresh inner block in DA to expose the inner text field.
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(innerElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(innerElementTypeName, true);
|
||||
} else {
|
||||
// Inner block list is shared → the EN inner block is visible in DA. Open the existing inner block.
|
||||
await umbracoUi.content.clickEditNestedBlockListEntry(outerElementTypeName, innerElementTypeName);
|
||||
}
|
||||
}
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.isBlockWorkspacePropertyEditable(innerElementTypeName, textPropertyName, tc.daEditable);
|
||||
});
|
||||
}
|
||||
-34
@@ -225,40 +225,6 @@ test('can edit invariant text property inside a variant block in non-default lan
|
||||
await umbracoUi.content.isBlockPropertyEditable(secondTextName, true);
|
||||
});
|
||||
|
||||
test('can edit variant text property inside invariant block in non-default language when AllowEditInvariantFromNonDefault is true', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithVariantAndInvariantBlockLists(
|
||||
documentTypeName,
|
||||
firstTextName,
|
||||
textStringDataType.id,
|
||||
secondTextName,
|
||||
textStringDataType.id,
|
||||
firstBlockListName,
|
||||
secondBlockListName,
|
||||
firstBlockElementTypeName,
|
||||
secondBlockElementTypeName
|
||||
);
|
||||
await umbracoApi.document.createDocumentWithMultipleVariantsWithSharedProperty(englishContentName, documentTypeId, AliasHelper.toAlias(secondTextName), textStringEditorAlias, cultures, '');
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.goToContentWithName(englishContentName);
|
||||
await umbracoUi.content.clickAddBlockListElementWithName(secondBlockListName);
|
||||
await umbracoUi.content.clickBlockElementWithName(firstBlockElementTypeName);
|
||||
await umbracoUi.content.enterBlockPropertyValue(firstTextName, 'Text1 in invariant block');
|
||||
await umbracoUi.content.enterBlockPropertyValue(secondTextName, 'Text2 in invariant block');
|
||||
await umbracoUi.content.clickCreateModalButton();
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
await umbracoUi.content.clickContainerSaveAndPublishButton();
|
||||
await umbracoUi.content.isSuccessNotificationVisible();
|
||||
await umbracoUi.content.switchLanguage(secondCulture);
|
||||
await umbracoUi.content.clickEditBlockListBlockButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.isBlockPropertyEditable(firstTextName, true);
|
||||
});
|
||||
|
||||
test('can edit invariant text property inside an invariant block in non-default language when AllowEditInvariantFromNonDefault is true', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithVariantAndInvariantBlockLists(
|
||||
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
import {ConstantHelper, test} from '@umbraco/acceptance-test-helpers';
|
||||
|
||||
// Content
|
||||
const documentName = 'NestedBlockMatrixContent';
|
||||
const danishVariantName = 'NestedBlockMatrixContent DA';
|
||||
const englishTextValue = 'English nested block text';
|
||||
// Document type
|
||||
const documentTypeName = 'NestedBlockMatrixDocType';
|
||||
// Nested block structure
|
||||
const outerBlockListName = 'OuterBlockList';
|
||||
const outerElementTypeName = 'OuterElement';
|
||||
const innerBlockListName = 'InnerBlockList';
|
||||
const innerElementTypeName = 'InnerElement';
|
||||
const textPropertyName = 'BlockText';
|
||||
const textStringDataTypeName = 'Textstring';
|
||||
// Cultures
|
||||
const firstCulture = 'en-US';
|
||||
const secondCulture = 'da';
|
||||
const cultures = [
|
||||
{isoCode: firstCulture, name: documentName},
|
||||
{isoCode: secondCulture, name: danishVariantName},
|
||||
];
|
||||
// Data Type
|
||||
let textStringDataTypeId: string;
|
||||
|
||||
// 18 cases from the AllowEditInvariantFromNonDefault matrix (nested block editor).
|
||||
// Variance flags: true = Varies By Culture, false = Shared/Invariant.
|
||||
// Constraint: when innerElement = false, text must also be false.
|
||||
const matrixCases: ReadonlyArray<{
|
||||
outerBlockList: boolean;
|
||||
outerElement: boolean;
|
||||
innerBlockList: boolean;
|
||||
innerElement: boolean;
|
||||
text: boolean;
|
||||
daEditable: boolean;
|
||||
}> = [
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: true, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: true, innerElement: true, text: false, daEditable: true},
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: true, innerElement: false, text: false, daEditable: true},
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: false, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: false, innerElement: true, text: false, daEditable: true},
|
||||
{outerBlockList: true, outerElement: true, innerBlockList: false, innerElement: false, text: false, daEditable: true},
|
||||
{outerBlockList: true, outerElement: false, innerBlockList: false, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: true, outerElement: false, innerBlockList: false, innerElement: true, text: false, daEditable: true},
|
||||
{outerBlockList: true, outerElement: false, innerBlockList: false, innerElement: false, text: false, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: true, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: true, innerElement: true, text: false, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: true, innerElement: false, text: false, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: false, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: false, innerElement: true, text: false, daEditable: true},
|
||||
{outerBlockList: false, outerElement: true, innerBlockList: false, innerElement: false, text: false, daEditable: true},
|
||||
{outerBlockList: false, outerElement: false, innerBlockList: false, innerElement: true, text: true, daEditable: true},
|
||||
{outerBlockList: false, outerElement: false, innerBlockList: false, innerElement: true, text: false, daEditable: true},
|
||||
{outerBlockList: false, outerElement: false, innerBlockList: false, innerElement: false, text: false, daEditable: true},
|
||||
];
|
||||
|
||||
const formatCombo = (tc: typeof matrixCases[number]): string =>
|
||||
`outer block list=${tc.outerBlockList ? 'Varies by culture' : 'Shared'}` +
|
||||
`, outer element=${tc.outerElement ? 'Varies by culture' : 'Shared'}` +
|
||||
`, inner block list=${tc.innerBlockList ? 'Varies by culture' : 'Shared'}` +
|
||||
`, inner element=${tc.innerElement ? 'Varies by culture' : 'Shared'}` +
|
||||
`, text=${tc.text ? 'Varies by culture' : 'Shared'}`;
|
||||
|
||||
test.beforeEach(async ({umbracoApi, umbracoUi}) => {
|
||||
await umbracoApi.language.createDanishLanguage();
|
||||
const textStringDataType = await umbracoApi.dataType.getByName(textStringDataTypeName);
|
||||
textStringDataTypeId = textStringDataType.id;
|
||||
await umbracoUi.goToBackOffice();
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(documentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(outerElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(innerElementTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(outerBlockListName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(innerBlockListName);
|
||||
await umbracoApi.language.ensureIsoCodeNotExists(secondCulture);
|
||||
});
|
||||
|
||||
for (const tc of matrixCases) {
|
||||
const expectedLabel = tc.daEditable ? 'can edit' : 'cannot edit';
|
||||
|
||||
test(`${expectedLabel} text property in non-default language (${formatCombo(tc)})`, async ({umbracoApi, umbracoUi}) => {
|
||||
test.slow();
|
||||
// Arrange
|
||||
const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithNestedBlockList(
|
||||
documentTypeName,
|
||||
outerBlockListName,
|
||||
outerElementTypeName,
|
||||
innerBlockListName,
|
||||
innerElementTypeName,
|
||||
textPropertyName,
|
||||
textStringDataTypeId,
|
||||
{
|
||||
outerBlockList: tc.outerBlockList,
|
||||
outerElement: tc.outerElement,
|
||||
innerBlockList: tc.innerBlockList,
|
||||
innerElement: tc.innerElement,
|
||||
text: tc.text,
|
||||
}
|
||||
);
|
||||
await umbracoApi.document.createDocumentWithMultipleVariantsAndNoValues(documentName, documentTypeId, cultures);
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(documentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.clickAddBlockElementButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(outerElementTypeName, true);
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(innerElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(innerElementTypeName, true);
|
||||
await umbracoUi.content.isBlockWorkspacePropertyEditable(innerElementTypeName, textPropertyName, true);
|
||||
await umbracoUi.content.enterTextstring(englishTextValue);
|
||||
await umbracoUi.content.clickCreateInModal(innerElementTypeName);
|
||||
await umbracoUi.content.clickCreateInModal(outerElementTypeName);
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
await umbracoUi.content.clickContainerSaveAndPublishButton();
|
||||
await umbracoUi.content.isSuccessNotificationVisible();
|
||||
await umbracoUi.content.switchLanguage(secondCulture);
|
||||
if (tc.outerBlockList) {
|
||||
// Outer block list varies → DA gets its own list, EN's block is not visible.
|
||||
// Add a fresh outer + inner block in DA to expose the inner text field.
|
||||
await umbracoUi.content.clickAddBlockElementButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(outerElementTypeName, true);
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(innerElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(innerElementTypeName, true);
|
||||
} else {
|
||||
// Outer block list is shared → the EN block is visible in DA. Open the
|
||||
// existing outer block, then the existing inner block within it.
|
||||
await umbracoUi.content.clickEditBlockListEntryWithName(outerElementTypeName);
|
||||
if (tc.innerBlockList) {
|
||||
// Inner block list varies → DA gets its own inner block, EN's inner block is not visible.
|
||||
// Add a fresh inner block in DA to expose the inner text field.
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(innerElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(innerElementTypeName, true);
|
||||
} else {
|
||||
// Inner block list is shared → the EN inner block is visible in DA. Open the existing inner block.
|
||||
await umbracoUi.content.clickEditNestedBlockListEntry(outerElementTypeName, innerElementTypeName);
|
||||
}
|
||||
}
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.isBlockWorkspacePropertyEditable(innerElementTypeName, textPropertyName, tc.daEditable);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user