Do VSCode webviews support Web Workers? - visual-studio-code

I'm in the middle of making a vscode extension, noticed some strange interactions when I tried to implement a Dedicated Worker to my extensions webview.
I'm already using the vscode API to pass messages around the extension, however when using a dedicated worker(in the webview) & passing messages around else where in the extension, the web worker somehow gets called.
If I let my web worker send a call back an infinite loop occurs and VSCode crashes. This leaves me to believe that VSCode is actually utilising web workers already? But shouldn't a new dedicated worker be spawned when using new Worker(), regardless of VSCode?
I tried implementing a shared worker, but didn't have any success (no response at all from the SharedWorker), which leaves me to believe that webviews don't support this? Am I right in saying that? Has anyone implemented this before?
I tried finding more information online and on their GitHub issues, but wasn't able to :/
TLDR: Do Webviews in VSCode support web workers?

Yes, you can. I don't know about seperate files, but you can use URL.createObjectUrl() to create a worker. Here is some code that worked for me (inside the webview html).
const blob = new Blob(['self.postMessage("Message from worker")'])
const uri = URL.createObjectURL(blob)
new Worker(uri).addEventListener('message', e => {
console.log(e)
})

Related

VS Code API - remote calls

I am currently investigating VS code extensions in conjunction with a code generation project. While I understand that the VS code API is fairly full-fledged to allow in-extension manipulation of documents I can't figure out how to do this outside of the extension.
Are there ways of remotely executing the vs code JavaScript APIs outside of vscode which in turn will drive the GUI.
I am trying to figure out if I can do any of the following:
Execute the API JavaScript code when through the code cli
Run a web server/socket within an extension to listen to events from external systems and execute the JS API accordingly
If not socket/rest server, should I listen to filesystem changes and react accordingly?
Basically, what are the options for remote control driving of vs code?
I've faced a similar problem with an editor extension I'm working on.
I would highly recommend listening to file changes outside of VSCode APIs. This way the majority of your code is not bound to a specific editor. I also had much more difficulty using the VSCode API called createFileSystemWatcher as it didn't capture all changes.
Upon activation, run a child process using a file watcher library. I'd recommend using chokidar - its the same library VSCode uses internally but with more extensive access to the API.
// get your workspace uri & root uri
const workspaceRoots = vscode.workspace.workspaceFolders
if (!workspaceRoots || !workspaceRoots.length) {
throw new Error('No workspace root path')
}
const workspaceRoot: vscode.WorkspaceFolder = workspaceRoots[0]
const rootUri = vscode.workspace.getWorkspaceFolder(workspaceUri);
// the action you want to trigger
const command = vscode.commands.registerCommand('YOUR_CUSTOM_COMMAND', yourCustomFunction)
// file watcher
const fsWatcher = chokidar.watch('watcher_name', {
cwd: rootUri.uri.path,
interval: 1000,
})
// listen to any add/update/delete fs events
fsWatcher.on('change', (path, event) => {
vscode.commands.executeCommand('YOUR_CUSTOM_COMMAND')
})
On any file change, it can trigger the action of your choice.
If a VS Code extension can achieve everything you are after, then the simplest approach would be to let the extension be driven externally. VS Code extensions run in a node.js environment, so they can start a http server, listen on a named pipe, or communicate with the outside world using pretty much any other mechanism.
You can also take a look at VS Code support for testing extensions, since tests also just use standard VS Code extension apis: https://code.visualstudio.com/api/working-with-extensions/testing-extension
For the development of VS Code itself, there are some automation scripts that simulate user actions. If you really need to, I believe you could adopt these script to your use case, however I can't say how much work it would be. These script also break if the UI changes. Better to go the extension route if possible

blank.html is downloaded multiple times

GWT is used and the application is deployed on WebLogic using HTTPS.
The performance is poor and with F12 Developer Tools, we could see that blank.html is downloaded multiple times. This is clearly related to GWT but we have not been able to figure out why.
The following is from javascript:
defineSeed(2613, 2614, makeCastMap([Q$BaseModelData, Q$ModelData, Q$Theme, Q$Serializable]), Slate_0);
var SLATE;
function $clinit_GXT(){
$clinit_GXT = nullMethod;
IMAGES = new XImages_generatedBundle_0;
MESSAGES = new XMessages__0;
SSL_SECURE_URL = getModuleBaseURL() + 'blank.html';
}
This is from GWT.java:
/**
* URL to a blank file used by GXT when in secure mode for iframe src to
* prevent the IE insecure content. Default value is 'blank.html'.
*/
public static String SSL_SECURE_URL = GWT.getModuleBaseURL() + "blank.html";
Does anyone know under what circumstances blank.html is called?
Thanks!
This is from GWT.java:
This is actually from GXT.java.
This is used in a few cases when creating an <iframe> element, so that IE won't give errors if your site is hosted from SSL. I can actually only find one case (as of GXT 3.1.1) which uses this, in Layer.java. Only IE pages loaded from https urls will make use of this.
The Layer class uses this as a "shim", a way to prop up some DOM elements above overs, and work around some browser bugs (typically plugin or iframe related). Menus and popup dialogs use this to ensure that they don't appear "underneath" content that they should be "above".
This file is very small - just enough HTML to convince IE than the iframe has correctly loaded, and no more. It never changes, and should load nearly instantly.
As far as performance goes, this should only happen when a Menu or Window/Dialog/Tooltip is shown - these shouldn't be happening on app startup usually, at least not more than a window or two. Additionally, the browser should recognize that it is loading the same element and cache it correctly, and not load it multiple times (though it might be listed several times as hitting the cache). If the server has instructed the browser to never cache the file, that is something you should look at changing.
In short, this is very unlikely to be the cause of any performance issues, at least in GXT itself. If somehow you have the shim enabled on every single widget in your project, this should not be required. If the file is loading slowly, something may be very wrong with your server configuration.
For reference, here is the entire file:
<html></html>

