I need to do some node require commands in a webdriverJS test script, because these dont get entered into the webdriverJS command queue, I am wrapping them in .then() functions (to deal with the asyncrony)
e.g.
var webdriver = require('selenium-webdriver');
// create webdriver instance so promise chain can be setup
var promise_builder = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).
build();
// wrap all functions in webdriver promises so they get managed by webdrivers
// command queue
promise_builder.sleep(0).then(function() {
// Run "non-command-queue" commands
var tests = require('./test_commands');
tests(helpers, setup, webdriver, driver);
}).then(function(){
// more non-webdriver commands
});
The problem here (other than the fact its inelegant) is that a browser instance is launched - just to achieve promise chaining.
Is there a better way to create the initial promise, e.g. a static method within the webdriver api for creating promises?
This seems to work:
// create an instance of webdriver.promise.ControlFlow
var flow = webdriver.promise.controlFlow();
// use webdriver.promise.controlFlow#execute() to schedule statements into command queue
flow.execute(function() {
// Run "non-command-queue" commands
var tests = require('./test_commands');
tests(helpers, setup, webdriver, driver);
}).then(function(){
// more non-webdriver commands
});
An explantion can be found on this Webdriver JS website/docs site, i.e.
At the heart of the promise manager is the ControlFlow class. You can obtain an instance of this class using webdriver.promise.controlFlow(). Tasks are enqueued using the execute() function. Tasks always execute in a future turn of the event loop, once those before it in the queue (if there are any) have completed.
I would use webdriver.promise.createFlow(callback) to start a new control flow.
So you'd have something like this:
webdriver.promise.createFlow(function() {
// Run "non-command-queue" commands
var tests = require('./test_commands');
tests(helpers, setup, webdriver, driver);
}).then(function(){
// more non-webdriver commands
});
Documentation: http://selenium.googlecode.com/git/docs/api/javascript/namespace_webdriver_promise.html
Update
I am now leaning towards the webdriver.promise.controlFlow.execute() option that #the_velour_fog described, since I get errors with after hook failing when new controlFlow is created. Guess creating a new flow messes with mocha async functionality.
Related
I am trying to use the JMeter Selenium Webdriver wait function but getting error output as -javax.script.ScriptException: TypeError: Can not create new object with constructor org.openqa.selenium.support.ui.WebDriverWait with the passed arguments; they do not match any of its method signatures. in at line number 2
var ui = JavaImporter(org.openqa.selenium.support.ui)
var wait = new ui.WebDriverWait(WDS.browser,120)
Code in the webdriver sampler:
var ui = JavaImporter(org.openqa.selenium.support.ui)
var wait = new ui.WebDriverWait(WDS.browser,120)
WDS.sampleResult.sampleStart()
WDS.browser.get('http://jmeter-plugins.org')
WDS.sampleResult.sampleEnd()
I am using the latest version of Jmeter (5.5) and the latest selenium webdriver support package (4.5.1). This use to work before. Can someone help here please? thanks!!
I have tried upgrading and degrading the Jmeter, but no luck.
WebDriver Sampler 4.5.1 comes bundled with selenium-support 4.5.0 and WebDriverWait constructor for this version expects 2nd argument to be Duration object
So you need to do something like:
var wait = new ui.WebDriverWait(WDS.browser, java.time.Duration.ofSeconds(120))
Also be informed that since JMeter 3.1 it's recommended to use Groovy language for scripting mainly for performance reasons so you might want consider switching, it would be way easier to debug your test.
I realize this has sort of been asked before but I want to get a clear confirmation.
I have a Windows Service running the Quartz.Net Scheduler. Jobs and Triggers have been created.
We will have an angular web client that will at times, need to fire jobs manually.
So in a Web API Controller, I have code like this:
var properties = new NameValueCollection
{
["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
["quartz.jobStore.useProperties"] = "true",
["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SqlServerDelegate, Quartz",
["quartz.jobStore.dataSource"] = "myDS",
["quartz.jobStore.tablePrefix"] = "QRTZ_",
["quartz.dataSource.NAME.provider"] = "SqlServer",
["quartz.dataSource.NAME.connectionString"] = "Server=localhost;Database=QuartzScheduler;Uid=blahuser;Pwd=blahpwd",
["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz"
};
var sched = new StdSchedulerFactory(properties).GetScheduler().Result;
var jobKey = new JobKey("DailyJob1130EST", "DailyGroup");
var jobDataMap = new JobDataMap();
jobDataMap.Add("listIds", "33333");
sched.TriggerJob(jobKey, jobDataMap);
The Job Name and Group do exist in the database.
I was hoping that the call to TriggerJob would cause the Scheduler I have running in my windows service, to fire the job. But it doesn't. Nothing happens, not even an error.
BTW, I don't want to use remoting since it requires the full .NET Framework and the help docs say that it is considered unsafe.
If TriggerJob doesn't work, I guess to run a job manually I'd have to add a new trigger to the scheduler to run once, or something???
There may be other ways, but one way that I was able to successfully do it was:
var sched = await new StdSchedulerFactory(properties).GetScheduler();
var jobKey = new JobKey("DailyJob1130EST", "DailyGroup");
var jobDataMap = new JobDataMap();
jobDataMap.Add("listIds", rInt.ToString());
var trig = TriggerBuilder.Create()
.WithIdentity("RunNowTrigger")
.StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5)))
.WithDescription("Run Now Trigger")
.Build();
sched.TriggerJob(jobKey, jobDataMap);
Note: "properties" were my NameValueCollection config information, which I omitted from the sample code. It was nothing out of the ordinary. It just setup the jobStore, dataSource, serializer.type and threadPool.type settings.
I was wondering how I can achieve something like an HTTPClient.
I tried WebBrowser class but it seems that the execution continues even though the URL specified has not yet loaded.
public void testWebBrowser(){
final WebBrowser b = new WebBrowser(){
#Override
public void onLoad(String url) {
BrowserComponent c = (BrowserComponent)this.getInternal();
JavascriptContext ctx = new JavascriptContext(c);
// I want this Javascript context here
}
};
// just a test URL
b.setURL("http://youtube.com");
// Suppose to get the Javascript context here though it executes without waiting for the whole page to load
}
How can I get the JS Context from within a WebBrowser context? Like a synchronous execution
WebBrowser browser = new WebBrowser();
browser.setURL("someURL");
// wait execution till the whole page in "someURL" loads till it executes the next line
BrowserComponent c = (BrowserComponent)browser.getInternal();
JavascriptContext ctx = new JavascriptContext(c);
If I understand correctly you are trying to create a scraping solution?
That's probably not the ideal approach since this will actually create a web browser which you then need to automate with JavaScript. I would suggest you create a webservice that encapsulates the HttpClient functionality and drive it with ConnectionRequest. This way when the web site changes you can just fix your server in a way seamless to your installed base.
I want time delay before function call in apex code. I already created one delay method but it is not working as per expectation. So, is there any way to get this working.
Thanks in advance.
Probably a better way to do this would be to break up your Apex code such that the part you want to execute later is in a separate method. You can then call this method from another method that has an #future annotation, or use the Apex Scheduler to schedule that code for a future time. Either of these methods will cause the code to be executed asynchronously after your original method has completed (the #future method is easier to implement but the scheduler method has the advantage of running at a predictable time).
If you need something like the sleep() function, one way to do it is to make a call to a http service which will sleep a requested amount of time. This is fairly simple to do, and there are existing publicly available services for it, for example the one at http://1.cuzillion.com/bin/resource.cgi.
First you have to Configure a new Remote Site in SalesForce (Security Controls -> Remote Site Settings), name it however you want but make sure the Remote Site URL matches the above URL, and that the "Active" checkbox is checked.
After that, you can define your method in code like so:
public static void sleep(Integer sleepSeconds) {
Long startTS = System.currentTimeMillis();
HttpRequest req = new HttpRequest();
req.setEndpoint('http://1.cuzillion.com/bin/resource.cgi?sleep=' + sleepSeconds);
req.setMethod('GET');
Http http = new Http();
HTTPResponse res = http.send(req);
Long duration = System.currentTimeMillis() - startTS;
System.debug('Duration: ' + duration + 'ms');
}
Running it yields:
sleep(1);
-> 08:46:57.242 (1242588000)|USER_DEBUG|[10]|DEBUG|Duration: 1202ms
You can easily do this in Visualforce. Either use apex:actionPoller and set the timeout property to whatever you want the interval to be. Or use window.setTimeout(function, 1000) in JavaScript. Then from the function in JavaScript you can either use JavaScript Remoting or apex:actionFunction to call back into Apex.
I need to check if a file exists and I need to do it from several places in code.
Some of the places I can handle it with a callback (kinda ugly but it will work). But the one I don't know how to handle seems to require that it be Synchronous.
I need to call the method to check if it exist from a RelayCommand as the "canExecute" method.
Any ideas on how to handle this?
This is what I currently have but calling the .WaitOne on the UI thread is blocking the background worker so it completely locks the app.
private bool FileExists(Uri file)
{
var exists = false;
ManualResetEvent resetEvent = new ManualResetEvent(false);
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, e) =>{
WebRequest request = HttpWebRequest.Create(file);
request.Method = "HEAD"; //only request the head so its quick
request.BeginGetResponse(result =>
{
try
{
//var response = request.EndGetResponse(result);
var req = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(result);
exists = (response.StatusCode.ToString() == "OK");
}
catch
{
exists = false;
}
resetEvent.Set();
}
, request);
};
worker.RunWorkerAsync();
resetEvent.WaitOne();
return exists;
}
You should never make HTTPWebRequest's synchronous on the UI thread - this could block the UI for seconds or minutes...
If you really want to make an HTTPWebRequest appear to be synchronous on a background thread then simply use a ManualResetEvent inside a callback - e.g. something like:
var resetEvent = new ManualResetEvent();
theHttpWebRequest.BeginGetResponse((result) => {
var response = theHttpWebRequest.EndGetResponse(result);
// use response.StatusCode to check for 404?
resetEvent.Set();
});
resetEvent.WaitOne();
Also, please note that checking if a file exists over HTTP might be better done by calling a small webservice which does the check - it depends on the size of the file you are checking.
AFAIK this is not possible. You can never make synchronous calls to web services in Silverlight.
You have to leave canExecute method empty (to always execute the command), and make async call to check if file exists in handler for the command. The real code for the command has to execute in handler for that async call.
I think it is only way you can manage it.
btw-you can use lambda expressions to make it look more like synchronous code. Or maybe Reactive Extensions may help with better looking code (jesse's tutorial).
The way I would approach this problem is to create some kind of flag ( i.e IsFileExists) and return that flag from CanExecute method. Flag shold be set to false initially and your button disabled under assumption that untill we know that file does exits we consider it doesn't. Next I would fire HTTPWebRequest or wcf call or any other async method to check if file exists. Once callback confirms that file exists set flag to true and fire CanExecuteChanged event. If you want to be fancy you can add some visual feedback while waiting for responce. In general user experienc would be much better than locking up screen for duration of the web request.