SlickGrid Selenium Automation Issues - selenium-webdriver

I am trying to interact with slick grid and I used the below code
JavascriptExecutor js = (JavascriptExecutor)driver;
//Returns the DIV element matching class grid-canvas, which contains every data row currently being rendered in the DOM.
WebElement rowCount = (WebElement) js.executeScript("return grid.getCanvasNode();");
but it is returning the error saying grid not defined.
I figured out that I have to define the grid for getting the above code to work.
The definition of the grid is as below which has to be defined
var grid;
var columns = [
{id: "Date", name: "Date", field: "Date"},
{id: "tpn", name: "tpn", field: "tpn"},
];
var options = {
enableCellNavigation: true,
enableColumnReorder: true,
explicitInitialization: true
};
$(function () {
var data = [];
for (var i = 0; i < 500; i++) {
data[i] = {
Date: "20180612",
SPN:Math.random(),
};
var myGrid = $("<div id='MovementTracker' style='height: 399px; overflow: hidden; outline: 0px; position: relative;'></div>");
grid = new Slick.Grid(myGrid, data, columns, options);
myGrid.appendTo($("#app > div > div > div > div > div.size--5.padding--horizontal--double > div.size--content > div > div > div"));
grid.init();
As the definition is multiline, I am struck here how to execute this multiline javascript code in selenium to make grid initialised.
Any help would be much appreciated

This is all about Javascript scope.
I know SlickGrid, but not Selenium. The grid variable is presumably a member of Document because it's not explicitly scoped. If Selenium executes in a different scope, you'd have to reference it as a member of Document. But it depends on the order of creation of the various scopes and objects.

Related

How to make a custom legend in angular-chart.js Pie Chart

I used angular-chart.js in my website to create a Pie chart, and I would like to customize the legend. By default, the legend shows the color and the label. (As shown in the picture below) I would like to add the value/data of that label, like what it shown in the tooltip of the chart.
This is my HTML code:
<canvas id="pie" class="chart chart-pie"
chart-data="chartData" chart-labels="chartLabels" chart-options="chartOptions">
</canvas>
Based on the angular-chart.js documentation, legend is now a Chart.js option so the chart-legend attribute has been removed.
That is why, in my JS code I've tried to add generateLabels, just in case this is what I need to customize the legend:
$scope.chartOptions = {
legend: {
display: true,
labels: {
generateLabels: function(chart){
console.log(chart.config);
}
}
}
};
But whenever I add this lines, it will not show the chart. I think it is an error or something. And I'm not sure, if generateLabels is the right option that I needed.
Can somebody teach me the right way to customize the legend to achieve what I wanted?
Thanks in advance!
Let me try shedding some light/answering your question:
generateLabels: does make custom labels,and replaces templates from v1 but in order to use it you have to get your chart information and reimplement legend labels adhering to the Legend Item Interface found in the docs and code. Sounds a bit cryptic, but in practice is somehow simple and goes like this:
var theHelp = Chart.helpers;
// You need this for later
// Inside Options:
legend: {
display: true,
// generateLabels changes from chart to chart, check the source,
// this one is from the doughnut :
// https://github.com/chartjs/Chart.js/blob/master/src/controllers/controller.doughnut.js#L42
labels: {
generateLabels: function(chart) {
var data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
var meta = chart.getDatasetMeta(0);
var ds = data.datasets[0];
var arc = meta.data[i];
var custom = arc && arc.custom || {};
var getValueAtIndexOrDefault = theHelp.getValueAtIndexOrDefault;
var arcOpts = chart.options.elements.arc;
var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor);
var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor);
var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth);
return {
// And finally :
text: ds.data[i] + "% of the time " + label,
fillStyle: fill,
strokeStyle: stroke,
lineWidth: bw,
hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
index: i
};
});
}
return [];
}
}
}
Result:
Codepen: Chart.js Pie Chart Custom Legend Labels
There are other alternatives, if you notice on the pen/pie, the slices also have data information, that is from a plugin (check the pen)
Still another option, is to render the legend labels off canvas,for instance:
myPieChart.generateLegend();
Which gives you this Html:
"<ul class='0-legend'><li><span style='background-color:black'> </span>she returns it </li><li><span style='background-color:white'></span>she keeps it</li></ul>"
I haven't tried it, but I think you can modify it with the global method for your data Legend on the callback an it will give you a block of Html you can insert off canvas.

