File size: 6,821 Bytes
8fd7a1d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import path from 'path';
import SeleniumHelper from '../helpers/selenium-helper';

const {
    clickText,
    clickXpath,
    findByText,
    findByXpath,
    getDriver,
    loadUri,
    rightClickText,
    scope
} = new SeleniumHelper();

const uri = path.resolve(__dirname, '../../build/index.html');

let driver;

const FILE_MENU_XPATH = '//div[contains(@class, "menu-bar_menu-bar-item")]' +
    '[*[contains(@class, "menu-bar_collapsible-label")]//*[text()="File"]]';
const SETTINGS_MENU_XPATH = '//div[contains(@class, "menu-bar_menu-bar-item")]' +
    '[*[contains(@class, "settings-menu_dropdown-label")]//*[text()="Settings"]]';

describe('Menu bar settings', () => {
    beforeAll(() => {
        driver = getDriver();
    });

    afterAll(async () => {
        await driver.quit();
    });

    test('File->New should be enabled', async () => {
        await loadUri(uri);
        await clickXpath(FILE_MENU_XPATH);
        await findByXpath('//*[li[span[text()="New"]] and not(@data-tip="tooltip")]');
    });

    test('File->Load should be enabled', async () => {
        await loadUri(uri);
        await clickXpath(FILE_MENU_XPATH);
        await findByXpath('//*[li[text()="Load from your computer"] and not(@data-tip="tooltip")]');
    });

    test('File->Save should be enabled', async () => {
        await loadUri(uri);
        await clickXpath(FILE_MENU_XPATH);
        await findByXpath('//*[li[span[text()="Save to your computer"]] and not(@data-tip="tooltip")]');
    });

    test('Share button should NOT be enabled', async () => {
        await loadUri(uri);
        await findByXpath('//div[span[div[span[text()="Share"]]] and @data-tip="tooltip"]');
    });

    test('Logo should be clickable', async () => {
        await loadUri(uri);
        await clickXpath('//img[@alt="Scratch"]');
        const currentUrl = await driver.getCurrentUrl();
        await expect(currentUrl).toEqual('https://scratch.mit.edu/');
    });

    test('(GH#4064) Project name should be editable', async () => {
        await loadUri(uri);
        const el = await findByXpath('//input[@value="Scratch Project"]');
        await el.sendKeys(' - Personalized');
        await clickText('Costumes'); // just to blur the input
        await clickXpath('//input[@value="Scratch Project - Personalized"]');
    });

    test('User is not warned before uploading project file over a fresh project', async () => {
        await loadUri(uri);
        await clickXpath(FILE_MENU_XPATH);
        await clickText('Load from your computer');
        const input = await findByXpath('//input[@accept=".sb,.sb2,.sb3"]');
        await input.sendKeys(path.resolve(__dirname, '../fixtures/project1.sb3'));
        // No replace alert since no changes were made
        await findByText('project1-sprite');
    });

    test('User is warned before uploading project file over an edited project', async () => {
        await loadUri(uri);

        // Change the project by deleting a sprite
        await rightClickText('Sprite1', scope.spriteTile);
        await clickText('delete', scope.spriteTile);

        await clickXpath(FILE_MENU_XPATH);
        await clickText('Load from your computer');
        const input = await findByXpath('//input[@accept=".sb,.sb2,.sb3"]');
        await input.sendKeys(path.resolve(__dirname, '../fixtures/project1.sb3'));
        await driver.switchTo().alert()
            .accept();
        await findByText('project1-sprite');
    });

    test('Theme picker shows themes', async () => {
        await loadUri(uri);
        await clickXpath(SETTINGS_MENU_XPATH);
        await clickText('Color Mode', scope.menuBar);

        expect(await (await findByText('Original', scope.menuBar)).isDisplayed()).toBe(true);
        expect(await (await findByText('High Contrast', scope.menuBar)).isDisplayed()).toBe(true);
    });

    test('Theme picker switches to high contrast', async () => {
        await loadUri(uri);
        await clickXpath(SETTINGS_MENU_XPATH);
        await clickText('Color Mode', scope.menuBar);
        await clickText('High Contrast', scope.menuBar);

        // There is a tiny delay for the color theme to be applied to the categories.
        await driver.wait(async () => {
            const motionCategoryDiv = await findByXpath(
                '//div[contains(@class, "scratchCategoryMenuItem") and ' +
                'contains(@class, "scratchCategoryId-motion")]/*[1]');
            const color = await motionCategoryDiv.getCssValue('background-color');

            // Documentation for getCssValue says it depends on how the browser
            // returns the value. Locally I am seeing 'rgba(128, 181, 255, 1)',
            // but this is a bit flexible just in case.
            return /128,\s?181,\s?255/.test(color) || color.includes('80B5FF');
        }, 5000, 'Motion category color does not match high contrast theme');
    });

    test('Settings menu switches between submenus', async () => {
        await loadUri(uri);
        await clickXpath(SETTINGS_MENU_XPATH);

        // Language and theme options not visible yet
        expect(await (await findByText('High Contrast', scope.menuBar)).isDisplayed()).toBe(false);
        expect(await (await findByText('Esperanto', scope.menuBar)).isDisplayed()).toBe(false);

        await clickText('Color Mode', scope.menuBar);

        // Only theme options visible
        expect(await (await findByText('High Contrast', scope.menuBar)).isDisplayed()).toBe(true);
        expect(await (await findByText('Esperanto', scope.menuBar)).isDisplayed()).toBe(false);

        await clickText('Language', scope.menuBar);

        // Only language options visible
        expect(await (await findByText('High Contrast', scope.menuBar)).isDisplayed()).toBe(false);
        expect(await (await findByText('Esperanto', scope.menuBar)).isDisplayed()).toBe(true);
    });

    test('Menu labels hidden when width is equal to 1024', async () => {
        await loadUri(uri);
        await driver.manage()
            .window()
            .setSize(1024, 768);

        const collapsibleMenus = ['Settings', 'File', 'Edit', 'Tutorials'];
        for (const menu of collapsibleMenus) {
            const settingsMenu = await findByText(menu, scope.menuBar);
            expect(await settingsMenu.isDisplayed()).toBe(false);
        }
    });

    test('Menu labels shown when width is greater than 1024', async () => {
        await loadUri(uri);
        await driver.manage()
            .window()
            .setSize(1200, 768);

        const collapsibleMenus = ['Settings', 'File', 'Edit', 'Tutorials'];
        for (const menu of collapsibleMenus) {
            const settingsMenu = await findByText(menu, scope.menuBar);
            expect(await settingsMenu.isDisplayed()).toBe(true);
        }
    });
});