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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
/*!
* Matomo - free/libre analytics platform
*
* SegmentEditor screenshot tests.
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
describe("SegmentSelectorEditorTest", function () {
var selectorsToCapture = ".segmentEditorPanel,.segmentEditorPanel .dropdown-body,.segment-element";
this.timeout(0);
var generalParams = 'idSite=1&period=year&date=2012-08-09';
var url = '?module=CoreHome&action=index&' + generalParams + '#?' + generalParams + '&category=General_Actions&subcategory=General_Pages';
async function selectFieldValue(fieldName, textToSelect)
{
await page.webpage.evaluate((fieldName) => {
$(fieldName + ' input.select-dropdown').click();
}, fieldName);
await page.webpage.evaluate((fieldName, textToSelect) => {
$(fieldName + ' .dropdown-content.active li:contains("' + textToSelect + '"):first').click();
}, fieldName, textToSelect);
await page.mouse.move(-10, -10);
}
async function selectDimension(prefixSelector, category, name)
{
await (await page.jQuery(prefixSelector + ' .metricListBlock .select-wrapper', { waitFor: true })).click();
await (await page.jQuery(prefixSelector + ' .metricListBlock .expandableList h4:contains(' + category + ')', { waitFor: true })).click();
await (await page.jQuery(prefixSelector + ' .metricListBlock .expandableList .secondLevel li:contains(' + name + ')', { waitFor: true })).click();
}
it("should load correctly", async function() {
await page.goto(url);
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('0_initial');
});
it("should open selector when control clicked", async function() {
await page.click('.segmentationContainer .title');
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('1_selector_open');
});
it("should open segment editor when edit link clicked for existing segment", async function() {
await page.evaluate(function() {
$('.segmentList .editSegment:first').click()
});
await page.waitForNetworkIdle();
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('2_segment_editor_update');
});
it("should start editing segment name when segment name edit link clicked", async function() {
await page.click('.segmentEditorPanel .editSegmentName');
await page.waitFor(250); // animation
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('3_segment_editor_edit_name');
});
it("should show the egment editor's available segments dropdown", async function() {
var elem = await page.$('.available_segments a.dropList');
await elem.hover();
await page.click('.available_segments a.dropList');
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('6_segment_editor_droplist');
});
it("should change segment when another available segment clicked in segment editor's available segments dropdown", async function() {
await (await page.jQuery('.ui-menu-item a:contains(Add new segment)')).click();
await page.waitForNetworkIdle();
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('6_segment_editor_different');
});
it("should close the segment editor when the close link is clicked", async function() {
await page.evaluate(function () {
$('.segmentEditorPanel .segment-footer .close').click();
});
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('7_segment_editor_closed');
});
it("should open blank segment editor when create new segment link is clicked", async function() {
await page.click('.segmentationContainer .title');
await page.click('.add_new_segment');
await page.waitForNetworkIdle();
await page.waitFor('.segmentRow0');
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('8_segment_editor_create');
});
it("should update segment expression when selecting different segment", async function() {
await selectDimension('.segmentRow0', 'Actions', 'Action URL');
await page.waitForNetworkIdle();
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('dimension_drag_drop');
});
it("should show suggested segment values when a segment value input is focused", async function() {
await page.click('.segmentEditorPanel .segmentRow0 .ui-autocomplete-input');
await page.waitForNetworkIdle();
await page.waitFor(500);
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('suggested_values');
});
it("should add an OR condition when clicking on add OR", async function() {
await page.click('.segmentEditorPanel .segment-add-or');
await page.waitFor(() => !! $('.segmentRow0 .segment-rows>div:eq(1)').length);
await page.waitForNetworkIdle();
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('add_new_or_condition');
});
it("should add an OR condition when a segment dimension is selected in the OR placeholder section", async function() {
await selectDimension('.segmentRow0 .segment-row:last', 'Actions', 'Clicked Outlink');
await page.waitForNetworkIdle();
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('drag_or_condition');
});
it("should add an AND condition when clicking on add AND", async function() {
await page.click('.segmentEditorPanel .segment-add-row');
await page.waitFor('.segmentRow1');
await page.waitForNetworkIdle();
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('add_new_and_condition');
});
it("should add an AND condition when a segment dimension is dragged to the AND placeholder section", async function() {
await selectDimension('.segmentRow1', 'Actions', 'Clicked Outlink');
await page.waitForNetworkIdle();
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('drag_and_condition');
});
it("should save a new segment and add it to the segment list when the form is filled out and the save button is clicked", async function() {
await page.evaluate(function () {
$('.metricValueBlock input').each(function (index) {
$(this).val('value ' + index).change();
});
});
await page.type('input.edit_segment_name', 'new segment');
await page.click('.segmentRow0 .segment-or'); // click somewhere else to save new name
await page.evaluate(function () {
$('button.saveAndApply').click();
});
await page.waitForNetworkIdle();
await page.waitFor('.segmentationContainer');
await page.click('.segmentationContainer');
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('saved');
});
it("should show the new segment after page reload", async function() {
await page.reload();
await page.click('.segmentationContainer .title');
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('saved');
});
it("should correctly load the new segment's details when the new segment is edited", async function() {
await page.click('.segmentList li[data-idsegment="4"] .editSegment');
await page.waitForNetworkIdle();
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('saved_details');
});
it("should correctly should show a confirmation when changing segment definition", async function() {
await page.click('.segmentEditorPanel .editSegmentName');
await page.evaluate(function () {
$('input.edit_segment_name').val('').change();
});
await page.type('input.edit_segment_name', 'edited segment');
await (await page.jQuery('.segmentRow0 .segment-or:first')).click(); // click somewhere else to save new name
await selectFieldValue('.segmentRow0 .segment-row:first .metricMatchBlock', 'Is not');
await selectFieldValue('.segmentRow0 .segment-row:last .metricMatchBlock', 'Is not');
await selectFieldValue('.segmentRow1 .segment-row .metricMatchBlock', 'Is not');
await page.evaluate(function () {
$('.metricValueBlock input').each(function (index) {
$(this).val('new value ' + index).change();
});
});
await page.evaluate(function () {
$('button.saveAndApply').click();
});
await page.waitFor('.modal.open');
await page.waitFor(500); // animation to show confirm
const modal = await page.$('.modal.open');
expect(await modal.screenshot()).to.matchImage('update_confirmation');
});
it("should correctly update the segment when saving confirmed", async function() {
var elem = await page.jQuery('.modal.open .modal-footer a:contains(Yes):visible');
await elem.click();
await page.waitForNetworkIdle();
await page.click('.segmentationContainer');
await page.waitForNetworkIdle();
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('updated');
});
it("should show the updated segment after page reload", async function() {
await page.reload();
await page.click('.segmentationContainer .title');
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('updated');
});
it("should correctly load the updated segment's details when the updated segment is edited", async function() {
await page.click('.segmentList li[data-idsegment="4"] .editSegment');
await page.waitForNetworkIdle();
await page.waitFor('.segmentListContainer .metricValueBlock');
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('updated_details');
});
it("should correctly show delete dialog when the delete link is clicked", async function() {
await page.click('.segmentEditorPanel a.delete');
await page.waitFor(500); // animation
const modal = await page.$('.modal.open');
expect(await modal.screenshot()).to.matchImage('deleted_dialog');
});
it("should correctly remove the segment when the delete dialog is confirmed", async function() {
var elem = await page.jQuery('.modal.open .modal-footer a:contains(Yes):visible');
await elem.click();
await page.waitForNetworkIdle();
await page.waitForSelector('.segmentationContainer .title');
await page.click('.segmentationContainer .title');
expect(await page.screenshotSelector(selectorsToCapture + ',.modal.open')).to.matchImage('deleted');
});
it("should not show the deleted segment after page reload", async function() {
await page.reload();
await page.waitForSelector('.segmentationContainer .title');
await page.click('.segmentationContainer .title');
expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('deleted');
});
it('should correctly handle complex segments with encoded characters and whitespace', async function () {
await page.goto(url);
await page.click('.segmentationContainer .title');
await page.click('a.add_new_segment');
await page.type('input.edit_segment_name', 'complex segment');
await page.waitFor('.segmentRow0');
await selectDimension('.segmentRow0', 'Visitors', 'Browser');
await selectFieldValue('.segmentRow0 .segment-row:eq(0) .metricMatchBlock', 'Is not');
await page.evaluate(function () {
var complexValue = 's#2&#--_*+?# #5"\'&<>.22,3';
$('.segmentRow0 .segment-row:first .metricValueBlock input').val(complexValue).change();
});
await page.click('.segment-add-or');
await page.waitFor(() => !! $('.segmentRow0 .segment-row:eq(1)').length);
// configure or condition
await selectDimension('.segmentRow0 .segment-row:eq(1)', 'Visitors', 'Browser');
await selectFieldValue('.segmentRow0 .segment-row:eq(1) .metricMatchBlock', 'Is');
await page.evaluate(function () {
var complexValue = 's#2&#--_*+?# #5"\'&<>.22,3';
$('.segmentRow0 .segment-row:eq(1) .metricValueBlock input').val(complexValue).change();
});
await page.click('.segment-add-row');
await page.waitFor('.segmentRow1 .segment-row');
// configure and condition
await selectDimension('.segmentRow1', 'Visitors', 'Browser');
await selectFieldValue('.segmentRow1 .segment-row:first .metricMatchBlock', 'Is not');
await page.evaluate(function () {
var complexValue = 's#2&#--_*+?# #5"\'&<>.22,3';
$('.segmentRow1 .metricValueBlock input').val(complexValue).change();
});
await page.evaluate(function () {
$('button.saveAndApply').click();
});
await page.waitForNetworkIdle();
await page.waitFor('.dataTable');
await page.waitForNetworkIdle();
expect(await page.screenshot()).to.matchImage('complex_segment');
});
});
|