Compare commits

...
Author SHA1 Message Date
Andreas ZerbstandGitHub 53e9774de9 Merge branch 'main' into v17/QA/allow-edit-invariant-setting-in-nested-block-tests 2026-06-25 13:34:27 +02:00
Andreas Zerbst 0b1ac1288f Fixes 2026-06-23 13:24:00 +02:00
Andreas Zerbst 0124156012 Merge remote-tracking branch 'origin/main' into v17/QA/allow-edit-invariant-setting-in-nested-block-tests 2026-06-23 10:12:36 +02:00
Nhu DinhandGitHub 24cae76612 Merge branch 'main' into v17/QA/allow-edit-invariant-setting-in-nested-block-tests 2026-06-18 10:43:07 +07:00
Nhu Dinh 3162a3a812 Merge branch 'main' into v17/QA/allow-edit-invariant-setting-in-nested-block-tests 2026-06-16 16:11:32 +07:00
Nhu Dinh 2b186026e2 Reverted npm command 2026-06-16 16:05:34 +07:00
Nhu Dinh a6faa00a7d Merge branch 'main' into v17/QA/allow-edit-invariant-setting-in-nested-block-tests 2026-06-16 13:43:42 +07:00
Nhu Dinh 694f715e1c Comment out the failing tests 2026-06-16 13:43:18 +07:00
Nhu Dinh cdb7a78b11 Merge branch 'main' into v17/QA/allow-edit-invariant-setting-in-nested-block-tests 2026-06-16 10:05:00 +07:00
Nhu Dinh 2558c4389c Merge branch 'main' into v17/QA/allow-edit-invariant-setting-in-nested-block-tests 2026-05-19 16:48:36 +07:00
Nhu Dinh 5d74dfbba4 Fixed comment 2026-05-19 13:06:27 +07:00
Nhu Dinh ac910a1e65 Removed not applicable tests 2026-05-15 16:42:05 +07:00
Nhu Dinh 352f72c2e0 Updated locator 2026-05-08 15:54:50 +07:00
Nhu Dinh a3ee6bd624 Updated locator 2026-05-08 13:15:22 +07:00
Nhu Dinh e26a0aee6e Make tests run in the pipeline 2026-05-08 11:09:52 +07:00
Nhu Dinh 97a851a868 Added comment for the non applicable tests 2026-05-08 11:07:44 +07:00
Nhu Dinh 97b3075cc3 Merge branch 'main' into v17/QA/allow-edit-invariant-setting-in-nested-block-tests 2026-05-08 10:55:30 +07:00
Nhu Dinh 6f7efb9650 Added tests for allow edit invariant setting is true with nested block 2026-05-08 10:42:56 +07:00
Nhu Dinh 0fdedd19ff Updated comment for not applicable tests 2026-05-08 10:41:14 +07:00
Nhu Dinh ad98d2ef31 Added tests for allow edit invariant setting is false with nested block 2026-05-08 10:40:43 +07:00
Nhu Dinh 983ffaabb0 Added ui helper for interacting with nested block 2026-05-08 10:40:03 +07:00
Nhu Dinh 6f1ab3575c Added api helper for creating document with multiple variants and no values 2026-05-08 10:21:45 +07:00
Nhu Dinh 036ce04198 Added api helper for createDocumentTypeWithNestedBlockList 2026-05-08 10:21:06 +07:00
6 changed files with 900 additions and 1288 deletions
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);
}
}
@@ -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);
});
}
@@ -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(
@@ -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);
});
}