Service workers install event not firing - caching

Taking inspiration from Google's page, I pasted this into my website:
var CACHE_NAME = 'my-site-cache-v1';
var urlsToCache = [
'serviceworker.css'
];
debugger // 1
self.addEventListener('install', function(event) {
debugger // 2
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
Debugger 1 stops the program flow, but debugger 2 is never reached.
ServiceWorker.css exists.
I'm navigating to the page using the Incognito window with the developer toolbar open.

The code in your snippet above must be loaded in via register. You will need to be developing with https to see this work
if ('serviceWorker' in navigator) {
window.addEventListener('load', function() {
navigator.serviceWorker.register('./codeWithYourJsAbove.js').then((function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}), function(err) {
console.log('ServiceWorker registration failed: ', err);
});
});
}

Related

Laravel Echo and whisper

I'm running echo server and redis. Private channels work perfectly, and messaging I have built for it works. Now I'm trying to get the whisper to work for the typing status as well but no luck. Does whisper require a pusher to work?
What I have tried on keyup (jquery)
Echo.private(chat- + userid)
.whisper('typing',{e: 'i am is typing...'});
console.log('key up'); // this one works so the keyup is triggered
then I'm of course listening the channel what I am whispering into:
Echo.private(chat- + userid).listenForWhisper('typing', (e) => {
console.log(e + ' this is typing');
});
But I get absolutely nothing anywhere. (debugging on at the echo server, nothing on console etc) Any help how to get this to work would be much appreciated.
Your input event:
$('input').on('keydown', function(){
let channel = Echo.private('chat')
setTimeout( () => {
channel.whisper('typing', {
user: userid,
typing: true
})
}, 300)
})
Your listening event:
Echo.private('chat')
.listenForWhisper('typing', (e) => {
e.typing ? $('.typing').show() : $('.typing').hide()
})
setTimeout( () => {
$('.typing').hide()
}, 1000)
Of course you have to have setup the authentication for this channel ahead of time to ensure that the trusted parties have access:
Broadcast::channel('chat', function ($user) {
return Auth::check();
});
Where $user will be the userid we passed to the user param in our object on the front end.
This is what my ReactJS componentDidMount looks like.
Your listening event.
componentDidMount() {
let timer; // timer variable to be cleared every time the user whispers
Echo.join('chatroom')
.here(...)
.joining(...)
.leaving(...)
.listen(...)
}).listenForWhisper('typing', (e) => {
this.setState({
typing: e.name
});
clearTimeout(timer); // <-- clear
// Take note of the 'clearTimeout' before setting another 'setTimeout' timer.
// This will clear previous timer that will make your typing status
// 'blink' if not cleared.
timer = setTimeout(() => {
this.setState({
typing: null
});
}, 500);
});
}

CasperJs Google login

I having been working on some code to access my google CSE
For that I need to sign in with my google account.
I have the following code:
var casper = require('casper').create({
verbose: true,
logLevel: 'debug',
waitTimeout: 5000,
clientScripts: ["libs/jquery.min.js"],
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5)
AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4'
});
const google_email = "MY_EMAIL";
const google_passwd = "MY_PASSWORD";
const loginUrl = 'https://accounts.google.com';
casper.start(loginUrl, function() {
this.waitForSelector('#view_container > form');
});
casper.then(function() {
this.fillSelectors('#view_container > form', {
'input[name="identifier"]': google_email
}, false);
});
casper.then(function() {
this.click('#identifierNext');
});
casper.wait(500, function() { //Wait for next page to load
this.capture('images/step01.png');
});
casper.then(function() {
this.evaluate(function () {
var identifierNext = $('#identifierNext');
identifierNext.click();
});
});
casper.then(function() {
this.capture('images/step02.png');
});
casper.run(function() {
this.echo("Done");
});
The part of entering the email seems to work.
But the click part isn't working.
I found this but it seems outdated.
Thanks
I haven't fixed the issue related to the new form, but we found a way to access the old form, so the "old" scripts should still work, and that solution is disabling JS. For that, change the loginUrl to
https://accounts.google.com/ServiceLogin?passive=1209600&continue=https%3A%2F%2Faccounts.google.com%2FManageAccount&followup=https%3A%2F%2Faccounts.google.com%2FManageAccount&flowName=GlifWebSignIn&flowEntry=ServiceLogin&nojavascript=1#identifier
Important thing: nojavascript=1
We are using the script posted in Casperjs Google Login Not working
Just changing the login URL.
Try this - a lot more delays are needed to wait for the dynamically loaded pages.
casper.options.verbose = true; // verbose reporting
casper.options.logLevel = 'debug'; // full log reporting
casper.options.exitOnError = false; // Keep going on error
const google_email = "EMAIL";
const google_passwd = "PASSWORD";
const loginUrl = 'https://accounts.google.com';
// Load the login page
casper.start(loginUrl, function() {
this.waitForSelector('#view_container'); // '> form' doesn't seem to work
});
// Fill in the 'username' form
casper.then(function() {
this.fill('form', {
identifier: google_email,
});
this.sendKeys('#view_container', casper.page.event.key.Enter , {keepFocus: true});
});
// First 'Enter' is too quick for Google, send another one after a pause
casper.wait(2500, function() {
this.sendKeys('#identifierId', casper.page.event.key.Enter , {keepFocus: true});
});
// Wait for the 'password' form
casper.waitForSelector("#passwordNext", function() {
this.echo("password form is apparently available");
});
// Password form seems to load slowly, even if the selector is found/visible, this delay ensures next form fill works
casper.wait(2500, function() {
this.echo("password form is really available");
});
// Fill in the 'password' form
casper.then(function() {
this.fill('form', {
password: google_passwd,
});
this.sendKeys('#view_container', casper.page.event.key.Enter , {keepFocus: true});
});
// First 'Enter' is too quick for Google, send another one after a pause
casper.wait(500, function() {
this.sendKeys('input.whsOnd.zHQkBf', casper.page.event.key.Enter , {keepFocus: true});
});
// Extend timeout to allow for slow dynamic page rendering
casper.options.waitTimeout = 25000;
casper.waitForSelector("#gb", function() {
this.echo("login complete");
});
casper.thenOpen('https://(google app you want)', function() {
// Check it opened okay
});

