Skip to content

Commit

Permalink
Widget resize tests (#3620)
Browse files Browse the repository at this point in the history
  • Loading branch information
ranbena authored Mar 28, 2019
1 parent b3819de commit fe4a7b6
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 10 deletions.
2 changes: 1 addition & 1 deletion client/app/components/dashboards/widget.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
</div>

<div class="body-row clearfix tile__bottom-control">
<a class="small hidden-print" ng-click="$ctrl.refresh()" ng-if="!$ctrl.public">
<a class="small hidden-print" ng-click="$ctrl.refresh()" ng-if="!$ctrl.public" data-test="RefreshIndicator">
<i ng-class='{"zmdi-hc-spin": $ctrl.widget.loading}' class="zmdi zmdi-refresh"></i>
<span am-time-ago="$ctrl.widget.getQueryResult().getUpdatedAt()" ng-if="!$ctrl.widget.loading"></span>
<rd-timer timestamp="$ctrl.widget.refreshStartedAt" ng-if="$ctrl.widget.loading"></rd-timer>
Expand Down
2 changes: 1 addition & 1 deletion client/app/components/parameters.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
ui-sortable="{ 'ui-floating': true, 'disabled': !editable }"
ng-model="parameters"
>
<div class="form-group m-r-10" ng-repeat="param in parameters">
<div class="form-group m-r-10" ng-repeat="param in parameters" data-test="ParameterName{{ param.name }}">
<label class="parameter-label">{{param.title}}</label>
<button class="btn btn-default btn-xs" ng-if="editable" ng-click="showParameterSettings(param, $index)">
<i class="zmdi zmdi-settings"></i>
Expand Down
4 changes: 2 additions & 2 deletions client/app/pages/dashboards/dashboard.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ <h3>
ng-class="{'preview-mode': !$ctrl.layoutEditing, 'editing-mode': $ctrl.layoutEditing}">
<div class="dashboard-widget-wrapper"
ng-repeat="widget in $ctrl.dashboard.widgets track by widget.id"
gridstack-item="widget.options.position" gridstack-item-id="{{ widget.id }}">
<div class="grid-stack-item-content" data-test="WidgetId{{ widget.id }}">
gridstack-item="widget.options.position" gridstack-item-id="{{ widget.id }}" data-test="WidgetId{{ widget.id }}">
<div class="grid-stack-item-content">
<dashboard-widget widget="widget" dashboard="$ctrl.dashboard" on-delete="$ctrl.removeWidget(widget.id)"></dashboard-widget>
</div>
</div>
Expand Down
205 changes: 199 additions & 6 deletions client/cypress/integration/dashboard/dashboard_spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const DRAG_PLACEHOLDER_SELECTOR = '.grid-stack-placeholder';
const RESIZE_HANDLE_SELECTOR = '.ui-resizable-se';


function createNewDashboardByAPI(name) {
return cy.request('POST', 'api/dashboards', { name }).then(({ body }) => body);
Expand Down Expand Up @@ -80,7 +82,7 @@ function addWidgetByAPI(dashId, queryData = {}) {
});
}

function dragBy(wrapper, offsetTop = 0, offsetLeft = 0) {
function dragBy(wrapper, offsetLeft = 0, offsetTop = 0) {
let start;
let end;
return wrapper
Expand All @@ -103,6 +105,34 @@ function dragBy(wrapper, offsetTop = 0, offsetLeft = 0) {
}));
}

function resizeBy(wrapper, offsetLeft = 0, offsetTop = 0) {
let start;
let end;
let from;
const getSize = $el => ({ height: $el.height(), width: $el.width() });

return wrapper
.then(($el) => {
start = getSize($el);
})
.within(() => cy.get(RESIZE_HANDLE_SELECTOR))
.then(($handle) => {
from = $handle.show().offset(); // turn on handle and get it's position
return wrapper
.trigger('mouseover', { force: true })
.trigger('mousedown', { pageX: from.left, pageY: from.top, force: true, which: 1 })
.trigger('mousemove', { pageX: from.left + offsetLeft, pageY: from.top + offsetTop, force: true, which: 1 });
})
.then(() => {
end = getSize(Cypress.$(DRAG_PLACEHOLDER_SELECTOR)); // see comment in dragBy ^^
return wrapper.trigger('mouseup', { force: true });
})
.then(() => ({
height: end.height - start.height,
width: end.width - start.width,
}));
}