Unable to Open new browser after each scenario in Cucumber-Protractor

I had automated all my scenarios using cucumber-protractor framework. All this scenarios run fine when executed individually i.e. closes the browser once scenario is complete but when ran together I am unable to open new browser window after each scenario. It just continues in same browser. Due to SSO login, I have to restart browser after each scenario.
I tried using maxSession, maxInstance in protractor but of no help. Though maxIntance opens new browser, it doesn't close old one and neither passes control to new one. I tried using getWindowHandler as well but that also didn't worked.
Any help is greatly appreciated as I am stuck on this for long time.
It seems juliemr answers your question:
tests are sharded by file, not by scenario, so you'll need to split the scenarios into separate files.
https://github.com/angular/protractor/issues/864#issuecomment-45571006
So you'll need to split the scenarios into separate feature files and, if desired, set maxInstances to however many you want to run at once. For example:
capabilities: {
'browserName': 'chrome',
'shardTestFiles': true,
'maxInstances': 10
}
Add a hook after each scenario to close the browser:
this.After(function(scenario, done) {
this.quit(done);
});

Coded UI - Add-ons

I'm using VS 2013 with CodedUI to automate UI tests on an application that is not built by my client (it's an implementation project). When inspecting the UI Control using inspect or coded UI, I see that the Automation ID keeps changing and I have no real way (beside position based) to capture my controls (the application is developed in Delphi).
So I'm wondering if there exist some library or add-ons (or something not even related to Coded UI and VS) that can help with this? For example some tools that can capture a screen shot of the control and then map it (the screenshot) to an Control Id that I will define and use that to automate?
Wow....I was able to find a way to do what I need using sikuli (http://www.sikuli.org/) checkout this post. Ill actually try it out tomorrow. But I found on the web (link below) that it`s possible.
From Coded UI we can call the sikuli script like that:
Process process = new Process();
ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.FileName = #"D:\Sikuli\ds.bat";
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
(code from) https://answers.launchpad.net/sikuli/+question/232233 , read this post guys!

Eclipse RAP - Firefox doesn't forget session

We've got an Eclipse RAP application that's behaving a bit strangely in Firefox - two distinct problems.
When you browse around, you can click on a button in one part of the system. This opens a popup window like so:
IWorkbenchBrowserSupport bs;
bs = PlatformUI.getWorkbench().getBrowserSupport();
int style = IWorkbenchBrowserSupport.AS_EXTERNAL;
IWebBrowser b = bs.createBrowser(style, getRandomID(), "Hello world", "");
b.openURL(new URL(...));
where the URL is another servlet in the application. This servlet is in the same runtime, but has nothing to do with RAP - it takes a binary blob from in-memory storage and dumps it in the output stream.
Problem 1: This causes the HTTP session to die in firefox, and shows the "session expired" RAP error page with a link to restart the session.
Problem 2: Now, when you click on the link to restart the session, it shows the application's dialog again, but the session expired error is shown again the moment you do anything. This prevents the user from using the system again, unless Firefox is closed down completely and restarted. A quick peek with FireBug reveals that the JSESSIONID passed by Firefox does not change.
Has anyone seen this before?
How long is the dumping of the stream to the output? May it cause a timeout? As RAP uses Javascript calls, it might be much shorter than the normal timeout time.
For problem 2: Firefox caches a lot of things; and if the Javascript execution hangs, it might cause such problems.
Are these problems present in other browsers? It might be a good idea to check with the internal browser (or any other browser with a different rendering engine).
It turns out that if a RAP application opens a popup window pointing to a servlet in the application itself, inside the current HTTP servlet context, the session is killed. Fixed by creating a dummy HTTP context for the servlet in question.
If you need to deliver content from within the same application, you should use a service handler instead. See this FAQ:
http://wiki.eclipse.org/RAP/FAQ#How_to_provide_download_link.3F