How to debug chrome extension at such part of code? - google-chrome-extension

The code below is the JavaScript file works with popup.html from a small project.
I use it for chrome extension development learning.
The first part of this code piece is getting two variable from chrome storage, let's call it part1.
The second part is a button-click event function,Let's call it part2.
The button is on popup page and called "spend".
In part2, I can set a breakpoint2 on chrome debugger DevTools,when I click the button on popup page, it will stop at breakpoint2.
But when I place a Breakpoint1 at part1,the code will not stop at that line, even I add one more line "debugger;", the program will not stop there.
So my problem is how to make the debugger stop at places like breakpoint1?
The source code for the extension:https://drive.google.com/file/d/1odxJy9pGnovzox2yXH-6MDO03_T7QIDE/view?usp=sharing
//popup.js
$(function(){
chrome.storage.sync.get(['total','limit'],function(budget){
//Breakpoint1
$('#total').text(budget.total);
$('#limit').text(budget.limit);
});
$('#spendAmount').click(function(){
//Breakpoint2
chrome.storage.sync.get(['total', 'limit'],function(budget){
var newTotal = 0;
if (budget.total){
newTotal += parseInt(budget.total);
}
var amount = $('#amount').val();
if (amount){
newTotal += parseInt(amount);
}
chrome.storage.sync.set({'total': newTotal}, function(){
bla();
bla();
}
});
$('#total').text(newTotal);
$('#amount').val('');
});
});
});
Any assistance is highly appreciated,Thanks in advance.

Related

Content script executed on tab while loading using browser.tabs.executeScript does not triggering window.onload event

In our firefox extension from the background script, we are checking the currently loading tab and check whether the URL is our desired URL if it is our desired URL then we are executing a javascript file on the tab with the help of browser.tabs.onupdated event using browser.tabs.executeScript and the file is executed successfully but the window.onload event present on the content script doesn't execute
but the console statement on the first line executed in the content script
Background.js
browser.tabs.onUpdated.addListener(
function (tabId, changeInfo, tab) {
// here checking wether to execute the script for the currently loading tab based on the URL of tab
browser.tabs.executeScript(tab.id, { file: "jquery.min.js" });
browser.tabs.executeScript(tab.id, { file: "automate.js" });
},
{ properties: ["status"] }
);
automate.js
console.log("automate.js executing");
window.addEventListener("load",function(){
// this console.log statement not printed
console.log("window is loaded");
})
By default content scripts run at document_idle:
The document and all its resources have finished loading.
Solution:
It is the same as load event conditions so you don't need it. Simply do what you need right away.
Alternative:
If for some reason you need to do something before the load event and something afterwards, you can use document_end to run the script at DOMContentLoaded event (DOM is ready, resources are still loading) or document_start (DOM is empty, only <html> node is parsed).
browser.tabs.executeScript(tab.id, { file: 'jquery.min.js', runAt: 'document_end' });
browser.tabs.executeScript(tab.id, { file: 'automate.js', runAt: 'document_end' });

How can I track many elements that are rendered asynchronously using nightwatch and selenium?

I just started to use NightWatch JS and Selenium, I'm trying to get the time that some charts take to be visible, but the commands get executed sequentially so I cannot get the real time that those elements take to be visible.
I'm also have developed asynchronous functions and i'm still getting the same result.
module.exports = {
'#tags': ['Testing'],
'Testing': function(browser) {
console.log(browser)
browser
.url('someURL')
.waitForElementVisible('input[name="username"]',10000)
.click('input[name="username"]')
.setValue('input[name="username"]', '************')
.click('input[type="password"]')
.setValue('input[type="password"]', '*********')
.pause(2000)
.click('button[id="btn_signin"]')
.pause(10000)
.isLogAvailable()
.waitForElementVisible('button[title="My content"]')
.click('button[title="My content"]')
.pause(10000)
.waitForElementVisible('div[title="Country"]')
.click('div[title="Country"]', function(){
browser.expect.element('g[clip-path="url(#_raveLibId_0_clipViewport)"]').visible
browser.expect.element('g[clip-path="url(#_raveLibId_1_clipViewport)"]').visible
})
}
};

Confusion understanding YouTube's loop parameter

