Is there a method that I can use to send keys to an input field using web component tester? I'd like to test sending the return key to a form.
I'm not aware of such a method in Web Component Tester, but Polymer's iron-test-helpers has MockInteractions that can send keys to a target. It even has one specifically for ENTER: MockInteractions.pressEnter(target).
Install
bower i --save-dev iron-test-helpers
Usage
<link rel="import" href="iron-test-helpers/iron-test-helpers.html">
<script>
describe('accessibility', function(done) {
it('should jump to next page on ENTER key', function() {
var el = fixture('basic');
var expectedIndex = el.pageIndex + 1;
MockInteractions.pressEnter(el.$.nextBtn);
// pressEnter() simulates key-down and asynchronous key-up,
// so wait a while before testing the result
setTimeout(function() {
expect(el.pageIndex).to.be.eql(expectedIndex);
done();
}, 500);
});
});
</script>
Related
In app use content script for all pages, and send message to active page on complete loaded page, but I have many calls of script sometimes 2 and more:
You can see that here
Code implimentation:
chrome.tabs.onCreated.addListener(function (tabs) {
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if(changeInfo.status === "complete") {
let tabid = tab.id;
console.log("Site is valid: url -> " + tab.url)
chrome.tabs.executeScript(tab.id, {
file: '/injections/mobile.bet365.com.js',
});
console.log(tab);
setTimeout(function () {
console.log("timeout was set")
chrome.tabs.query({}, function (tabs) {
let countOpenedTabsFrom = tabs.length;
let opener = 1;
// на целевой вкладке
chrome.tabs.sendMessage(tabid, {
message: "start_app",
opener: opener,
queuenumber: countOpenedTabsFrom
}, function (response) {
console.log(response);
});
});
}, 500);
}
And executed script have many queries too.
Why is this happen?
Every time onCreated event fires, you're adding a new onUpdated listener.
When, after that, onUpdated event fires, all of them are executed, leading to the behavior you're seeing.
You either need to de-register the handlers when they are done, or register the handler only once. See chrome.events docs (which describe common points of all event objects in other APIs) for ideas on how to implement that.
Note that the code inside chrome.tabs.onCreated listener does not use the tabs parameter at all, so it's not clear why do you even need to listen to onCreated.
I build an html/js application (a progressive web app) with Polymer and polymer-cli and the well generated service-worker for caching and offline.
I wonder how to notify the user when a new version of the application is available and invite him to restart browser.
any ideas ?
Edit
a talk at IO2016 where Eric Bidel talk about service worker and notify user about new version of an application :
https://youtu.be/__KvYxcIIm8?list=PLOU2XLYxmsILe6_eGvDN3GyiodoV3qNSC&t=1510
Need to check the google IO Web source code
References:
https://developers.google.com/web/fundamentals/instant-and-offline/service-worker/lifecycle
https://classroom.udacity.com/courses/ud899
// page script
document.addEventListener('DOMContentLoaded', function(){
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/sw.js')
.then(function(registration) {
console.info('ServiceWorker registration successful with scope:', registration.scope);
// if there's no controller, this page wasn't loaded
// via a service worker, so they're looking at the latest version.
// In that case, exit early
if (!navigator.serviceWorker.controller) return;
// if there's an updated worker already waiting, update
if (registration.waiting) {
console.info('show toast and upon click update...');
registration.waiting.postMessage({ updateSw: true });
return;
}
// if there's an updated worker installing, track its
// progress. If it becomes "installed", update
if (registration.installing) {
registration.addEventListener('statechange', function(){
if (registration.installing.state == 'installed'){
console.info('show toast and upon click update...');
registration.installing.postMessage({ updateSw: true });
return;
}
});
}
// otherwise, listen for new installing workers arriving.
// If one arrives, track its progress.
// If it becomes "installed", update
registration.addEventListener('updatefound', function(){
let newServiceWorker = registration.installing;
newServiceWorker.addEventListener('statechange', function() {
if (newServiceWorker.state == 'installed') {
console.info('show toast and upon click update...');
newServiceWorker.postMessage({ updateSw: true });
}
});
});
})
.catch(function(error) {
console.info('ServiceWorker registration failed:', error);
});
navigator.serviceWorker.addEventListener('controllerchange', function() {
window.location.reload();
});
}
});
// sw script
self.addEventListener('message', function(e) {
if (e.data.updateSw){
self.skipWaiting();
}
});
Thanks to IO team .. we need to check if the current service-worker becomes redundant
// Check to see if the service worker controlling the page at initial load
// has become redundant, since this implies there's a new service worker with fresh content.
if (navigator.serviceWorker && navigator.serviceWorker.controller) {
navigator.serviceWorker.controller.onstatechange = function(event) {
if (event.target.state === 'redundant') {
// Define a handler that will be used for the next io-toast tap, at which point it
// be automatically removed.
const tapHandler = function() {
window.location.reload();
};
if (IOWA.Elements && IOWA.Elements.Toast &&
IOWA.Elements.Toast.showMessage) {
IOWA.Elements.Toast.showMessage(
'A new version of this app is available.', tapHandler, 'Refresh',
null, 0); // duration 0 indications shows the toast indefinitely.
} else {
tapHandler(); // Force reload if user never was shown the toast.
}
}
};
}
I used HTML5 File API to drag a file into an Electron application and obtained file details (name, mime-type, size, etc.). How can I achieve the same when selecting a file via Electron's dialog module? Below is the code (renderer process) that leverages HTML5's File API:
const {dialog} = require('electron').remote;
// Using jQuery ($)
var holder = $('#holder');
holder.on('drag dragstart dragend dragover dragenter dragleave drop', function(evt) {
evt.preventDefault();
evt.stopPropagation();
})
.on('drop', function(evt) {
let file = evt.originalEvent.dataTransfer.files[0];
console.log(file.name);
console.log(file.type);
console.log(file.size);
})
.on('click', function(evt) {
dialog.showOpenDialog({
properties: [ 'openFile' ]
}, function(file) {
console.log(file); // just displays local, full path
// code to get name, type, size... how do I?
});
});
Check this library: mmmagic, it will do just what you want.
I'm trying to get angular to read the contents of a file that the user selects through an <input type="file" control. Even though angular does not have directives for file upload controls, it should be easy to fix that with a call to $apply:
function MyController($scope) {
$('#myFile').on('change', function() {
var that = this;
$scope.$apply(function() { $scope.files = that.files });
});
}
Unfortunately, the event is never fired. It's like the selector is unable to refer to the correct DOM element: even though the selector finds the element, the list of files is always empty. This also happens if i poke around with the js console. The DOM inspector instead has the file list among its properties.
It's driving me crazy, but the only way I've got it to work so far is to use an inline event handler that assigns to a global variable. Why is the jquery selector returning another item? Is there some template compilation mumbo-jumbo that angular does which confuses selectors?
Here is what I do:
http://plnkr.co/edit/JPxSCyrxosVXfZnzEIuS?p=preview
app.directive('filelistBind', function() {
return function( scope, elm, attrs ) {
elm.bind('change', function( evt ) {
scope.$apply(function() {
scope[ attrs.name ] = evt.target.files;
console.log( scope[ attrs.name ] );
});
});
};
});
template:
<input type="file" filelist-bind name="files"/>
<p>selected files : <pre>{{ files | json }}</pre></p>
This kind of task, you definitely want to make use of directive.
But I think that your main concern is how to access the selected file
objects and my example should clarify that.
If you are looking for file upload with angular you can use this plugin
https://github.com/danialfarid/angular-file-upload
It is basically a directive like tosh's answer that takes care of non-HTML5 browsers with FileAPI flash polyfill and has $http.uploadFile function to upload the actual file via AJAX.
This site uses Angular service for HTML5 File Upload. A simple way is to setup a controller which calls the service and updates the UI when the asynchronous call is completed.
controller:
myapp.controller('fileUploadCtrl', ['$scope', '$q', 'FileInputService', function ($scope, $q, FileInputService) {
$scope.fileInputContent = "";
$scope.onFileUpload = function (element) {
$scope.$apply(function (scope) {
var file = element.files[0];
FileInputService.readFileAsync(file).then(function (fileInputContent) {
$scope.fileInputContent = fileInputContent;
});
});
};
}]);
service:
myapp.service('FileInputService', function ($q) {
this.readFileAsync = function (file) {
var deferred = $q.defer(),
fileReader = new FileReader(),
fileReader.readAsText(file);
fileReader.onload = function (e) {
deferred.resolve(e.target.result);
};
return deferred.promise;
};
});
template:
Choose File <input type="file" onchange="angular.element(this).scope().onFileUpload(this)">
<br />
{{fileInputContent}}
Reference: You can find the full source code and reference on this site.
I have a javascript code that creates a simple clock.
define([
"dojo/_base/declare",
"dojo/dom",
"dojo/date/locale",
"dojo/_base/event"
],
function(declare, dom, locale, event) {
return declare([], {
...
...
createClock : function() {
html_time = dom.byId("time");
window.setInterval(this.tick(), 1000);
}
});
});
JS code is working correctly! Also, I have a html code:
<body>
<script>
require([ "gui/common/Clock"
],
function(Clock) {
var clock = new Clock();
clock.createClock();
});
</script>
Current time: <span id="time"></span>
...
But if I run the code in the browser, then I get an error:
Error: useless setInterval call (missing quotes around argument?)
[Break On This Error]
window.setInterval(this.tick(), 1000);
In the browser the time appears, but it does not tick. Anybody can explain what is my problem?
Do not execute the method: window.setInterval(this.tick, 1000);
Also to execute tick in this scope, use lang.hitch as of dojo/_base/lang module:
window.setInterval(lang.hitch(this, "tick"), 1000);
You can find some inspiration in my answer to How to do something while a dojo xhr request is waiting or loading.