why is casper.on('click' ...) not triggering?

Following is a minimal casper script that does a Google query. I've added casper.on('click' ...) prior to running the script, but it doesn't appear to get triggered.
What am I missing?
// File: google_click_test.js
"use strict";
var casper = require('casper').create();
casper.on('click', function(css) {
casper.echo('casper.on received click event ' + css);
});
// ================================================================
// agenda starts here
casper.start('https://google.com', function g01() {
casper.echo('seeking main page');
});
casper.then(function a02() {
casper.waitForSelector(
'form[action="/search"]',
function() {
casper.echo("found search form");
},
function() {
casper.echo("failed to find search form");
casper.exit();
});
});
casper.then(function a03() {
casper.fillSelectors('form[action="/search"]', {
'input[title="Google Search"]' : 'casperjs'
}, false);
});
casper.then(function a04() {
casper.click('form[action="/search"] input[name="btnG"]')
casper.echo('clicked search button');
});
casper.run();
Output:
Here's the output. I would expect to see casper.on received click event somewhere, but it seems that it didn't get triggered:
$ casperjs --ignore-ssl-errors=true --web-security=no google_click_test.js
seeking main page
found search form
clicked search button
$
Although your example runs fine for me using casperjs 1.1.0-beta3 and phantomjs 1.9.8, I've been having similar issues in the last few months with casperjs. Sadly it seems that the author has stopped maintaining the project. More information here:
https://github.com/n1k0/casperjs/issues/1299
I would suggest moving to a different testing framework. In my case I chose a combination of mocha + chai + nightmarejs. This gist is a good starting point:
https://gist.github.com/MikaelSoderstrom/4842a97ec399aae1e024

Using Kango API from iFrame

Using Kango, I have added an iFrame to a page. This iFrame points to an internal resource. I want this iFrame to be able to communicate with the background script. I would love to actually get the Kango API accessable from the iFrame, but if this is not possible I wonder how I might target this iFrame with a content script.
From your application that is inside the iFrame you can do:
top.window.postMessage({ type: 'EVENT', data: {} }, "*");
Then inside your Kango extension HTML link a JS file that has:
KangoAPI.onReady(function () {
window.addEventListener('message', function (event) {
console.log('host.js -> message', event);
kango.dispatchMessage('MessageToWindow', event);
});
document.body.onload = function () {
try {
document.getElementById('iFrameID').src = 'URL';
} catch (ex) {
throw ex;
}
}
});
Then inside the background.js
kango.addMessageListener('MessageToWindow', function (event) {
console.log('background.js -> MessageToWindow', event);
kango.browser.tabs.getCurrent(function (tab) {
console.log('background.js -> TAB', tab || 'NONE');
console.log('background.js -> TYPE', event.data.data.type || 'NONE');
console.log('background.js -> DATA', event.data.data.data || 'NONE');
tab.dispatchMessage(event.data.data.type, event.data.data.data);
});
});
Lastly, inside the content.js
kango.addMessageListener('EVENT', function(event) {
kango.console.log('got event');
});
Seems like a lot, but this was the only way that I could get it to work. Hope that helps!

Running into Error while waiting for Protractor to sync with the page with basic protractor test