describe('Dashboard', () => {
beforeEach(() => {
cy.login();
Expand Down Expand Up @@ -291,19 +321,19 @@ describe('Dashboard', () => {
});

it('stays put when dragged under snap threshold', () => {
dragBy(cy.get('@textboxEl'), 0, 90).then((delta) => {
dragBy(cy.get('@textboxEl'), 90).then((delta) => {
expect(delta.left).to.eq(0);
});
});

it('moves one column when dragged over snap threshold', () => {
dragBy(cy.get('@textboxEl'), 0, 110).then((delta) => {
dragBy(cy.get('@textboxEl'), 110).then((delta) => {
expect(delta.left).to.eq(200);
});
});

it('moves two columns when dragged over snap threshold', () => {
dragBy(cy.get('@textboxEl'), 0, 330).then((delta) => {
dragBy(cy.get('@textboxEl'), 330).then((delta) => {
expect(delta.left).to.eq(400);
});
});
Expand All @@ -316,7 +346,7 @@ describe('Dashboard', () => {
.then(($el) => {
start = $el.offset();
editDashboard();
return dragBy(cy.get('@textboxEl'), 0, 200);
return dragBy(cy.get('@textboxEl'), 200);
})
// cancel
.then(() => {
Expand All @@ -338,7 +368,7 @@ describe('Dashboard', () => {
.then(($el) => {
start = $el.offset();
editDashboard();
return dragBy(cy.get('@textboxEl'), 0, 200);
return dragBy(cy.get('@textboxEl'), 200);
})
// apply
.then(() => {
Expand All @@ -351,6 +381,104 @@ describe('Dashboard', () => {
});
});
});

describe('Resizeable', () => {
describe('Column snap', () => {
beforeEach(() => {
editDashboard();
});

it('stays put when dragged under snap threshold', () => {
resizeBy(cy.get('@textboxEl'), 90).then((delta) => {
expect(delta.width).to.eq(0);
});
});

it('moves one column when dragged over snap threshold', () => {
resizeBy(cy.get('@textboxEl'), 110).then((delta) => {
expect(delta.width).to.eq(200);
});
});

it('moves two columns when dragged over snap threshold', () => {
resizeBy(cy.get('@textboxEl'), 400).then((delta) => {
expect(delta.width).to.eq(400);
});
});
});

describe('Row snap', () => {
beforeEach(() => {
editDashboard();
});

it('stays put when dragged under snap threshold', () => {
resizeBy(cy.get('@textboxEl'), 0, 10).then((delta) => {
expect(delta.height).to.eq(0);
});
});

it('moves one row when dragged over snap threshold', () => {
resizeBy(cy.get('@textboxEl'), 0, 30).then((delta) => {
expect(delta.height).to.eq(50);
});
});

it('shrinks to minimum', () => {
cy.get('@textboxEl')
.then(($el) => {
resizeBy(cy.get('@textboxEl'), -$el.width(), -$el.height()); // resize to 0,0
return cy.get('@textboxEl');
})
.then(($el) => {
expect($el.width()).to.eq(200);
expect($el.height()).to.eq(35);
});
});
});

it('discards resize on cancel', () => {
let start;
cy.get('@textboxEl')
// save initial position, resize textbox 1 col
.then(($el) => {
start = $el.height();
editDashboard();
return resizeBy(cy.get('@textboxEl'), 0, 200);
})
// cancel
.then(() => {
cy.get('.dashboard-header').within(() => {
cy.contains('button', 'Cancel').click();
});
return cy.get('@textboxEl');
})
// verify returned to original size
.then(($el) => {
expect($el.height()).to.eq(start);
});
});

it('saves resize on apply', () => {
let start;
cy.get('@textboxEl')
// save initial position, resize textbox 1 col
.then(($el) => {
start = $el.height();
editDashboard();
return resizeBy(cy.get('@textboxEl'), 0, 200);
})
// apply
.then(() => {
cy.contains('button', 'Apply Changes').click().should('not.exist');
return cy.get('@textboxEl');
})
// verify size change persists
.then(($el) => {
expect($el.height()).to.not.eq(start);
});
});
});
});

describe('Widget', () => {
Expand Down Expand Up @@ -413,6 +541,71 @@ describe('Dashboard', () => {
.should('eq', 335);
});
});

describe('Height behavior on refresh', () => {
const paramName = 'count';
const queryData = {
query: `select s.a FROM generate_series(1,{{ ${paramName} }}) AS s(a)`,
};

beforeEach(function () {
addWidgetByAPI(this.dashboardId, queryData).then((elTestId) => {
cy.visit(this.dashboardUrl);
cy.getByTestId(elTestId).as('widget').within(() => {
cy.getByTestId('RefreshIndicator').as('refreshButton');
});
cy.getByTestId(`ParameterName${paramName}`).within(() => {
cy.get('input').as('paramInput');
});
});
});

it('grows when dynamically adding table rows', () => {
// listen to results
cy.server();
cy.route('GET', 'api/query_results/*').as('FreshResults');

// start with 1 table row
cy.get('@paramInput').clear().type('1');
cy.get('@refreshButton').click();
cy.wait('@FreshResults', { timeout: 10000 });
cy.get('@widget').invoke('height').should('eq', 285);

// add 4 table rows
cy.get('@paramInput').clear().type('5');
cy.get('@refreshButton').click();
cy.wait('@FreshResults', { timeout: 10000 });

// expect to height to grow by 1 grid grow
cy.get('@widget').invoke('height').should('eq', 435);
});

it('revokes auto height after manual height adjustment', () => {
// listen to results
cy.server();
cy.route('GET', 'api/query_results/*').as('FreshResults');

editDashboard();

// start with 1 table row
cy.get('@paramInput').clear().type('1');
cy.get('@refreshButton').click();
cy.wait('@FreshResults');
cy.get('@widget').invoke('height').should('eq', 285);

// resize height by 1 grid row
resizeBy(cy.get('@widget'), 0, 5);
cy.get('@widget').invoke('height').should('eq', 335);

// add 4 table rows
cy.get('@paramInput').clear().type('5');
cy.get('@refreshButton').click();
cy.wait('@FreshResults');

// expect height to stay unchanged (would have been 435)
cy.get('@widget').invoke('height').should('eq', 335);
});
});
});
});
});

0 comments on commit fe4a7b6

Please sign in to comment.