Probably looking for an answer to an age-old question, but I would like to block script execution. In my use-case blocking the browser is acceptable.
Also, in my use-case I am trying to do this from a Firefox extension, which means my code is "Chrome code", running in the browser environment.
This can easily be done by using a modal window, then programmatically closing the window. So this demonstrates that there is a blocking mechanism that exists.
Is there any way to achieve modal blocking without actually creating or opening the modal window? Some way to tap into the blocking mechanism used for modal windows?
I've done a lot of searching on this subject, but to no avail.
Using nsIProcess you can block the thread.
You can create an executable which has a sleep or usleep method or equivalent. Then run the process synchronously (nsIProcess.run) and set blocking argument to true.
Of course for portability you will need to create an executable appropriate for each platform you wish to support, and supply code for discrimination.
Basic code is something like the following. I have verified on 'nix (Mac OS X) this code to work, using a bash script with only the line sleep .03:
let testex = Components.classes["#mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsIFile);
testex.initWithPath("/Users/allasso/Desktop/pause.sh");
let process = Components.classes["#mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(testex);
let delay = 30; // convert this to milliseconds in the executable
process.run(true,[delay],1); // `run` method runs synchronously, first arg says to block thread
In an extension you probably would want to make your nsIFile file object more portable:
Components.utils.import("resource://gre/modules/FileUtils.jsm");
let testex = FileUtils.getFile("ProfD",["extension#moz.org","resources","pause.sh"]);
Of course keep in mind that Javascript is basically single-threaded, so unless you are blocking a thread spawned using Web Workers you will be freezing the entire UI during the sleep period (just like you would if you opened a modal window).
References:
https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess
https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile
https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O#Getting_special_files
https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/basic_usage
OPTION 1
There is enterModalState and leaveModalState in nsIDOMWindowUtils here: MDN :: nsIDOMWindowUtils Reference
However they don't seem to work for me. This topic might explain why: nsIDOMWindowUtils.isInModalState() not working they topic says isInModalState is marked [noscript] which I see, but enterModalState and leaveModalState are not marked [noscript] I have no idea why it's not working.
What does work for me though is suppressEventHandling:
var utils = Services.wm.getMostRecentWindow('navigator:browser').
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
utils.suppressEventHandling(true); //set arg to false to unsupress
OPTION 2
You can open a tiny window with the source window as the window you want to make modal and as dialog but open it off screen. Its dialog so it wont show a new window the OS tab bars. However hitting alt+f4 will close that win, but you can attach event listeners (or maybe use the utils.suppressEventHandling so keyboard doesnt work in it) to avoid the closing till you want it closed. Here's the code:
var sDOMWin = Services.wm.getMostRecentWindow(null);
var sa = Cc["#mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
var wuri = Cc["#mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
wuri.data = 'about:blank';
sa.AppendElement(wuri);
let features = "chrome,modal,width=1,height=1,left=-100";
if (PrivateBrowsingUtils.permanentPrivateBrowsing || PrivateBrowsingUtils.isWindowPrivate(sDOMWin)) {
features += ",private";
} else {
features += ",non-private";
}
var XULWindow = Services.ww.openWindow(sDOMWin, 'chrome://browser/content/browser.xul', null, features, sa);
/*
XULWindow.addEventListener('load', function() {
var DOMWindow = XULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
DOMWindow.gBrowser.selectedTab.linkedBrowser.webNavigation.stop(Ci.nsIWebNavigation.STOP_ALL);
DOMWindow.gBrowser.swapBrowsersAndCloseOther(DOMWindow.gBrowser.selectedTab, aTab);
//DOMWindow.gBrowser.selectedTab = newTab;
}, false);
*/
Related
While trying to automate android native application , Appium is not identify or focus on any single element on second page of native application after automating first page login functionality successfully .I have tried with all wait method and driver. context method but it is now working .I have tried to debug the code with so many wait time but it is not working .When i put a break point after automating first page and tried to debug the application then i observed that if i put any manual action on second page (open window and close same window )then appium is allowing to identify the second page also but i didn't understand why it is happening .By automation script, i am unable to do anything on second page .Could any team help me for the same? Page source code for second page :- "
i have tried with below method for identify the second page..
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
ICapabilities caps = driver.Capabilities;
String context = driver.Context;
Console.WriteLine("Current context", context);
driver.Context = ("NATIVE_APP");
String afterloginsource = driver.PageSource;
Console.WriteLine("After loginv page source :- ", afterloginsource);
TouchAction t = new TouchAction(driver);
t.Tap(100, 100).Perform();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(2400));
String loginsource = driver.PageSource;
Console.WriteLine("Befor login page source :- ",loginsource);
driver.HideKeyboard();
//enter valid account
driver.FindElementById("com.Testing:id/userid").SendKeys("00229715");//uat02
// driver.HideKeyboard();
/////driver.FindElement(By.XPath("//android.widget.EditText[#index='1']")).SendKeys("17765919"); ////upn02
///enter valid password
driver.FindElementById("com.Testing:id/password").SendKeys("1");
///click login button
driver.FindElementById("com.Testing:id/login").Click();
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(30));
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(200));
ICapabilities caps = driver.Capabilities;
String context = driver.Context;
Console.WriteLine("Current context", context);
driver.Context = ("NATIVE_APP");
String afterloginsource = driver.PageSource;
Console.WriteLine("After loginv page source :- ", afterloginsource);
TouchAction t = new TouchAction(driver);
t.Tap(100, 100).Perform();
AndroidElement expandList = driver.FindElementById("com.Testing:id/btn_more_options");
expandList.Click(); Or //((IJavaScriptExecutor)driver).ExecuteScript("mobile: scroll", scrollObject);
//IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
//IWebElement hiddenButton = driver.FindElementById("com.Testing:id/enableNotify");
//String script = "arguments[0].click();";
//js.ExecuteScript(script, hiddenButton);
it is giving error as nosuchelement exception for any element on second page.
NoSuchElement states for inability to find the element. It strongly seems for me that xpath locators to webelements on the page are incorrect.
I do recommend to try out remote debugging just to ensure the locators are organized correctly. And using remote debugging tool - You may also check the locators on-the-fly there.
As an option B) - I could also recommend to take a quick glance towards SeeTest automation tool. The link above guide on how to set up project from scratch, and here is public documentation for SeeTest.
I'm writing a lua program that needs to call an external popup (let's call it Poppy) provided as an external library/API by another active programme (environment is Windows).
Poppy has a bad habit; when invoked, it pops up, does its work and then vanishes -- leaving the current Lua dialog hidden behind Poppy's parent program.
After calling Poppy, dlg.BRINGFRONT="YES" will bring the iup dialog dlg to the front.
Is there a technique to identify what dlg should be -- i.e. what was the topmost iup dialog before the external API was invoked?
I've read the iup documentation and can't see a way to do this. However, as I need to call Poppy in a large number of instances, I'd like to simplify the process of bringing the current dialog to the front.
I'm invoking Poppy thus:
local res = Poppy('INDI')
dlg.BRINGFRONT="YES"
return res
Inside the code that invokes Poppy in Windows, you can call:
HWND dlg_handle = GetActiveWindow();
Then when Poppy returns, call:
SetForegroundWindow(dlg_handle);
I've succeeded in doing this using the Winapi library and the following code:
winapi = require ("winapi")
currentwin = winapi.get_foreground_window()
--invoke Poppy here and wait for control to return
currentwin:set_foreground()
I'm currently developing a Ruby on Rails application that on certain moment has to import a (at least for me) medium-large dataset using a third-party API. It has to do an average of 6000 API calls. One after another. It lasts about 20 minutes.
Right now I have made a rails task that does everything as I want (calls, write to db, etc). But now I want this task/code to be ALSO called from a button on the web. I know it's not a good approach to let the controller call the task so that's why I'm asking.
I want this import code to be available to be called from a controller and a task, because later I want to be able to call this task from a cronjob, and even if it's possible to have callbacks on the progress of the task on the controller, i.e. know how many calls are left.
I know it's not a good approach to let the controller call the task
There's nothing wrong with having a button trigger a background task like this, but of course you need to do so with care. For example, perhaps:
If the task is already running, don't let a second instance overlap.
If the task runs for too long, automatically kill it.
Carefully restrict who can trigger this.
There are many libraries available for implementing a progress bar, or you could even write a custom implementation. For example, see this blog post - which works by polling the current progress:
// app/views/exports/export_users.js.haml
:plain
var interval;
$('.export .well').show();
interval = setInterval(function(){
$.ajax({
url: '/progress-job/' + #{#job.id},
success: function(job){
var stage, progress;
// If there are errors
if (job.last_error != null) {
$('.progress-status').addClass('text-danger').text(job.progress_stage);
$('.progress-bar').addClass('progress-bar-danger');
$('.progress').removeClass('active');
clearInterval(interval);
}
progress = job.progress_current / job.progress_max * 100;
// In job stage
if (progress.toString() !== 'NaN'){
$('.progress-status').text(job.progress_current + '/' + job.progress_max);
$('.progress-bar').css('width', progress + '%').text(progress + '%');
}
},
error: function(){
// Job is no loger in database which means it finished successfuly
$('.progress').removeClass('active');
$('.progress-bar').css('width', '100%').text('100%');
$('.progress-status').text('Successfully exported!');
$('.export-link').show();
clearInterval(interval);
}
})
},100);
An variant approach you could consider is to use a websocket to see progress, rather than polling.
Convert the specific tasks into background jobs, i.e. (active job, sideqik), so your system can continue working while it's doing the tasks. Create classes for each task and call those classes within your background jobs or cronjobs.
One design pattern that could fit here is the "command" pattern, I gave you a list of things you can Google :).
Just move most of the code from the task to a module or method in a model. You can call this code from the task (as your do it now) or from a background job that would start through a controller when you press a button on a view.
Assuming a scenario where DX12 is being hooked for overlay rendering it looks like the best function to hook is the IDXGISwapChain::Present the same way it was done for DX11. Having this function hooked the swap chain is available and from that the device can be retrieved to create resources. Given those resources it’s possible to record rendering commands too. The problem arises when we are trying to execute the rendering commands as there is no option to retrieve the associated command queue from the swap chain so there is nothing like this:
CComPtr<ID3D12Device> pD3D12Device;
if (pSwapChain->GetDevice(__uuidof(ID3D12Device), (void**)(&pD3D12Device)) == S_OK)
{
pD3D12Device->GetCommandQueueForSwapChain( swapChain )->ExecuteCommandLists(…);
}
The other option would be creating a new command queue to execute on, like this:
CComPtr<ID3D12Device> pD3D12Device;
if (pSwapChain->GetDevice(__uuidof(ID3D12Device), (void**)(&pD3D12Device)) == S_OK)
{
D3D12_COMMAND_QUEUE_DESC queue_desc = {};
queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
HRESULT commandQueueRes = _device->CreateCommandQueue( &queue_desc, IID_PPV_ARGS( &_commandQueue ) );
_commandQueue->ExecuteCommandLists( ... );
}
This results in an error and subsequent device removal. See the error message below.
D3D12 ERROR: ID3D12CommandQueue::ExecuteCommandLists: A command list, which writes to a swap chain back buffer, may only be executed on the command queue associated with that buffer. [ STATE_SETTING ERROR #907: EXECUTECOMMANDLISTS_WRONGSWAPCHAINBUFFERREFERENCE]
The problem is not resolved even if the ID3D12CommandQueue::ExecuteCommandLists is hooked as well because there is no way to retrieve the associated swap chain from the command queue either.
So my question is what is the recommended way to deal with this problem in a scenario where the swap chain creation happens before the hooking could possibly happen?
In case anyone is looking for the answer here's what I found out.
There is no official way to do this, for overlay rendering the recommended way is to use DirectComposition but this has performance consequences which is not very nice for game overlays.
Investigating the memory a bit there is a possible solution to get the CommandQueue from the swap chain with something like this:
#ifdef _M_X64
size_t* pOffset = (size_t*)((BYTE*)swapChain + 216);
#else
size_t* pOffset = (size_t*)((BYTE*)swapChain + 132);
#endif
*(&_commandQueue) = reinterpret_cast<ID3D12CommandQueue*>(*pOffset);
Obviously this solution is not recommended but it might be useful if someone just want's to do some debugging.
My final solution is to hook into a function that uses the CommandQueue (I use ExecuteCommandLists) and get the pointer there and use it later to render the overlay. It's not completely satisfying but it works as long as there are no multiple swap chains.
I am developing a mobile application using phonegap, Initially I have developed using WEBSQL but now I m planning to move it on INDEXDB. The problem is it does not have direct support on IOS , so on doing much R&D I came to know using IndexedDB Polyfil we can implement it on IOS too
http://blog.nparashuram.com/2012/10/indexeddb-example-on-cordova-phonegap.html
http://nparashuram.com/IndexedDBShim/
Can some please help me how to implement this as there are not enough documentation for this and I cannot figure out a any other solution / api except this
I have tested this on safari 5.1.7
Below is my code and Error Image
var request1 = indexedDB.open(dbName, 5);
request1.onsuccess = function (evt) {
db = request1.result;
var transaction = db.transaction(["AcceptedOrders"], "readwrite");
var objectStore = transaction.objectStore("AcceptedOrders");
for (var i in data) {
var request = objectStore.add(data[i]);
request.onsuccess = function (event) {
// alert("am again inserted")
// event.target.result == customerData[i].ssn;
};
}
};
request1.onerror = function (evt) {
alert("IndexedDB error: " + evt.target.errorCode);
};
Error Image
One blind guess
Maybe your dbName contains illegal characters for WebSQL database names. The polyfill doesn't translate your database names in any kind. So if you create a database called my-test, it would try to create a WebSQL database with the name my-test. This name is acceptable for an IndexedDB database, but in WebSQL you'll get in trouble because of the - character. So your database name has to match both, the IndexedDB and the WebSQL name conventions.
... otherwise use the debugger
You could set a break point onto your alert(...); line and use the debugger to look inside the evt object. This way you may get either more information about the error itself or more information to share with us.
To do so, enable the development menu in the Safari advanced settings, hit F10 and go to Developer > Start debugging JavaScript (something like that, my Safari is in a different language). Now open then "Scripts" tab in the developer window, select your script and set the break point by clicking on the line number. Reload the page and it should stop right in your error callback, where you can inspect the evt object.
If this doesn't help, you could get the non-minified version of the polyfill and try set some breakpoints around their open function to find the origin of this error.
You could try my open source library https://bitbucket.org/ytkyaw/ydn-db/wiki/Home. It works on iOS and Android.