I'm new to mobile automation, but not new to automation in general (worked with web). I'm building an automation where a two-finger zoom is required. I've looked through documentation trying to find a solution, and can't find one. There is Multi-Touch, but it's a misnomer because it seems to implement many different touches with one finger only in quick succession. Something like this doesn't appear to work:
client.touchMultiPerform([
[{ action: 'press', options: { x: 300, y: 100 } },
{ action: 'moveTo', options: { x: 100, y: 100 } },
{ action: 'release' },
],
[{ action: 'press', options: { x: 330, y: 100 } },
{ action: 'moveTo', options: { x: 400, y: 100 } },
{ action: 'release' },
],
]);
This does the first touch action, then the second touch action. Is there a method that allows this? Maybe a plugin? Or am I just not understanding a remarkably simple solution?
Here's a more complete example of what I've built:
var webdriverio = require('webdriverio');
var expect = require('chai').expect;
var config = require('./helpers/desiredCapabilities').options;
var client = webdriverio.remote(config);
describe('Android Script Testing', function () {
before(function () {
this.timeout(5000);
return client.init();
});
afterEach(function(){
this.timeout(5000);
});
it("should just click on things",async function(){
this.timeout(0);
client.click("#selectRegionButton")
client.waitForVisible("#Account", 5000).click("#Account");
client.touchAction(
[
[{ action: 'press', options: { x: 300, y: 100 } },
{ action: 'moveTo', options: { x: 100, y: 100 } },
{ action: 'release' }],
[{ action: 'press', options: { x: 330, y: 100 } },
{ action: 'moveTo', options: { x: 400, y: 100 } },
{ action: 'release' }],
]);
});
});
I'm not sure you are using Appium here, but if there is Appium in use then zoom and pinch will only work with Espresso Automation name in the desired capabilities.
Same is confirmed here and I have also tested the same using Espresso Automation name in Appium Java binding.
Try using the same automation name and your code should work.
Also, you have used client.touchAction in your code, instead use client.touchMultiPerform.
Related
Using Quagga.js, we are working on barcode recognition in web view.
It works fine on the mobile web, but it happens on the APP.
The problem is two things below.
The target div provided by Quagga does not contain the camera, but switches to the full screen.
Problem 1 Image
After barcode recognition, the camera remains in the Blackscreen state, not off.
Problem 1 Image
Already unpacked permissions from info.plist.
Privacy - Camera Usage Description
Privacy - Photo Library Additions Usage Description
Below is my code.
openItem.addEventListener("click", () => {
document.querySelector(".barcode_Camera").style.bottom = "0px";
/* Barcode Scan Script */
Quagga.init({
inputStream: {
type : "LiveStream",
target: document.querySelector('#camera_Area'), // Or '#yourElement' (optional)
constraints: {
width: {min: 1280},
height: {min: 480},
facingMode: "environment",
aspectRatio: {min: 1, max: 2}
}
},
locator: {
patchSize: "small",
halfSample: true
},
numOfWorkers: 4,
frequency: 10,
decoder: {
readers : [{
format: "code_93_reader",
config: {}
}],
debug: {
drawBoundingBox: false,
showFrequency: false,
drawScanline: false,
showPattern: false
},
multiple: false
},
}, function (err) {
if (err) {
console.log(err);
return
}
console.log("Initialization finished. Ready to start");
Quagga.start();
});
}); /*Close*/
Quagga.onProcessed(function (result) {
let drawingCtx = Quagga.canvas.ctx.overlay,
drawingCanvas = Quagga.canvas.dom.overlay;
if (result) {
if (result.boxes) {
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")),
parseInt(drawingCanvas.getAttribute("height")));
result.boxes.filter(function (box) {
return box !== result.box;
}).forEach(function (box) {
Quagga.ImageDebug.drawPath(box, {x: 0, y: 1}, drawingCtx, {color: "#88d147", lineWidth: 2});
});
}
}
});
Quagga.onDetected(function (data) {
document.querySelector('#barcode').value = data.codeResult.code;
let closeTarget = closeItem.closest(".barcode_Camera");
document.querySelector(".barcode_Camera").style.bottom = "-100%";
Quagga.stop();
});
I would like to ask for your help if there is anything else I need to do in the info.plist or how I can solve the problem.
I'm using a Apexchart Timeline and I need to pass a custom url from each bar on click.
Here is an example of the series:
series: [{
name: "series"
data: [{
x: "element 1"
y: 10
z: "https://google.com"
}, {
x: "element 2"
y: 20
z: "https://yahoo.com"
}]
}, {
name: "series2"
data: [{
x: "element 3"
y: 10
z: "https://stackoverflow.com"
}]
}],
I'm trying to buil the onclick event
chart: {
type: 'rangeBar',
events: {
dataPointSelection: function(event, chartContext, config) {
window.location = obj.w.config.series[obj.seriesIndex].data[obj.dataPointIndex].z;
}
}
}
But it doesn't works..
Any idea how to fix it?
I tried also with this:
events: {
dataPointSelection: function(event, chartContext, config) {
return document.location.href = obj.w.config.series[obj.seriesIndex].data[obj.dataPointIndex].z;
}
}
No way
You should rename config into obj:
events: {
dataPointSelection: function(event, chartContext, obj) {
return document.location.href = obj.w.config.series[obj.seriesIndex].data[obj.dataPointIndex].z;
}
}
We're currently generating a polar chart in HighCharts that renders correctly on the client-side (in the browser), and correctly applies formatters to the xAxis, yAxis, and plotOptions. Here is a jsFiddle that shows how it is rendering (correctly) in the browser: https://jsfiddle.net/cmodzelewski/38f03Lse/1/
On the server side, we are constructing a JSON payload and sending it to a node-export-server instance and returning a PNG. Based on our research, it is clear that formatters need to be included in the callback key of our JSON payload and passed to the server as a string, rather than in the infile key.
That's fine, and so we're converting our formatter functions into strings, composing them into the options object in our callback key, and then redrawing the chart at the end of our callback key.
This approach works great for non-polar charts, but if polar == true the export server returns a valid PNG from the export server, however that chart does not apply our formatter functions to the xAxis, yAxis, or plotOptions.series.
Here is the JSON payload that we are sending to a node-export-server instance:
{
"callback": "function (chart) {var options = chart.options;var xAxisFormatter = function () { var extra_hrs = 0; if (this.value == 0) { extra_hrs = 12; }; return ((this.value / 0.5)/60) + extra_hrs + ':00'; };if (\"labels\" in options[\"xAxis\"]) { options[\"xAxis\"][\"labels\"][\"formatter\"] = xAxisFormatter; } else { options[\"xAxis\"][\"labels\"] = { \"formatter\": xAxisFormatter, \"style\": { \"fontSize\": \"8px\" } }; };var yAxisFormatter = function () { return Highcharts.numberFormat(this.value, 2, '.', ',') + \"%\"; };if (\"labels\" in options[\"yAxis\"]) { options[\"yAxis\"][\"labels\"][\"formatter\"] = yAxisFormatter; } else { options[\"yAxis\"][\"labels\"] = { \"formatter\": yAxisFormatter, \"style\": { \"fontSize\": \"8px\" } };};var plotOptionsFormatter = function () { return Highcharts.numberFormat(this.value, 2, '.', ',') + \"%\"; };options[\"plotOptions\"][\"series\"][\"dataLabels\"][\"formatter\"] = plotOptionsFormatter;chart = new Highcharts.chart(chart.container, options);chart.redraw();}",
"infile": "{chart: {backgroundColor: \"white\", borderWidth: 0, height: 300, polar: true, width: 300}, colors: [\"#16C1F3\", \"#3C6E71\", \"#EAC435\", \"#E63946\", \"#33658A\", \"#DFD6A7\", \"#627264\", \"#86CCA5\", \"#6268B0\", \"#E8D33F\", \"#DA2C38\"], credits: {enabled: false, position: {align: \"right\", verticalAlign: \"bottom\"}, text: \"(c) Insight Industry Inc., 2017.\"}, exporting: {enabled: false}, legend: {enabled: false}, plotOptions: {column: {groupPadding: 0, pointPadding: 0}, series: {dataLabels: {}, pointInterval: 30, pointStart: 0}}, series: [{data: [{name: \"12:00am - 4:59am\", x: 0, y: 2.737994945240101}, {name: \"5:00am - 5:29am\", x: 150, y: 1.6287559674248806}, {name: \"5:30am - 5:59am\", x: 165, y: 1.6849199663016006}, {name: \"6:00am - 6:29am\", x: 180, y: 5.9112608817747825}, {name: \"6:30am - 6:59am\", x: 195, y: 11.513619769727605}, {name: \"7:00am - 7:29am\", x: 210, y: 17.98652064026959}, {name: \"7:30am - 7:59am\", x: 225, y: 17.733782645324347}, {name: \"8:00am - 8:29am\", x: 240, y: 20.190957596180848}, {name: \"8:30am - 8:59am\", x: 255, y: 7.848918843021623}, {name: \"9:00am - 9:59am\", x: 270, y: 8.438640831227183}, {name: \"10:00am - 10:59am\", x: 300, y: 3.1592249368155008}, {name: \"11:00am - 11:59am\", x: 330, y: 1.1654029766919405}], name: null, pointPlacement: \"on\", type: \"column\"}], title: {text: null}, tooltip: {style: {fontSize: \"10px\"}, valueDecimals: 1, valueSuffix: \"%\"}, xAxis: {labels: {style: {fontSize: \"10px\"}}, max: 360, min: 0, tickInterval: 30, title: {text: null}}, yAxis: {labels: {style: {fontSize: \"10px\"}}, max: 25.0, min: 0, showLastLabel: false, tickInterval: 5, title: {style: {color: \"#0A3B61\", fontSize: \"9px\", fontWeight: \"bold\"}, text: \"Workers, Aged 25+\"}}}",
"scale": 2,
"type": "png"
}
We have recreated what we (suspect) is the process that the node export server goes through, and have definitely recreated the (weird) behavior that we're seeing in this jsFiddle: https://jsfiddle.net/cmodzelewski/v4gm6t9a/2/
Are we missing something blatantly obvious (which is what we suspect)? Or is there a better way of doing this to get the behavior we're looking for?
Any help would be very much appreciated!
In your fiddle with the suspected process, and in your callback, you are setting the axis labels in the following way:
options["yAxis"]["labels"]
This will set an object labels on the yAxis element, however, since you can have several axis in highcharts, they are indexed, and stored as such. That means you have to edit the first axis like this:
options["yAxis"][0]["labels"]
Here is a picture of the yAxis object in the incorrect configuration:
Here is a picture of the yAxis object in the correct configuration:
Working example using your second fiddle: https://jsfiddle.net/ewolden/v4gm6t9a/4/
I am generating a Project Cumulative Flow Chart, which is based on the Project name that I fetch using a "find," however I can't get it working.
Here is the Problem:
1) The "Find" in my code is just fetching one kind of project name, "FE," however, I have a lot of other Project name such as FE, BE, VisualRF, etc. I am not sure what's going on
2) I return this to "storeConfig" inside the chart and then I want try to give "Name" to the "stateFieldName." This is not working! I don't see any graph at all.
Here is the code.
_chart2: function() {
var projectName = this.getContext().getProject()._refObjectName;
console.log("========");
console.log(projectName); <<<<<<<<<< This always prints one name'FE' (My project name are FE, BE, etc)
this.chart = {
xtype: 'rallychart',
storeType: 'Rally.data.lookback.SnapshotStore',
storeConfig: this._getStoreForChart2(),
calculatorType: 'Rally.example.CFDCalculator',
calculatorConfig: {
stateFieldName: this.getContext().getProject()._refObjectName, <<<<< I think usage is not fetching name of all projects
stateFieldValues: ['FE','BE','VisualRF']
},
width: 1000,
height: 600,
chartConfig: this._getChart2Config()
};
this.chartContainer.add(this.chart);
},
_getStoreForChart2: function() {
var obj1 = {
find: {
_TypeHierarchy: { '$in' : [ 'Defect' ] },
Children: null,
_ProjectHierarchy: this.getContext().getProject().ObjectID,
_ValidFrom: {'$gt': Rally.util.DateTime.toIsoString(Rally.util.DateTime.add(new Date(), 'day', -30)) },
State: "Open",
},
fetch: ['Severity','Project','ObjectID','FormattedID'],
hydrate: ['Severity','Project','ObjectID','FormattedID'],
sort: {
_ValidFrom: 1
},
context: this.getContext().getDataContext(),
limit: Infinity,
val: this.Name,
};
return obj1;
},
Though this should not matter but here is the code for the high chart function I am calling above
_getChart2Config: function() {
console.log("starting chart config");
return {
chart: {
zoomType: 'xy'
},
title: {
text: 'Chart2'
},
xAxis: {
tickmarkPlacement: 'on',
tickInterval: 20,
title: {
text: 'Date'
}
},
yAxis: [
{
title: {
text: 'Count'
}
}
],
plotOptions: {
series: {
marker: {
enabled: false
}
},
area: {
stacking: 'normal'
}
}
};
},
Down below you can see 'FE' getting printed:
Thanks a lot!
Kay
stateFieldName is the field which is used to calculate the CFD- usually ScheduleState or a custom dropdown field like KanbanState that captures your process. The stateFieldValues should be the values of that field (Defined, In-Progress, Accepted, Completed, etc.) This doesn't deal with projects at all. Definitely remember to include that field in your hydrate and fetch as well.
I'm trying to implement geolocation on my app written in sencha framework, but I don't really know how to implement geolocation using Sencha Touch 2 and Google Maps Api.
I have following code:
Ext.define('App.view.WhereAmI', {
extend: 'Ext.Container',
xtype: 'whereAmI',
//? fullscreen: true,
requires: [
'Ext.Map'
],
config: {
layout: 'fit',
scrollable: true,
styleHtmlContent: true,
style: 'text-align: center; background-color:white;',
items:
[
{
xtype: 'toolbar',
docked: 'top',
title: 'Where Am I?',
minHeight: '60px',
items: [
{
ui: 'back',
xtype: 'button',
id: 'backButton',
text: 'Powrót',
},
{
minHeight: '60px',
right: '5px',
html: ['<img src="resources/images/Image.png"/ style="height: 100%; ">',].join(""),
},
],
},
{
xtype:'map',
},
]
},
//launch : function () { },
});
What do I exactly need to add to this view to implement marker with my current location?
Thanks for help!
Try using geolocation :
var geo = Ext.create('Ext.util.Geolocation', {
autoUpdate:false,
listeners:{
locationupdate:function (geo) {
console.log('Current latitude: ' + geo.getLatitude() + 'Long: ' + geo.getLongitude());
},
locationerror:function (geo, bTimeout, bPermissionDenied, bLocationUnavailable, message) {
if (bTimeout) {
alert('Timeout occurred.');
} else {
alert('Error occurred.');
}
}
}
});
or add
useCurrentLocation:true,
in sencha touch map