Triggering click events from within a FF sandbox - firefox-addon

I am trying to trigger a click event on an element on a page from within a Firefox sandbox. I have tried using jQuery's .click() as well as doing:
var evt = document.createEvent("HTMLEvents");
evt.initEvent("click", true, false );
toClick[0].dispatchEvent(evt);
Has anyone been able to trigger a click event on a page in the browser through a sandbox? I can get the DOM element fine, but triggering the event is a different story.

You have to create the event on the right document:
var evt = pageDocument.createEvent("HTMLEvents");
evt.initEvent("click", true, false );
toClick[0].dispatchEvent(evt);
The true means the event "bubbles" and the false means the event cannot be cancelled. From https://developer.mozilla.org/en/DOM/event.initEvent

Related

Can't interact with chrome extension page with playwright

I want to automate metamask chrome extension with playwright. I found the code below in the API document. I'm able to load Metemask extension but when I try to click the Get Started button on the metamask home page it shows timeout error waiting for the selector.
I need help to check what is the problem and how to work with backgroundpage
(async () => {
const pathToExtension = require('path').join(__dirname, 'my-extension');
const userDataDir = '/tmp/test-user-data-dir';
const browserContext = await chromium.launchPersistentContext(userDataDir,{
headless: false,
args: [
`--disable-extensions-except=${pathToExtension}`,
`--load-extension=${pathToExtension}`
]
});
const backgroundPage = browserContext.backgroundPages()[0];
// Test the background page as you would any other page.
await backgroundPage.click('.btn-primary') // Get Started button
await browserContext.close();
})();
Background page is invisible and doesn't have the button you are trying to click. What you need is to be able to click on elements inside the extension popup window which is currently not supported. Please thumb up this feature request https://github.com/microsoft/playwright/issues/5593 if you need it.

Trigger ipcRenderer event from devtools in Electron BrowserWindow

I need to trigger this event from devtools. It gets triggered when called from the main process (js) using mainWindow.webContents.send('get-holdings', 'get holdings!');
I have webPrefences set with nodeIntegration: false as there were jquery and angular errors if nodeIntegration was set to true.
For debugging, I want to do it from devtools console. I looking for the code that needs to be put into the devtools console to trigger the get-holdings event.
ipcRenderer.on('get-holdings', (event, arg) => {
var holdings;
$.getJSON('https://example.com/api/holdings', function(res){
holdings = res.data;
console.log(holdings);
ipcRenderer.send('save-holdings', holdings);
});
console.log(arg);
})
Please help!
Borrowing ideas from the code in devtron, I solved it using this in the pre-load script
window.__electron = require('electron');
Then, I could simply do the following:
win = window.__electron.remote.getCurrentWindow()
win.webContents.send('get-holdings', 'get holdings!');

Grails file download does not initiate when called from remoteFunction

In my Grails application, a user can click on a g:link which will call my controller to export certain data to a CSV file. This works with no problems.
I then moved that button to a jQuery dialog box and, when the button is clicked, I use
${remoteFunction(action:'export', onSuccess:'closeMe();', id:courseInstance?.id)}
to call the same controller method and close the dialog box. I've confirmed that the method is actually called, and the dialog box closes. The user is not prompted with the CSV dowmload, however. I'm assuming this has something to do with the remoteFunction, but I'm not really sure. Can anyone explain why this might happen, and a potential fix?
Thanks!
With AJAX requests you can't handle to download content as attachment and so it can't trigger the Save As dialog.
There are a couple of workarounds for this:
Use a plain g:link as before and bind the 'closeMe();' function to the 'click' event. The problem is that you have no control on error or success response.
Use an iframe: You can create a temporary invisible iframe and set its location to the URL of the file to download. It also has the backside of not controlling the success/error response.
The code could be the same as in this answer:
<script type="text/javascript">
function downloadURL(url) {
var iframe;
var hiddenIFrameID = 'hiddenDownloader';
iframe = document.getElementById(hiddenIFrameID);
if (iframe === null) {
iframe = document.createElement('iframe');
iframe.id = hiddenIFrameID;
iframe.style.display = 'none';
document.body.appendChild(iframe);
}
iframe.src = url;
}
</script>
And the link
Export