jQuery UI Draggable / Sortable 4 column w/ CSS Transitions - Erratic Behavior

I am creating a simple drag and drop layout that incorporates 4 columns with the use of CSS easing effects when positioning. I have tried multiple solutions but nothing solves the problem. Eventually this will be an angularjs app.
Heres the JSfiddle (this is four columns so spread your browser to view the whole layout)
You will notice when you drag a module that sometimes it will let you snap to the grid and show the "placeholder" and some times it won't.
Sometimes the ".placeholder" which is the ".marker" in my example will randomly place the .marker div above the containing li elements causing this to happen.
Link to marker image
Is there a way to force the element to always be on the bottom element of all the li items of a parent ul?
Any help would be greatly appreciated!
var stylesheet = $('style[name=impostor_size]')[0].sheet;
var rule = stylesheet.rules ? stylesheet.rules[0].style : stylesheet.cssRules[0].style;
var setPadding = function(atHeight) {
rule.cssText = 'border-top-width: '+atHeight+'px';
};
$('.button-up').click(function(){
updateWidgetData();
});
$('.main-area ul').sortable({
connectWith: '.column',
cursor: 'move',
placeholder: 'marker',
forcePlaceholderSize: true,
opacity: 0.4,
start: function(event, ui){
setPadding(ui.item.height());
},
stop: function(event, ui){
ui.item.css({'top':'0','left':'0'}); //Opera fix
if(!$.browser.mozilla && !$.browser.safari)
updateWidgetData();
var next = ui.item.next();
next.css({'-moz-transition':'none', '-webkit-transition':'none', 'transition':'none'});
setTimeout(next.css.bind(next, {'-moz-transition':'border-top-width 0.1s ease-in', '-webkit-transition':'border-top-width 0.1s ease-in', 'transition':'border-top-width 0.1s ease-in'}));
}
}).disableSelection();
function updateWidgetData() {
var items = [];
$('.column').each(function() {
var columnId=$(this).attr('id');
$('.dragbox', this).each(function(i) {
var item = {
id: $(this).attr('id'),
order : i,
column: columnId
};
items.push(item);
});
});
var sortorder = { items: items };
//Pass sortorder variable to server using ajax to save state
$.post('updatePanels.php', 'data='+$.toJSON(sortorder), function(response) {
if(response=="success")
$("#console").html('<div class="success">Saved</div>').hide().fadeIn(1000);
setTimeout(function() {
$('#console').fadeOut(1000);
}, 2000);
});
}

ExtJS 4 Chart - Change with Ajax store

I have some trouble with my app. I have a chart and the data are loaded from a store who make an Ajax connection.
The first time I load my page it work fine but I have three buttons and my goal is to load a new chart to replace the previous when someone click on a button but this doesn't work like I want. I have some bugs and I want to know if there a "official" way to do what I want to do.
I have an error:
Error : TypeError: me.labels[inflections.length - 1] is undefined
Source File : extjs-4.1.0/ext-all-debug.js
Ligne : 58728
When someone click on a button I do this:
var el = Ext.get('GraphVolumeBar03');
if(!el) {
var elem = Ext.create('Axiastats.view.GraphVolumeBar03');
Ext.create('Ext.panel.Panel', {
id : 'GraphVolumeBar03',
renderTo: 'graphContainer-body',
height : 300,
border: false,
items: elem,
});
}
else {
el.show();
Ext.getCmp('GraphVolumeBar03-chart').redraw(true);
}
And I hide the old charts but I don't think it's the right solution:
var el2 = Ext.get('GraphVolumeBar01');
if(el2) { el2.hide(); }
var el3 = Ext.get('GraphVolumeBar02');
if(el3) { el3.hide(); }