I have a YouTube video link which I am trying to supply parameters to:
https://www.youtube.com/embed/wU4DgHHwVCc?autoplay=1&start=20&end=25&loop=1
Everything else works perfectly except for the loop parameter. The video doesn't loop. According to Google Developer's page:
This parameter has limited support in the AS3 player and in IFrame embeds, which could load either the AS3 or HTML5 player. Currently, the loop parameter only works in the AS3 player when used in conjunction with the playlist parameter.
So even though my Chrome browser is not using AS3, as I've disabled flash, I added the playlist parameter to the URL just to see what would happen.
https://www.youtube.com/embed/wU4DgHHwVCc?autoplay=1&start=20&end=25&loop=1&playlist=wU4DgHHwVCc
Now the video does loop but both start and end parameters are ignored and the video starts at 00:00 instead of 00:20 as specified in the URL.
Why do I need to specify the playlist parameter when I am not using AS3 player?
Why does it ignore the start and end parameters on loop?
OS: Ubuntu 16.04 LTS
Chrome version: 60.0.3112.90 (64-bit)
Looking at Youtube documentation... You can modify their shown i-frame API example code like below to get a looping effect.
The trick is :
Set Start Time of video at 20 seconds
Listen for playback begin event and handle with onPlayerStateChange() function, which itself starts a timer of a 5 seconds countdown (ie: 5000 millisecs).
When timer reaches zero it triggers function handleVideo() which itself starts a new timer of 5 seconds. Then auto-seeks back to 20 second (start time) in video's timeline. The timer now creates a feedback loop.
Try my example code below in a new html page. Can also test it here.
Code was tested on Windows/Chrome.
<!DOCTYPE html>
<html>
<body>
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
<script>
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady()
{
player = new YT.Player('player',
{
width: '100%',
height: '800',
videoId: 'wU4DgHHwVCc',
startSeconds:20,
//endSeconds:25,
events:
{
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event)
{
event.target.seekTo(20);
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(handleVideo, 5000);
done = true;
}
}
// Custom function to LOOP
// Moves playhead back to 20 seconds
function handleVideo()
{
setTimeout(handleVideo, 5000);
player.seekTo(20);
}
</script>
</body>
</html>
It is simple. For single video to loop, you need to have it twice.
Try this out.
https://www.youtube.com/embed/wU4DgHHwVCc?playlist=wU4DgHHwVCc&autoplay=1&rel=0&loop=1
Note that "rel" must be set to "0" for any videos that might have them linked as they break the loop.
I made a page for testing HERE if you like to test.

visual-studio-code: Howto executeCommand<T>(command: string, ...rest: any[]): Thenable<T>

I try to figure out how to implement a visual studio code extension. (Based on the "Hello World!" example.)
I want to do the following:
Execute an example.cmd file in the editor in a node.js child_process (that works)
But prior to that, automatically save the file to activate the latest changes (thats the problem)
At https://code.visualstudio.com/Docs/extensionAPI/vscode-api there is description of visual studio code api.
This is the command I think to be used:
executeCommand<T>(command: string, ...rest: any[]): Thenable<T>
What I need:
The file save is asynchronous. E.g. there may show up a File Save Dialog. The user may save properly or cancel it. I need to wait til end of the user action, then in case of succeess call my command prompt.
In my code:
let disposable = vscode.commands.registerCommand('extension.sayHello', () => {
....
var retval =
vscode.commands.executeCommand('workbench.action.files.save')
.then(function(result)
{
// It should wait til end of user action,
// But it never reach here
myOutputChannel.append('workbench.action.files.save:' + result + '\n');
});
// and immediately runs the child process code below
....
});
What happens:
It runs through the code, don't wait, don't save, process the non existing file, reports an error, exit function. After all the File Save Dialog appears. :(
Can anyone give me a hint whats wrong? Is this a bug of visual studio code? Or what I am doing wrong? I am new to node.js . I guess, I didn't get how to use Thenable<T> properly?
Here's a short snippet on how to properly save the file:
let editor = vscode.window.activeTextEditor;
if (!editor) {
return;
}
let doc = editor.document;
await editor.document.save();

Chrome extension delay condition

I have created a chrome extension which does something after its button is clicked.
However I dont want it be abused so I need the its code to be executed after some time.
How can I surround this code with a timeout in order to achieve this?
Thank you for reading me!
chrome.tabs.getSelected(null,function(tab) {
var Mp=tab.url.substring(0,23);
if(Mp=='https://www.example.com')
{
onWindowLoad();
chrome.extension.onMessage.addListener(function(request, sender) {
if (request.action == "getSource")
{
...Working here
}
});
}
else
{
message.innerHTML='<span style="color: #f00">This is not a valid page</span>';
}
});
function onWindowLoad()
{
var message = document.querySelector('#message');
chrome.tabs.executeScript(null, {file: "getPagesSource.js"});
}
I had to make a compromise so just after the getSelected I added the following line:
chrome.browserAction.disable(tab.Id);
It disables the action button thus it cant be clicked while the script sends the data to the server, as with this extension I grab the tab url in order to store it in my database.
After the ajax response and adding the following
if(xhr.readyState==4)
{
message.innerHTML=xhr.responseText;
chrome.browserAction.enable(tab.Id); /////<---THAT LINE
}
the button gets ready again to be clicked.
I couldnt find the way to add a specific delay in seconds, this way seems stupid but its working, as the response's delay from my server is enough for switching the 2 states of the action button.
With this, however another problem came up, which Ill write in different question.

Resources