describe('my homepage', function() {
var ptor = protractor.getInstance();
beforeEach(function(){
// ptor.ignoreSynchronization = true;
ptor.get('http://localhost/myApp/home.html');
// ptor.sleep(5000);
})
describe('login', function(){
var email = element.all(protractor.By.id('email'))
, pass = ptor.findElement(protractor.By.id('password'))
, loginBtn = ptor.findElement(protractor.By.css('#login button'))
;
it('should input and login', function(){
// email.then(function(obj){
// console.log('email', obj)
// })
email.sendKeys('josephine#hotmail.com');
pass.sendKeys('shakalakabam');
loginBtn.click();
})
})
});
the above code returns
Error: Error while waiting for Protractor to sync with the page: {}
and I have no idea why this is, ptor load the page correctly, it seem to be the selection of the elements that fails.
TO SSHMSH:
Thanks, your almost right, and gave me the right philosophy, so the key is to ptor.sleep(3000) to have each page wait til ptor is in sync with the project.
I got the same error message (Angular 1.2.13). My tests were kicked off too early and Protractor didn't seem to wait for Angular to load.
It appeared that I had misconfigured the protractor config file. When the ng-app directive is not defined on the BODY-element, but on a descendant, you have to adjust the rootElement property in your protractor config file to the selector that defines your angular root element, for example:
// protractor-conf.js
rootElement: '.my-app',
when your HTML is:
<div ng-app="myApp" class="my-app">
I'm using ChromeDriver and the above error usually occurs for the first test. I've managed to get around it like this:
ptor.ignoreSynchronization = true;
ptor.get(targetUrl);
ptor.wait(
function() {
return ptor.driver.getCurrentUrl().then(
function(url) {
return targetUrl == url;
});
}, 2000, 'It\'s taking too long to load ' + targetUrl + '!'
);
Essentially you are waiting for the current URL of the browser to become what you've asked for and allow 2s for this to happen.
You probably want to switch the ignoreSynchronization = false afterwards, possibly wrapping it in a ptor.wait(...). Just wondering, would uncommenting the ptor.sleep(5000); not help?
EDIT:
After some experience with Promise/Deferred I've realised the correct way of doing this would be:
loginBtn.click().then(function () {
ptor.getCurrentUrl(targetUrl).then(function (newURL){
expect(newURL).toBe(whatItShouldBe);
});
});
Please note that if you are changing the URL (that is, moving away from the current AngularJS activated page to another, implying the AngularJS library needs to reload and init) than, at least in my experience, there's no way of avoiding the ptor.sleep(...) call. The above will only work if you are staying on the same Angular page, but changing the part of URL after the hashtag.
In my case, I encountered the error with the following code:
describe("application", function() {
it("should set the title", function() {
browser.getTitle().then(function(title) {
expect(title).toEqual("Welcome");
});
});
});
Fixed it by doing this:
describe("application", function() {
it("should set the title", function() {
browser.get("#/home").then(function() {
return browser.getTitle();
}).then(function(title) {
expect(title).toEqual("Welcome");
});
});
});
In other words, I was forgetting to navigate to the page I wanted to test, so Protractor was having trouble finding Angular. D'oh!
The rootElement param of the exports.config object defined in your protractor configuration file must match the element containing your ng-app directive. This doesn't have to be uniquely identifying the element -- 'div' suffices if the directive is in a div, as in my case.
From referenceConf.js:
// Selector for the element housing the angular app - this defaults to
// body, but is necessary if ng-app is on a descendant of <body>
rootElement: 'div',
I got started with Protractor by watching the otherwise excellent egghead.io lecture, where he uses a condensed exports.config. Since rootElement defaults to body, there is no hint as to what is wrong with your configuration if you don't start with a copy of the provided reference configuration, and even then the
Error while waiting for Protractor to sync with the page: {}
message doesn't give much of a clue.
I had to switch from doing this:
describe('navigation', function(){
browser.get('');
var navbar = element(by.css('#nav'));
it('should have a link to home in the navbar', function(){
//validate
});
it('should have a link to search in the navbar', function(){
//validate
});
});
to doing this:
describe('navigation', function(){
beforeEach(function(){
browser.get('');
});
var navbar = element(by.css('#nav'));
it('should have a link to home in the navbar', function(){
//validate
});
it('should have a link to search in the navbar', function(){
//validate
});
});
the key diff being:
beforeEach(function(){
browser.get('');
});
hope this may help someone.
I was getting this error:
Failed: Error while waiting for Protractor to sync with the page: "window.angular is undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See http://git.io/v4gXM for details"
The solution was to call page.navigateTo() before page.getTitle().
Before:
import { AppPage } from './app.po';
describe('App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
});
it('should have the correct title', () => {
expect(page.getTitle()).toEqual('...');
})
});
After:
import { AppPage } from './app.po';
describe('App', () => {
let page: AppPage;
beforeEach(() => {
page = new AppPage();
page.navigateTo();
});
it('should have the correct title', () => {
expect(page.getTitle()).toEqual('...');
})
});
If you are using
browser.restart()
in your spec some times, it throws the same error.
Try to use
await browser.restart()

Resources