-
Notifications
You must be signed in to change notification settings - Fork 2k
/
Copy pathlayout-grid.ts
129 lines (115 loc) · 4.52 KB
/
layout-grid.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { Locator } from 'playwright';
import { OpenInlineInserter } from '../../pages';
import { BlockFlow, EditorContext, PublishedPostContext } from '.';
// As a layout block, there's pretty massive amounts of potential variability in configuration.
// To keep things simple and maintainable, I think it's best to just lock in a simple, singular case (two columns of text) for the smoke test.
interface ConfigurationData {
leftColumnText: string;
rightColumnText: string;
}
interface ColumnDetails {
columnNumber: number;
textToAdd: string;
}
const blockParentSelector = '[aria-label="Block: Layout Grid"]';
const selectors = {
twoColumnButton: `${ blockParentSelector } button[aria-label="2 cols"]`,
addBlockButton: ( column: number ) =>
`${ blockParentSelector } [aria-label="Block: Column"]:nth-child(${ column }) button[aria-label="Add block"]`,
paragraphBlock: ( column: number ) =>
`${ blockParentSelector } [aria-label="Block: Column"]:nth-child(${ column }) [data-title=Paragraph]`,
};
/**
* Class representing the flow of using a Layout Grid block in the editor.
*/
export class LayoutGridBlockFlow implements BlockFlow {
private configurationData: ConfigurationData;
/**
* Constructs an instance of this block flow with data to be used when configuring and validating the block.
*
* @param {ConfigurationData} configurationData data with which to configure and validate the block.
*/
constructor( configurationData: ConfigurationData ) {
this.configurationData = configurationData;
}
blockSidebarName = 'Layout Grid';
blockEditorSelector = blockParentSelector;
/**
* Configure the block in the editor with the configuration data from the constructor.
*
* @param {EditorContext} context The current context for the editor at the point of test execution.
*/
async configure( context: EditorContext ): Promise< void > {
await context.page.pause();
const twoColumnButtonLocator = context.editorLocator.locator( selectors.twoColumnButton );
await twoColumnButtonLocator.click();
/**
* Workaround for the issue where the inline inserter of the Layout Grid
* block disappears when the "+" button is clicked too early after a
* column count has been selected.
*
* @see {@link https://github.com/Automattic/block-experiments/issues/294}
*/
await context.page.waitForTimeout( 1000 );
await this.addTextToColumn(
{
columnNumber: 1,
textToAdd: this.configurationData.leftColumnText,
},
context
);
await this.addTextToColumn(
{
columnNumber: 2,
textToAdd: this.configurationData.rightColumnText,
},
context
);
}
/**
* Add text to a given column in a layout grid.
*
* @param {ColumnDetails} columnDetails Details for the column to be configured.
* @param {EditorContext} context The current context for the editor at the point of test execution.
*/
private async addTextToColumn(
columnDetails: ColumnDetails,
context: EditorContext
): Promise< void > {
// The inline inserter can be opened in a lot of ways.
// We have to define our own function to do so, and make sure we're clicking the right button.
const openInlineInserter: OpenInlineInserter = async ( editor: Locator ) => {
const addBlockButtonLocator = editor.locator(
selectors.addBlockButton( columnDetails.columnNumber )
);
// On mobile, a lot of clicks are eaten en route to the button. This doesn't play well with Playwright and can cause fragility.
// A more stable, viewport-safe approach is to focus and press enter (which is also a real workflow for keyboard users).
await addBlockButtonLocator.focus();
await addBlockButtonLocator.press( 'Enter' );
};
await context.editorPage.addBlockInline(
'Paragraph',
selectors.paragraphBlock( columnDetails.columnNumber ),
openInlineInserter
);
const addedParagraphLocator = context.editorLocator.locator(
selectors.paragraphBlock( columnDetails.columnNumber )
);
await addedParagraphLocator.fill( columnDetails.textToAdd );
}
/**
* Validate the block in the published post.
*
* @param {PublishedPostContext} context The current context for the published post at the point of test execution.
*/
async validateAfterPublish( context: PublishedPostContext ): Promise< void > {
const expectedLeftColumnTextLocator = context.page.locator(
`text=${ this.configurationData.leftColumnText }`
);
await expectedLeftColumnTextLocator.waitFor();
const expectedRightColumnTextLocator = context.page.locator(
`text=${ this.configurationData.rightColumnText }`
);
await expectedRightColumnTextLocator.waitFor();
}
}