test("Clicking on route handlers and controller sends an inspection message", async function(assert) { let name, message, applicationRow; port.reopen({ send(n, m) { name = n; message = m; if (name === 'route:getTree') { this.trigger('route:routeTree', { tree: routeTree }); } } }); await visit('route-tree'); name = null; message = null; applicationRow = find('.js-route-tree-item'); await click('.js-route-handler', applicationRow); assert.equal(name, 'objectInspector:inspectRoute'); assert.equal(message.name, 'application'); name = null; message = null; await click('.js-route-controller', applicationRow); assert.equal(name, 'objectInspector:inspectController'); assert.equal(message.name, 'application'); name = null; message = null; let postRow = findAll('.js-route-tree-item')[1]; await click('.js-route-controller', postRow); assert.equal(name, null, "If controller does not exist, clicking should have no effect."); assert.equal(message, null); });
test("Send to console", async function (assert) { await visit('/'); let obj = { name: 'My Object', objectId: 'object-id', details: [{ name: 'Own Properties', expand: true, properties: [{ name: 'myProp', value: { inspect: 'Teddy', type: 'type-string', computed: false } }] }] }; await triggerPort('objectInspector:updateObject', obj); await click('.js-send-to-console-btn'); assert.equal(name, 'objectInspector:sendToConsole'); assert.equal(message.objectId, 'object-id'); assert.equal(message.property, 'myProp'); await click('.js-send-object-to-console-btn'); assert.equal(name, 'objectInspector:sendToConsole'); assert.equal(message.objectId, 'object-id'); assert.equal(message.property, undefined); });
test("Object details", async function (assert) { let firstDetail, secondDetail; await visit('/'); await triggerPort('objectInspector:updateObject', objectToInspect()); assert.equal(find('.js-object-name').textContent, 'My Object'); firstDetail = findAll('.js-object-detail')[0]; secondDetail = findAll('.js-object-detail')[1]; assert.equal(find('.js-object-detail-name', firstDetail).textContent, 'First Detail'); assert.notOk(firstDetail.classList.contains('mixin_state_expanded'), 'Detail not expanded by default'); await click('.js-object-detail-name', firstDetail); assert.ok(firstDetail.classList.contains('mixin_state_expanded'), 'Detail expands on click.'); assert.notOk(secondDetail.classList.contains('mixin_state_expanded'), 'Second detail does not expand.'); assert.equal(findAll('.js-object-property', firstDetail).length, 1); assert.equal(find('.js-object-property-name', firstDetail).textContent, 'numberProperty'); assert.equal(find('.js-object-property-value', firstDetail).textContent, '1'); await click('.js-object-detail-name', firstDetail); assert.notOk(firstDetail.classList.contains('mixin_state_expanded'), 'Expanded detail minimizes on click.'); await click('.js-object-detail-name', secondDetail); assert.ok(secondDetail.classList.contains('mixin_state_expanded')); assert.equal(findAll('.js-object-property', secondDetail).length, 2); assert.equal(findAll('.js-object-property-name', secondDetail)[0].textContent, 'objectProperty'); assert.equal(findAll('.js-object-property-value', secondDetail)[0].textContent, 'Ember Object Name'); assert.equal(findAll('.js-object-property-name', secondDetail)[1].textContent, 'stringProperty'); assert.equal(findAll('.js-object-property-value', secondDetail)[1].textContent, 'String Value'); });
test('`pointer-events` is set to `auto` for any step element on clean up', async function(assert) { assert.expect(4); await visit('/'); await click('.toggleHelpModal'); // Go through a step of the tour... await click('[data-id="intro"] .next-button', document.documentElement); // Check the target elements have pointer-events = 'none' // Get the 2 shepherd-target's findAll('.shepherd-target', document.documentElement).map((elem) => { assert.equal(elem.style.pointerEvents, 'none'); }); // Exit the tour await click('[data-id="installation"] .cancel-button', document.documentElement); // Check all the target elements now have pointer-events = 'auto' // Get the 2 shepherd-target's again findAll('.shepherd-target', document.documentElement).map((elem) => { assert.equal(elem.style.pointerEvents, 'auto'); }); });
test('If the options of a multiple select implement `isEqual`, that option is used to determine whether or not two items are the same', function(assert) { let User = EmberObject.extend({ isEqual(other) { return get(this, 'name') === get(other, 'name'); } }); this.search = (term) => { return names.filter((n) => n.indexOf(term) > -1).map((name) => User.create({ name })); }; this.render(hbs` {{#power-select-multiple selected=selected onchange=(action (mut selected)) search=search as |user|}} {{user.name}} {{/power-select-multiple}} `); typeInSearch('M'); click(findAll('.ember-power-select-option')[1]); typeInSearch('Mi'); assert.equal(findAll('.ember-power-select-option')[0].attributes['aria-selected'].value, 'true', 'The item in the list is marked as selected'); click(findAll('.ember-power-select-option')[0]); // select the same user again should i[0])t assert.equal(findAll('.ember-power-select-multiple-option').length, 0); });
it('login dropdown form stays visible when fields are focused', async function() { await visit('/'); await click(LOGIN_DROPDOWN_TOGGLE); expect(find(LOGIN_DROPDOWN)).to.have.class('open'); await click(LOGIN_EMAIL); expect(find(LOGIN_DROPDOWN)).to.have.class('open'); });
test('perform and cancel-all', async function(assert) { assert.expect(3); await visit('/helpers-test'); assert.equal(currentURL(), '/helpers-test'); await click('.perform-task'); assert.equal(find('.task-status').textContent, '1-2-3-4'); await click('.cancel-task'); assert.equal(find('.task-status').textContent, 'canceled'); });
test("it adds sign on calc", async function(assert) { this.set("transactionType", "income"); this.render(hbs`{{transaction-value-input transactionType=transactionType}}`); await click("[data-test-value-display]"); await fillCalcValue("123"); await click('[data-test-calc-key="equals"]'); assert.equal(find("[data-test-value-display]").textContent.trim(), "+123.00"); });
test('Cancel link cancels the tour', async function(assert) { await visit('/'); await click('.toggleHelpModal'); assert.ok(document.body.classList.contains('shepherd-active'), 'Body has class of shepherd-active, when shepherd becomes active'); await click('.shepherd-content a.shepherd-cancel-link', document.documentElement); assert.notOk(document.body.classList.contains('shepherd-active'), 'Body does not have class of shepherd-active, when shepherd becomes inactive'); });
test("it closes the overlay on calc", async function(assert) { this.set("transactionType", "income"); this.render(hbs`{{transaction-value-input transactionType=transactionType}}`); await click("[data-test-value-display]"); assert.ok(find(".ember-modal-dialog"), "The modal is visible"); await fillCalcValue("123"); await click('[data-test-calc-key="equals"]'); assert.notOk(find(".ember-modal-dialog"), "The modal is hidden"); });
test('clicking translucent overlay triggers callback', async function(assert) { window.onClickOverlayCallbackCalled = false; await click('#example-translucent-with-callback button'); await click(overlaySelector); assert.isPresentOnce(overlaySelector); assert.ok(window.onClickOverlayCallbackCalled); await click(dialogCloseButton); assert.isAbsent(overlaySelector); });
test('buttons work when type is not specified and passed action is triggered', async function(assert) { assert.expect(4); let buttonActionCalled = false; const steps = [{ id: 'test-buttons-custom-action', options: { attachTo: { element: '.first-element', on: 'bottom' }, builtInButtons: [ { classes: 'shepherd-button-secondary button-one', text: 'button one' }, { classes: 'shepherd-button-secondary button-two', text: 'button two', action() { buttonActionCalled = true; } }, { classes: 'shepherd-button-secondary button-three', text: 'button three' } ], classes: 'shepherd shepherd-open shepherd-theme-arrows shepherd-transparent-text', copyStyles: false, highlightClass: 'highlight', title: 'Welcome to Ember-Shepherd!', text: ['Testing highlight'] } }]; await visit('/'); tour.set('steps', steps); await click('.toggleHelpModal'); assert.ok(find('.button-one', document.body), 'tour button one is visible'); assert.ok(find('.button-two', document.body), 'tour button two is visible'); assert.ok(find('.button-three', document.body), 'tour button three is visible'); await click(find('.button-two', document.body)); assert.ok(buttonActionCalled, 'button action triggered'); });
test('Selecting and removing should result in desired behavior', function(assert) { assert.expect(3); this.numbers = numbers; this.render(hbs` {{#power-select-multiple options=numbers selected=foo onchange=(action (mut foo)) as |option|}} {{option}} {{/power-select-multiple}} `); clickTrigger(); click(findAll('.ember-power-select-option')[1]); assert.equal(findAll('.ember-power-select-multiple-option').length, 1, 'Should add selected option'); click('.ember-power-select-multiple-remove-btn'); assert.equal(find('.ember-power-select-trigger-multiple-input').attributes.placeholder.value, '', 'Input still does not have a placeholder'); assert.equal(findAll('.ember-power-select-multiple-option').length, 0, 'Should remove selected option'); });
test('in place', async function(assert) { await click('#example-in-place button'); let dialogText = 'In Place'; let inPlaceDialogSelector = `${dialogSelector}.ember-modal-dialog-in-place`; let inPlaceRootSelector = '#container-in-place'; let inPlaceCloseButton = [inPlaceRootSelector, inPlaceDialogSelector, 'button'].join(' '); assert.equal($(dialogSelector).css('position'), 'static', 'not absolutely positioned'); assert.equal($(dialogSelector).css('left'), 'auto', 'should not be positioned (left)'); assert.equal($(dialogSelector).css('margin-left'), '0px', 'should not be positioned (margin-left)'); assert.equal(findContains(`${modalRootElementSelector} ${dialogSelector}`, dialogText), undefined, 'dialog is not open'); assert.ok(findContains(`${inPlaceRootSelector} ${dialogSelector}`, dialogText), 'dialog rendered in place, once'); await click(inPlaceCloseButton); assert.equal(findContains(`${modalRootElementSelector} ${dialogSelector}`, dialogText), undefined, 'dialog is not open'); assert.equal(findContains(`${inPlaceRootSelector} ${dialogSelector}`, dialogText), undefined, 'dialog is not rendered in place'); });
test('copyStyles copies the element correctly', async function(assert) { assert.expect(1); const steps = [{ id: 'intro', options: { attachTo: '.first-element bottom', builtInButtons: [ { classes: 'shepherd-button-secondary cancel-button', text: 'Exit', type: 'cancel' }, { classes: 'shepherd-button-primary next-button', text: 'Next', type: 'next' } ], classes: 'shepherd shepherd-open shepherd-theme-arrows shepherd-transparent-text', copyStyles: true, title: 'Welcome to Ember Shepherd!', text: ['A field that has rested gives a bountiful crop.'], scrollTo: false } }]; await visit('/'); tour.set('steps', steps); await click('.toggleHelpModal'); assert.equal(findAll('.first-element', document.documentElement).length, 2, 'First element is copied with copyStyles'); });
test("it opens a modal on input click", async function(assert) { this.render(hbs`{{transaction-value-input}}`); assert.notOk(find(".ember-modal-dialog")); await click("[data-test-value-display]"); assert.ok(find(".ember-modal-dialog")); });
return wait().then(() => { click('[data-test-task-group]'); assert.ok( taskGroupSpy.withArgs(taskGroup).calledOnce, 'Clicking the task group row calls the gotoTaskGroup action' ); });
test("Reload", async function(assert) { let types = [], instances = []; port.reopen({ send(n, m) { if (n === 'container:getTypes') { this.trigger('container:types', { types }); } if (n === 'container:getInstances' && m.containerType === 'controller') { this.trigger('container:instances', { instances, status: 200 }); } } }); await visit('/container-types/controller'); assert.equal(findAll('.js-container-type').length, 0); assert.equal(findAll('.js-container-instance-list-item').length, 0); types = getTypes(); instances = getInstances(); await click('.js-reload-container-btn'); assert.equal(findAll('.js-container-type').length, 2); assert.equal(findAll('.js-container-instance-list-item').length, 2); });
test("it sets the input val on date selection", async function(assert) { this.render(hbs`{{date-picker}}`); await click("[data-test-date-picker-input]"); await calendarSelect(".ember-power-calendar", new Date(2017, 6, 2)); assert.equal(find("[data-test-date-picker-input]").value, "7/2/2017"); });
test("Stringified json should not get double parsed", async function (assert) { await visit('/'); let obj = { name: 'My Object', objectId: 'object-id', details: [{ name: 'Own Properties', expand: true, properties: [{ name: 'boundProp', value: { inspect: '{"name":"teddy"}', type: 'type-string', computed: false } }] }] }; await triggerPort('objectInspector:updateObject', obj); await click('.js-object-property-value'); let txtField = find('.js-object-property-value-txt'); assert.equal(txtField.value, '"{"name":"teddy"}"'); await fillIn(txtField, '"{"name":"joey"}"'); await keyEvent('.js-object-property-value-txt', 'keyup', 13); assert.equal(name, 'objectInspector:saveProperty'); assert.equal(message.property, 'boundProp'); assert.equal(message.value, '{"name":"joey"}'); assert.equal(message.mixinIndex, 0); });
return settled().then(() => { click('tr.job-row'); assert.ok( gotoJobSpy.withArgs(parent.get('children.firstObject')).calledOnce, 'Clicking the job row calls the gotoJob action' ); });
test('If a group is disabled, any options inside cannot be interacted with mouse', function(assert) { assert.expect(4); let options = [ { groupName: 'Smalls', options: ['one', 'two', 'three'] }, { groupName: 'Mediums', options: ['four', 'five', 'six'] }, { groupName: 'Bigs', disabled: true, options: [ { groupName: 'Fairly big', options: ['seven', 'eight', 'nine'] }, { groupName: 'Really big', options: ['ten', 'eleven', 'twelve'] }, 'thirteen' ] }, 'one hundred', 'one thousand' ]; this.options = options; this.render(hbs` {{#power-select options=options selected=foo onchange=(action (mut foo)) as |option|}} {{option}} {{/power-select}} `); clickTrigger(); assert.equal(find('.ember-power-select-option[aria-current="true"]').textContent.trim(), 'one'); assert.notOk(find('.ember-power-select-option[aria-selected="true"]'), 'No option is selected'); triggerEvent(findAll('.ember-power-select-option')[8], 'mouseover'); assert.equal(find('.ember-power-select-option[aria-current="true"]').textContent.trim(), 'one'); click(findAll('.ember-power-select-option')[9]); assert.notOk(find('.ember-power-select-option[aria-selected="true"]'), 'Noting was selected'); });
test("it adds a class on click", async function(assert) { this.render(hbs`{{transaction-value-input}}`); assert.notOk(findWithAssert("[data-test-transaction-value-input]").classList.contains("focused")); await click("[data-test-value-display]"); assert.ok(findWithAssert("[data-test-transaction-value-input]").classList.contains("focused")); });
test("it opens a modal on input click", async function(assert) { this.render(hbs`{{date-picker}}`); assert.notOk(find(".ember-modal-dialog")); await click("[data-test-date-picker-input]"); assert.ok(find(".ember-modal-dialog")); });
test('task produces a curried version of the task passed into it', async function(assert) { assert.expect(2); this.register('component:my-component', Component.extend({ myTask: task(function * (...args) { assert.deepEqual(args, [1,2,3,4,5,6]); return 999; }), })); this.register('component:inner-component', Component.extend({ click() { return this.get('curriedTask').perform(4,5,6).then(v => { assert.equal(v, 999); }); } })); this.register('template:components/my-component', hbs`{{inner-component id="my-component" curriedTask=(task (task myTask 1 2) 3)}}`); this.render(hbs`{{my-component}}`); await click('#my-component'); });
andThen(() => { const deployment = sortedDeployments.models[0]; const deploymentRow = $(findAll('.timeline-object')[0]); const taskGroupSummaries = deployment.deploymentTaskGroupSummaryIds.map(id => server.db.deploymentTaskGroupSummaries.find(id) ); click(deploymentRow.find('button').get(0)); andThen(() => { assert.equal( $('.deployment-metrics .label:contains("Canaries") + .value') .get(0) .textContent.trim(), `${sum(taskGroupSummaries, 'placedCanaries')} / ${sum( taskGroupSummaries, 'desiredCanaries' )}`, 'Canaries, both places and desired, are in the metrics' ); assert.equal( $('.deployment-metrics .label:contains("Placed") + .value') .get(0) .textContent.trim(), sum(taskGroupSummaries, 'placedAllocs'), 'Placed allocs aggregates across task groups' ); assert.equal( $('.deployment-metrics .label:contains("Desired") + .value') .get(0) .textContent.trim(), sum(taskGroupSummaries, 'desiredTotal'), 'Desired allocs aggregates across task groups' ); assert.equal( $('.deployment-metrics .label:contains("Healthy") + .value') .get(0) .textContent.trim(), sum(taskGroupSummaries, 'healthyAllocs'), 'Healthy allocs aggregates across task groups' ); assert.equal( $('.deployment-metrics .label:contains("Unhealthy") + .value') .get(0) .textContent.trim(), sum(taskGroupSummaries, 'unhealthyAllocs'), 'Unhealthy allocs aggregates across task groups' ); assert.equal( find('.deployment-metrics .notification').textContent.trim(), deployment.statusDescription, 'Status description is in the metrics block' ); }); });
test('breadcrumbs includes allocations and link to the allocation detail page', function(assert) { assert.equal( find('[data-test-breadcrumb="allocations"]').textContent.trim(), 'Allocations', 'Allocations is the first breadcrumb' ); assert.equal( find('[data-test-breadcrumb="allocations"]').getAttribute('href'), '#', "Allocations breadcrumb doesn't link anywhere" ); assert.equal( find('[data-test-breadcrumb="allocation"]').textContent.trim(), allocation.id.split('-')[0], 'Allocation short id is the second breadcrumb' ); assert.equal( find('[data-test-breadcrumb="task"]').textContent.trim(), task.name, 'Task name is the third breadcrumb' ); click('[data-test-breadcrumb="allocation"]'); andThen(() => { assert.equal( currentURL(), `/allocations/${allocation.id}`, 'Second breadcrumb links back to the allocation detail' ); }); });
export function stopJob() { click('[data-test-stop] [data-test-idle-button]'); return wait().then(() => { click('[data-test-stop] [data-test-confirm-button]'); return wait(); }); }
test('each task row should link to the task detail page', function(assert) { const task = server.db.taskStates.where({ allocationId: allocation.id }).sortBy('name')[0]; click('[data-test-task-row] [data-test-name] a'); andThen(() => { assert.equal( currentURL(), `/allocations/${allocation.id}/${task.name}`, 'Task name in task row links to task detail' ); }); andThen(() => { visit(`/allocations/${allocation.id}`); }); andThen(() => { click('[data-test-task-row]'); }); andThen(() => { assert.equal( currentURL(), `/allocations/${allocation.id}/${task.name}`, 'Task row links to task detail' ); }); });
test("Properties are bound to the application properties", async function (assert) { await visit('/'); let obj = { name: 'My Object', objectId: 'object-id', details: [{ name: 'Own Properties', expand: true, properties: [{ name: 'boundProp', value: { inspect: 'Teddy', type: 'type-string', computed: false } }] }] }; await triggerPort('objectInspector:updateObject', obj); assert.equal(find('.js-object-property-value').textContent, 'Teddy'); await triggerPort('objectInspector:updateProperty', { objectId: 'object-id', mixinIndex: 0, property: 'boundProp', value: { inspect: 'Alex', type: 'type-string', computed: false } }); await click('.js-object-property-value'); let txtField = find('.js-object-property-value-txt'); assert.equal(txtField.value, '"Alex"'); await fillIn(txtField, '"Joey"'); await keyEvent('.js-object-property-value-txt', 'keyup', 13); assert.equal(name, 'objectInspector:saveProperty'); assert.equal(message.property, 'boundProp'); assert.equal(message.value, 'Joey'); assert.equal(message.mixinIndex, 0); await triggerPort('objectInspector:updateProperty', { objectId: 'object-id', mixinIndex: 0, property: 'boundProp', value: { inspect: 'Joey', type: 'type-string', computed: false } }); assert.equal(find('.js-object-property-value').textContent, 'Joey'); });