JQuery bind click event keep old binding values

I have an ASP.NET MVC 3.0 partial view which is render inside a jquery ui dialog.
Inside this partial view I have some link which help me to display some more info.
#foreach (StatusType status in ViewBag.Status)
{
<li>#status.StatusMessage<a href='#' status='#status.StatusCode'><img src=#Url.Content("~/Content/Images/information.png") alt="See detail"/></a></li>
}
I've bound those link with the click event:
$('a[status]').live('click', function (e) {
if (e.preventDefault)
e.preventDefault();
else
e.returnValue = false;
var status = $(this).attr('status');
alert('#Model.Code');
...});
What is happening is when I click the first time on the link it will display me the correct Code (let's say 12). When I will load the partial view again for another code (66) it will display me two alert message, the first one with 12 (the old value I've clicked before) and the second one with 66.
The more partial view I will load the more value I will have in my alert.
I don't understand why it is keeping me like an history of all the code I've clicked.
If somebody have any idea on this problem, it will be welcomed, it just driving me mad.
Thanks in advance.
UPDATED
The use of the on instead of the live works, but I still have an issue with the dialog.
I've change the code with the solution proposed:
$('#StatusDiv').on('click', 'a[status]', function (e) {
e.preventDefault();
var status = $(this).attr('status');
alert('#Model.Code');
$('#StatusDialog').dialog({
autoOpen: false,
width: 800,
resizable: true,
title: 'Status Info',
modal: true,
open: function (event, ui) {
alert('#Model.Code');
$(this).load('#Url.Action("ViewStatusInfo")', { clientId: clientId, Code: '#Model.Code', status: status
});
}
});
$('#StatusDialog').dialog('open');
});
The first alert display the correct code, but the second alert inside the open function display the old one. On the second click it will work correctly but I don't understand how it can pick the old value since the first display is correct...
Thanks again for your help.
First of all: do not use live in last versions of jquery.
$('#list').on('click', '.status', function(e){
e.preventDefault();
alert(this.href);
});
Here we bind event to #list and when we will insert new links, everything will work.
Demo: jsfiddle.net/wPSH2/

Initiate jQuery UI Dialog from a result of AJAX call

I have Page A which calls Page B using AJAX. Page B will be put in a div container in Page A. Within the result (which is Page B), there's a code that will initiate a jQuery UI Dialog. The div for the dialog is also in Page B. However, it doesn't work. I'd have to put the initiation code in Page A. So, if I want to put the initiation code in Page B, what should I do ?
The initiation code:
$('#dialog').dialog({
bgiframe: true,
autoOpen: false,
width: 300,
height: 300,
modal: true,
resizable: false,
buttons: {
'Create an account': function() { },
Cancel: function() { }
},
close: function() { }
});
I've also tried using $('div.dialog') as the selector (changed the id to class) and it does work, but everytime I request Page B (without reloading Page A), the dialog will multiply. For an example, the first time I requested Page B, one dialog will be opened. The second time I requested Page B, two dialogs will be opened.
Your approach isn't far off, you're just duplicating the dialog on the call when loading each time, so destroy the previous one, so instead of this:
$('div.dialog').dialog({ ...options... });
Call this:
$('div.dialog').dialog('destroy').dialog({ ...options... });
This prevents multiple dialogs from being instantiated for the same element. Alternatively, you can check if the dialog has been created on that element yet, like this:
$('div.dialog').filter(function() {
return $(this).closest('.ui-dialog').length === 0;
}).dialog({ ...options... });
This creates the dialog only on <div class="dialog"> elements that aren't already wrapped in a dialog.
You could do that using jQuery live function with custom event binding.
Everytime you make a call to Page B, you would have to trigger your custom event, so that the new dialog element can be binded in the event handler. The initiation code would have to be still in Page A if you follow this method.

Resources