123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277 |
- import path from 'path';
- import SeleniumHelper from '../helpers/selenium-helper';
- const {
- clickText,
- clickButton,
- clickXpath,
- findByText,
- findByXpath,
- getDriver,
- getLogs,
- loadUri,
- rightClickText,
- scope
- } = new SeleniumHelper();
- const uri = path.resolve(__dirname, '../../build/index.html');
- let driver;
- describe('Working with the blocks', () => {
- beforeAll(() => {
- driver = getDriver();
- });
- afterAll(async () => {
- await driver.quit();
- });
- test('Blocks report when clicked in the toolbox', async () => {
- await loadUri(uri);
- await clickText('Code');
- await clickText('Operators', scope.blocksTab);
- await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
- await clickText('join', scope.blocksTab); // Click "join <hello> <world>" block
- await findByText('apple banana', scope.reportedValue); // Tooltip with result
- const logs = await getLogs();
- await expect(logs).toEqual([]);
- });
- test('Switching sprites updates the block menus', async () => {
- await loadUri(uri);
- await clickText('Sound', scope.blocksTab);
- await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
- // "Meow" sound block should be visible
- await findByText('Meow', scope.blocksTab);
- await clickText('Backdrops'); // Switch to the backdrop
- // Now "pop" sound block should be visible and motion blocks hidden
- await findByText('pop', scope.blocksTab);
- await clickText('Motion', scope.blocksTab);
- await findByText('Stage selected: no motion blocks');
- const logs = await getLogs();
- await expect(logs).toEqual([]);
- });
- test('Creating variables', async () => {
- await loadUri(uri);
- await clickText('Code');
- await clickText('Variables', scope.blocksTab);
- await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
- // Expect a default variable "my variable" to be visible
- await clickText('my\u00A0variable', scope.blocksTab);
- await findByText('0', scope.reportedValue);
- await clickText('Make a Variable');
- let el = await findByXpath("//input[@name='New variable name:']");
- await el.sendKeys('score');
- await clickButton('OK');
- await clickText('Make a Variable');
- el = await findByXpath("//input[@name='New variable name:']");
- await el.sendKeys('second variable');
- await clickButton('OK');
- // Make sure reporting works on a new variable
- await clickText('Variables', scope.blocksTab);
- await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
- await clickText('score', scope.blocksTab);
- await findByText('0', scope.reportedValue); // Tooltip with result
- // And there should be a monitor visible
- await rightClickText('score', scope.monitors);
- await clickText('slider');
- await findByXpath("//input[@step='1']");
- // Changing the slider to a decimal should make it have a step size of 0.01
- await rightClickText('score', scope.monitors);
- await clickText('change slider range');
- el = await findByXpath("//input[@name='Maximum value']");
- await el.sendKeys('.1');
- await clickButton('OK');
- await findByXpath("//input[@step='0.01'][@max='100.1']");
- const logs = await getLogs();
- await expect(logs).toEqual([]);
- });
- test('Creating a list', async () => {
- await loadUri(uri);
- await clickText('Code');
- await clickText('Variables', scope.blocksTab);
- await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
- await clickText('Make a List');
- let el = await findByXpath("//input[@name='New list name:']");
- await el.sendKeys('list1');
- await clickButton('OK');
- // Click the "add <thing> to list" block 3 times
- await clickText('add', scope.blocksTab);
- await clickText('add', scope.blocksTab);
- await clickText('add', scope.blocksTab);
- await clickText('list1', scope.blocksTab);
- await findByText('thing thing thing', scope.reportedValue); // Tooltip with result
- // Interact with the monitor, adding an item
- await findByText('list1', scope.monitors); // Just to be sure it is there
- await clickText('+', scope.monitors);
- el = await findByXpath(`//body//${scope.monitors}//input`);
- await el.sendKeys('thing2');
- await el.click(); // Regression for "clicking active input erases value" bug.
- await clickText('list1', scope.monitors); // Blur the input to submit
- // Check that the list value has been propagated.
- await clickText('list1', scope.blocksTab);
- await findByText('thing thing thing thing2', scope.reportedValue); // Tooltip with result
- const logs = await getLogs();
- await expect(logs).toEqual([]);
- });
- test('Custom procedures', async () => {
- await loadUri(uri);
- await clickText('My Blocks');
- await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
- await clickText('Make a Block');
- // Click on the "add an input" buttons
- await clickText('number or text', scope.modal);
- await clickText('boolean', scope.modal);
- await clickText('Add a label', scope.modal);
- await clickText('OK', scope.modal);
- // Make sure a "define" block has been added to the workspace
- await findByText('define', scope.blocksTab);
- const logs = await getLogs();
- await expect(logs).toEqual([]);
- });
- test('Adding an extension', async () => {
- await loadUri(uri);
- await clickXpath('//button[@title="Add Extension"]');
- await clickText('Pen');
- await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
- // Make sure toolbox has been scrolled to the pen extension
- await findByText('stamp', scope.blocksTab);
- const logs = await getLogs();
- await expect(logs).toEqual([]);
- });
- test('Record option from sound block menu opens sound recorder', async () => {
- await loadUri(uri);
- await clickText('Code');
- await clickText('Sound', scope.blocksTab);
- await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for scroll animation
- await clickText('Meow', scope.blocksTab); // Click "play sound <Meow> until done" block
- await clickText('record'); // Click "record..." option in the block's sound menu
- // Access has been force denied, so close the alert that comes up
- await driver.sleep(1000); // getUserMedia requests are very slow to fail for some reason
- await driver.switchTo().alert()
- .accept();
- await findByText('Record Sound'); // Sound recorder is open
- const logs = await getLogs();
- await expect(logs).toEqual([]);
- });
- test('Renaming costume changes the default costume name in the toolbox', async () => {
- await loadUri(uri);
- // Rename the costume
- await clickText('Costumes');
- await clickText('costume2', scope.costumesTab);
- const el = await findByXpath("//input[@value='costume2']");
- await el.sendKeys('newname');
- // Make sure it is updated in the block menu
- await clickText('Code');
- await clickText('Looks', scope.blocksTab);
- await driver.sleep(500); // Wait for scroll to finish
- await clickText('newname', scope.blocksTab);
- });
- test('Renaming costume with a special character should not break toolbox', async () => {
- await loadUri(uri);
- // Rename the costume
- await clickText('Costumes');
- await clickText('costume2', scope.costumesTab);
- const el = await findByXpath("//input[@value='costume2']");
- await el.sendKeys('<NewCostume>');
- // Make sure it is updated in the block menu
- await clickText('Code');
- await clickText('Looks', scope.blocksTab);
- await driver.sleep(500); // Wait for scroll to finish
- await clickText('<NewCostume>', scope.blocksTab);
- await clickText('Sound', scope.blocksTab);
- });
- test('Adding costumes DOES update the default costume name in the toolbox', async () => {
- await loadUri(uri);
- // By default, costume2 is in the costume tab
- await clickText('Looks', scope.blocksTab);
- await driver.sleep(500); // Wait for scroll to finish
- await clickText('costume2', scope.blocksTab);
- // Also check that adding a new costume does update the list
- await clickText('Costumes');
- const el = await findByXpath('//button[@aria-label="Choose a Costume"]');
- await driver.actions().mouseMove(el)
- .perform();
- await driver.sleep(500); // Wait for thermometer menu to come up
- await clickXpath('//button[@aria-label="Paint"]');
- await clickText('costume3', scope.costumesTab);
- // Check that the menu has been updated
- await clickText('Code');
- await clickText('costume3', scope.blocksTab);
- });
- // Skipped because it was flakey on travis, but seems to run locally ok
- test.skip('Adding a sound DOES update the default sound name in the toolbox', async () => {
- await loadUri(uri);
- await clickText('Sounds');
- await clickXpath('//button[@aria-label="Choose a Sound"]');
- await clickText('A Bass', scope.modal); // Should close the modal
- await clickText('Code');
- await clickText('Sound', scope.blocksTab);
- await driver.sleep(500); // Wait for scroll to finish
- await clickText('A\u00A0Bass', scope.blocksTab); // Need for block text
- });
- // Regression test for switching between editor/player causing toolbox to stop updating
- test('"See inside" after being on project page re-initializing variables', async () => {
- const playerUri = path.resolve(__dirname, '../../build/player.html');
- await loadUri(playerUri);
- await clickText('See inside');
- await clickText('Variables');
- await driver.sleep(500); // Wait for scroll to finish
- await clickText('my\u00A0variable');
- await clickText('See Project Page');
- await clickText('See inside');
- await clickText('Variables');
- await driver.sleep(500); // Wait for scroll to finish
- await clickText('my\u00A0variable');
- });
- // Regression test for switching editor tabs causing toolbox to stop updating
- test('Creating variables after adding extensions updates the toolbox', async () => {
- await loadUri(uri);
- await clickText('Costumes');
- await clickText('Code');
- await clickText('Variables', scope.blocksTab);
- await driver.sleep(500); // Wait for scroll
- await clickText('Make a List');
- const el = await findByXpath("//input[@name='New list name:']");
- await el.sendKeys('list1');
- await clickButton('OK');
- await clickText('list1', scope.blocksTab);
- });
- });
|