How to query current expanded item in accordion layout

OK, so here is the way I can find current collapsed in accordion layout:
Ext.getCmp("myaccordion").query("{collapsed}")
How in the same manner I can find expanded one? I can't see expanded property. Moreover, this code:
Ext.getCmp("myaccordion").query("not:{collapsed}")
crushes my browser down.
UPD: here is my decision, based on example in ExtJS docs:
Ext.ComponentQuery.pseudos.expanded = function(items) {
var res = [];
for (var i = 0, l = items.length; i < l; i++) {
if (!items[i].collapsed) {
res.push(items[i]);
}
}
return res;
};
And then I just query this way Ext.getCmp("myaccordion").query(">*:expanded")
But can we make it shorter, using :not somehow?
You don't have to use a function for this component query.
If you have other panels somewhere in your framework that are not collapsed query('[collapsed=false]') would also include those so that was probably the problem you were having.
But you can limit the query to only direct children by calling child instead:
Ext.getCmp("myaccordion").child("[collapsed=false]");
Or you can limit it to direct children in the selector string itself if you give the accordion an id config, as it looks like you did: (id: 'myaccordion'). You can use:
Ext.ComponentQuery.query('#myaccordion > panel[collapsed=false]')
If you have the accordion configured for only one expanded panel at a time (the default config) that will give you an array with one item - the expanded panel. If you have more than one expanded panel they will each be contained in the array.
You could do:
Ext.onReady(function(){
var p1 = Ext.create('Ext.panel.Panel', {
renderTo: document.body,
width: 100,
height: 100,
title: 'Foo',
collapsed: true
});
var p2 = Ext.create('Ext.panel.Panel', {
renderTo: document.body,
width: 100,
height: 100,
title: 'Foo',
collapsed: false
});
console.log(Ext.ComponentQuery.query('[collapsed=false]'));
});

How do I hide the top toolbar of a Ext.Panel? (ExtJS 2.0)

For some reason Ext.Panel.getTopToolbar() is returning an array of objects (the elements of the toolbar, but NOT the toolbar itself) and not an Ext.Toolbar. Because of that, I can't manage to hide an already set toolbar. How should I proceed?
Sample code:
function (panel)
{
alert(panel.getTopToolbar()); // displays the list of elements in the toolbar
panel.getTopToolbar().hide(); // error: "hide" is not a function
}
It should work, so it sounds like maybe you used topToolbar as a config instead of using tbar as the config? If you set a tbar config it gets instantiated and saved as topToolbar which is the Ext.Toolbar instance exposed by getTopToolbar(). If you overwrote topToolbar directly you might see this issue.
You might find this block of code in Panel.onRender (you'll have to include that file directly) and set a breakpoint in Firebug to see what's happening:
if(this.tbar && this.topToolbar){
if(this.topToolbar instanceof Array){
this.topToolbar = new Ext.Toolbar(this.topToolbar);
}
this.topToolbar.render(this.tbar);
}
panel.getTopToolbar().setVisible(false);
In 4.2.1 what works for me is:
var topToolbar = Ext.create('Ext.toolbar.Toolbar', {
dock: 'top',
width: 'auto',
id: 'mytoolbar',
hidden: true,
items: [...]
});
var p = Ext.create('App.view.MyCustomPanel', {
html: 'test',
});
if (userCanSeeToolbar) {
p.addDocked(topToolbar);
}
Then dynamically I can show/hide the top toolbar:
/* if (userCanSeeToolbar) { */
p.getDockedComponent('mytoolbar').show();
p.getDockedComponent('mytoolbar').hide();

Resources