UNPKG

generator-addin

Version:

MyGeotab/Geotab Drive add-in generator

328 lines (275 loc) 10.7 kB
const puppeteer = require('puppeteer'); const mocks = require('./mocks/mocks.js'); const assert = require('chai').assert; // JSON-RPC helpers const rpcRequest = body => { let decodedBody = decodeURIComponent(body); let json = decodedBody.replace('JSON-RPC=', ''); return JSON.parse(json); }; const rpcResponse = (response, err) => { return { id: -1, result: response, error: err }; }; // puppeteer options const opts = { headless: true, slowMo: 0, timeout: 10000 }; // test describe('User visits addin', () => { let browser, page; // Open Page before(async () => { browser = await puppeteer.launch(opts); page = await browser.newPage(); // Allowing puppeteer access to the request - needed for mocks await page.setRequestInterception(true); // Setup mocks await page.on('request', request => { if (request.url() === `http://${mocks.server}/apiv1`) { let rpcBody = rpcRequest(request.postData()); let payload = ''; switch (rpcBody.method) { case 'Authenticate': payload = mocks.credentials; break; case 'Get': switch (rpcBody.params.typeName) { case 'Group': payload = mocks.groups; break; case 'Device': payload = [mocks.device]; break; case 'User': payload = [mocks.user]; break; } } request.respond({ content: 'application/json', headers: { 'Access-Control-Allow-Origin': '*' }, body: JSON.stringify(rpcResponse(payload)) }); } else { request.continue(); } }); // Login await page.goto('http://localhost:9000/'); let loggedIn = await page.evaluate( () => { let dialogWindow = document.getElementById('loginDialog'); return (dialogWindow.style.display = 'none' ? true : false); }) if(loggedIn){ await page.click('#logoutBtn'); } await page.waitForSelector('#loginDialog'); await page.type('#email', mocks.login.userName); await page.type('#password', mocks.login.password); await page.type('#database', mocks.login.database); await page.type('#server', mocks.server); await page.click('#loginBtn'); }); // Confirm page has loaded it('should be loaded', async () => { await page.waitForSelector('html', { visible: true }); }); // Confirm page displaying after initialized and focus is called it('should display root div', async () => { <% if (!isDriveAddin) { %> await page.waitForSelector('#<%= root %>', { visible: true }); <% } else { %> await page.waitForSelector('#app', { visible: false }); <% } %> }); <% if (!isDriveAddin) { %> <% if (!isButton) { %> // Navbar tests it('should have a navbar', async () => { let navbar = await page.$('#menuId') !== null; assert.isTrue(navbar, 'Navbar does not exist'); }); it('nav bar should collapse', async () => { await page.click('#menuToggle'); let collapsed = await page.evaluate( () => { let nav = document.querySelector('#menuId'); return nav.className.includes('menuCollapsed'); }); assert.isTrue(collapsed, 'Navbar does not collapse'); }); it('nav bar should extend from collapsed state', async () => { await page.click('#menuToggle'); let extended = await page.evaluate( () => { let nav = document.querySelector('#menuId'); return !nav.className.includes('menuCollapsed'); }); assert.isTrue(extended, 'Navbar did not re-extend'); }); it('blur button should blur addin', async () => { await page.click('#toggleBtn'); let hidden = await page.evaluate( () => { let toggled = false; let addin = document.getElementById('<%= root%>'); if(addin.className.includes('hidden')){ toggled = true; } return toggled; }); assert.isTrue(hidden, 'add-in is hidden'); }); it('focus button should focus addin', async () => { await page.click('#toggleBtn'); let hidden = await page.evaluate( () => { let toggled = false; let addin = document.getElementById('<%= root%>'); if(addin.className.includes('hidden')){ toggled = true; } return toggled; }); assert.isFalse(hidden, 'add-in is hidden'); }); // Group Search logic it('should open the group display box', async () => { await page.click('#group-toggle-button'); await page.waitForSelector('#group-dropdown', { visible: true }); // Cleanup. await page.click('#group-toggle-button'); }); it('should close the group display box', async () => { await page.click('#group-toggle-button'); await page.click('#group-toggle-button'); await page.waitForSelector('#group-dropdown', { visible: false }); }); it('should populate the group dropdown', async () => { await page.click('#group-toggle-button'); await page.waitForSelector('#group-dropdown', { visible: true }); let children = await page.$eval('#group-dropdown-ul', el => el.children); assert.isTrue(Object.keys(children).length === 2, 'Group dropdown is not populated.'); // Cleanup. await page.click('#group-toggle-button'); }); it('should close the group dropdown when clicking off of the group-wrapper', async () => { await page.click('#group-toggle-button'); await page.waitForSelector('#group-dropdown', { visible: true }); await page.click('#checkmateContent'); await page.waitForSelector('#group-dropdown', { visible: false }); let dropdownDisplay = await page.$eval('#group-dropdown', el => el.style.display); assert.isTrue(dropdownDisplay === 'none', 'Dropdown display value is ' + dropdownDisplay); await page.click('#group-toggle-button'); }); it('should filter the group dropdown', async () => { let enterKey = 'Enter'; await page.click('#group-toggle-button'); await page.type('#group-input', 'child'); await page.keyboard.press(enterKey); let children = await page.$eval('#group-dropdown-ul', el => el.children); // Check to make sure the entire dictionary is searched, not just the root node. assert.isTrue(Object.keys(children).length === 3, 'Search did not return all related groups'); // Cleanup. await page.click('#group-toggle-button'); }); // Should notify when not working? it('should store active groups in the state', async () => { let enterKey = 'Enter'; await page.click('#group-toggle-button'); await page.type('#group-input', 'child'); await page.keyboard.press(enterKey); await page.waitForSelector('#group-dropdown-ul', { visible: true }); await page.click('#group-use-b4-label'); let activeGroups = await page.evaluate( async () => { return state.getGroupFilter(); }); assert.isTrue(activeGroups.length === 1); assert.isTrue(activeGroups[0].id === 'b4'); // Cleanup. await page.click('#group-toggle-button'); }); it('should refocus after group filter is selected', async () => { let originalFocus = await page.evaluate( () => geotab.addin.<%= root%>.focus); await page.click('#group-toggle-button'); await page.evaluate( () => { geotab.addin.<%= root%>.count = 0; geotab.addin.<%= root%>.focus = () => { geotab.addin.<%= root%>.count++; }; }); await page.click('#group-use-b4-label'); let invocations = await page.evaluate( () => { return geotab.addin.<%= root%>.count; }); assert.isTrue(invocations === 1, 'Incorrect number of invocations on focus().'); // Undoing state modifications for future tests. await page.evaluate( (addinFocus) => { geotab.addin.<%= root%>.focus = addinFocus; }, originalFocus); }); <% } %> <% } %> // Mock function tests it('should authenticate api', async () => { let success = await page.evaluate( () => { let authenticated = false; api.getSession( (credentials, server) => { if(server !== 'undefined' && credentials !== 'undefined'){ authenticated = true; } }); return authenticated; }); assert.isTrue(success, 'api is not authenticating properly'); }) it('add-in should exist in geotab object', async () => { let keyLength = await page.evaluate( () => { <% if (isButton) { %> let len = Object.keys(geotab.customButtons).length <% } else { %> let len = Object.keys(geotab.addin).length <% } %> return len; }); assert.isTrue(keyLength > 0, `Add-in is not present in mock backend`); }); it('should load the state object', async () => { let state = await page.evaluate( () => { let stateExists = typeof state == 'object'; return stateExists; }); assert.isTrue(state, 'State is not defined'); }); // Tests Finished after(async () => { await browser.close(); }); <% if (isDriveAddin) { %> // Optional setup for Drive apps -> Selecting the device used // select a device (only part of local add-in debugging) before(async () => { await page.select('select#devices', mocks.device.id); await page.click('#okBtn'); }); <% } %> });