Welcome to mirror list, hosted at ThFree Co, Russian Federation.

SegmentSelectorEditor_spec.js « UI « tests « SegmentEditor « plugins - github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: e5a05fcf4ae7e61b3efa5ba2fed7239bf6710ee8 (plain)
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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/*!
 * 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.waitForTimeout(250); // animation
        expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('3_segment_editor_edit_name');
    });

    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.waitForSelector('.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', 'Behaviour', '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.waitForTimeout(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.$eval('.segmentEditorPanel .segmentRow0 .ui-autocomplete-input', e => e.blur());
        await page.click('.segmentEditorPanel .segment-add-or');
        await page.waitForFunction(() => !! $('.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', 'Behaviour', '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.waitForSelector('.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', 'Behaviour', '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, elem) {
                $(elem).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.waitForTimeout(200);

        await page.evaluate(function () {
            $('button.saveAndApply').click();
        });
        await page.waitForNetworkIdle();
        await page.waitForSelector('.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.$eval('.segmentEditorPanel .segmentRow0 .ui-autocomplete-input', e => e.blur());
        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.waitFor(200);

        await page.evaluate(function () {
           $('button.saveAndApply').click();
        });
        await page.waitForSelector('.modal.open');
        await page.waitForTimeout(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 (await page.waitForSelector('.segmentationContainer')).click();
        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.waitForSelector('.segmentListContainer .metricValueBlock');

        expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('updated_details');
    });

    it('should display autocomplete dropdown options correctly with lower case', async function() {
        await page.click('.expandableSelector .select-wrapper');
        await page.waitForSelector('.expandableList');
        await page.click('.expandableSelector');
        await page.type('.expandableSelector', 'event');
        await page.waitForTimeout(100);
        expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('autocomplete_lowercase');
    });

    it('should display autocomplete dropdown options correctly with upper case', async function() {
        const input = await page.$('.expandableSelector');
        await input.click({ clickCount: 3 })
        await page.type('.expandableSelector', 'EVENT');
        await page.waitForTimeout(100);
        expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('autocomplete_uppercase');
    });

    it('should display autocomplete dropdown options correctly with capitalized', async function() {
        const input = await page.$('.expandableSelector');
        await input.click({ clickCount: 3 })
        await page.type('.expandableSelector', 'Event');
        await page.waitForTimeout(100);
        expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('autocomplete_capitalized');
    });


    it("should correctly show delete dialog when the delete link is clicked", async function() {
        await page.click('.segmentEditorPanel a.delete');
        await page.waitForTimeout(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.waitForSelector('.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.waitForFunction(() => !! $('.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.waitForSelector('.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.waitFor(200);

        await page.evaluate(function () {
            $('button.saveAndApply').click();
        });

        await page.waitForNetworkIdle();
        await page.waitForSelector('.dataTable');
        await page.waitForNetworkIdle();

        expect(await page.screenshot()).to.matchImage('complex_segment');
    });

    it('should not show "AND segmented reports are pre-processed (faster, requires cron)" when enable_create_realtime_segments = 0', async () => {
        testEnvironment.overrideConfig('General', 'enable_create_realtime_segments', 0);
        testEnvironment.save();
        await page.goto(url);
        await page.click('.segmentationContainer .title');
        await page.click('.add_new_segment');
        await page.waitForNetworkIdle();
        expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('enabled_create_realtime_segments');
    });

    it("should save a new segment when enable_create_realtime_segments = 0", async function() {
        // ensure segment won't be archived after saving it.
        testEnvironment.overrideConfig('General', 'enable_create_realtime_segments', 0);
        testEnvironment.overrideConfig('General', 'enable_browser_archiving_triggering', 0);
        testEnvironment.overrideConfig('General', 'browser_archiving_disabled_enforce', 1);
        testEnvironment.optionsOverride = {
          enableBrowserTriggerArchiving: '0',
        };
        testEnvironment.save();
        await page.evaluate(function () {
          $('.segmentRow0 .segment-row:first .metricValueBlock input').val('3').change();
        });

        await page.type('input.edit_segment_name', 'auto archive segment');
        await page.click('.segmentRow0 .segment-or'); // click somewhere else to save new name

        // this is for debug purpose. If segment can't be saved, and alert might be shown, causing the UI test to hang
        page.on('dialog', (dialog)=> {
            console.log(dialog.message());
        });

        await page.waitFor(200);

        await page.evaluate(function () {
            $('button.saveAndApply').click();
        });
        await page.waitForNetworkIdle();
        await page.waitForSelector('.segmentationContainer');

        await page.click('.segmentationContainer .title');
        expect(await page.screenshotSelector(selectorsToCapture)).to.matchImage('enabled_create_realtime_segments_saved');
    });
});