Checking if an element is present in protractor - protractor

I have a protractor test that expects a certain panel to be NOT PRESENT after login. My code is below, but every time it is executed, protractor hangs and then fails later on.
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
it('The team overlay page should not be present when another user logs in.', function() {
loginPage.login(user.username, user.password);
expect(element(by.css('div.panel#myPanel')).isPresent()).toBe(false);
});
I also tried using .count() but it also does the same thing. Same error as above.
expect(element.all(by.css('div.panel#myPanel')).count()).toBe(0);

You could try waiting for the element by allowing the browser to fully load with some of the following:
browser.driver.sleep(time in milliseconds)
browser.waitForAngular()
You could increase the timeout interval:
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000
Otherwise:
Make sure your locator via css is working correctly (i.e, test it when the panel should be present), and make sure the webpage you are trying to access supports Angular. My bet is there is something incorrect with the format of your locator, as I don't see what else could be an issue.

Related

Slow performance in a second POST request on SAPUI5

the community of SAPUI5 in the world is so small, so i need to see if someone can help me with this problem or an explanation of what may be happening next.
I have a UI5 application which consumes gateway services using the oDataModel,
When I try to make a POST request, the service responds very quickly, but the second time I call the same service the times of the request increase drastically, as in 200%. The strangest thing of all is that the first request and the second are the same.
In my browser, the first request has a success time of approximately 10 seconds, while the second request (which is equal to the first) has a time of 2-3 minutes.
In my browser, THE SECOND REQUEST appears with status of "Pending" for 2-3 minutes, but in gateway the request was completed correctly in like 20 seconds.
this is the way i call the oDataModel the first time and the second time.
SERVICE
var oModel = new sap.ui.model.odata.ODataModel(serviceUrl);
oModel.headers = {
"X-Requested-With": "XMLHttpRequest",
"Accept": "application/atom+xml,application/atomsvc+xml,application/xml,application/atom+xml",
"Content-Type": "application/atom+xml",
"DataServiceVersion": "2.0"
};
oModel.setCountSupported(false);
oModel.setSizeLimit(this._maxSize);
oModel.attachRequestFailed(this.showLoadError);
then, in my controller i do the following.
CONTROLLER
function initializeOrders(){
var oParameters = {
Lgnum: localStorage.Yard,
PlanStatus: "",
Orders: [{}],
Transports: [{}]
};
oModel.create("/IncomingSet", oParameters,
null,
jQuery.proxy(this._readODataOnSuccess, this),
jQuery.proxy(this._readODataOnError, this)
)}
This initializeOrders function is executed when the application is started and it is also executed when I want to refresh the application information if there were changes.
If someone can help me with this question I will be very grateful because not in the sap forums I have not found anything good
I found the problem, it was the rendering of some controls, but the chrome console show like pending because of that. this must be closed, as a solution for all the people who find this problem:
-If you have a control that uses a big amount of data coming from the service always try to use it on demand, the amount of data can block the memory of the browser. In example, a dynamic combobox charged with model
the best practice is just to set the model when you need it
maybe its a bug from Chrome or i dont know, well... its solved... 2 weeks to solve this.

Play ws scala server hangs up on request after 120seconds - which options to use?

I am pretty sure that this is a config problem, so I'll post my code and the relevant application.conf options of my play app.
I have a play server that needs to interact with another server "B" (basically multi-file upload to B). The interaction happens inside an async -Action which should result in an OK with B's response on the upload. This is the reduced code:
def authenticateAndUpload( url: String) = Action.async( parse.multipartFormData) { implicit request =>
val form = authForm.bindFromRequest.get
val (user, pass) = (form.user, form.pass)
//the whole following interaction with the other server happens in a future, i.e. login returns a Future[Option[WSCookie]] which is then used
login(user, pass, url).flatMap {
case Some(cookie) => //use the cookie to upload the files and collect the result, i.e. server responses
//this may take a few minutes and happens in yet another future, which eventually produces the result
result.map(cc => Ok(s"The server under url $url responded with $cc"))
case None =>
Future.successful(Forbidden(s"Unable to log into $url, please go back and try again with other credentials."))
}
}
I am pretty sure that the code itself works since I can see my server log which nicely prints B's responses every few seconds and proceeds until everything is correctly uploaded. The only problem is that the browser hangs up with a server overloaded message after 120s which should be a play default value - but for which config parameter?
I tried to get rid of it by setting every play.server.http. timeout option I could get my hands on and even decided to use play.ws, specific akka, and other options of which I am quite sure that they are not necessary... however the problem remains, here is my current application.config part:
ws.timeout.idle="3600s"
ws.timeout.request ="3600s"
ws.timeout.response="3600s"
play.ws.timeout.idle="3600s"
play.ws.timeout.request="3600s"
play.ws.timeout.response="3600s"
play.server.http.connectionTimeout="3600s"
play.server.http.idleTimeout="3600s"
play.server.http.requestTimeout="3600s"
play.server.http.responseTimeout="3600s"
play.server.http.keepAlive="true"
akka.http.host-connection-pool.idle-timeout="3600s"
akka.http.host-connection-pool.client.idle-timeout= "3600s"
The browser hang up happened both on Safari and Chrome, where Chrome additionally started a second communication with B after about 120 seconds - also both of these communications succeeded and produced the expected logs, only the browsers had both hang up.
I am using Scala 2.12.2 with play 2.6.2 in an SBT environment, the server is under development, pre-compiled but then started via run - I read that it may not pick up the application.conf options - but it did on some file size customizing. Can someone tell me the correct config options or my mistake on the run process?

Protractor: test loading state

I'm setting up protractor for our web app, and all works fine, except one thing: When someone clicks the "login" button, while the HTTP request is running, the button should have class "loading". However, when I try to test this, protractor waits for the HTTP request to finish before it runs the expectation, which then fails, because the loading class is removed again.
How can I assert that the loading class is added?
describe('Authorization', function() {
it('the site loads', () => {
browser.get('/');
expect(browser.getCurrentUrl()).toBe('http://localhost:8000/#/login');
element(by.model('vm.credentials.username')).sendKeys('username');
element(by.model('vm.credentials.password')).sendKeys('password');
element(by.css('#sign-in')).click();
expect(element(by.css('#sign-in')).getAttribute('class')).toMatch(/\bloading\b/);
});
});
I think I found the solution.
The element() function waits for angular to settle in, but browser.driver.findElement() doesn't. So by changing the assertion line to
expect(browser.driver.findElement(by.css('#sign-in')).getAttribute('class')).toMatch(/\bloading\b/);
the tests now pass
As per your problem, protractor is executing your expect statement along with click() function. Protractor is async and fast so it executes everything that it can and then waits for promise/callback to be returned. Try waiting for the click to happen first and then try to assert the class. Here's how you can do it -
element(by.css('#sign-in')).click().then(function(){
expect(element(by.css('#sign-in')).getAttribute('class')).toMatch(/\bloading\b/);
});
Also if the http request is blocking your execution, then try to wait for the element to be displayed. If the element is displayed then it's as good as your element is verified.
browser.wait(protractor.ExpectedConditions.visibilityOf($('.loading')), 10000)
.then(function(){
expect(true).toBe(true);
});
Hope this helps.

How do I call a method on my ServiceWorker from within my page?

I have a ServiceWorker registered on my page and want to pass some data to it so it can be stored in an IndexedDB and used later for network requests (it's an access token).
Is the correct thing just to use network requests and catch them on the SW side using fetch, or is there something more clever?
Note for future readers wondering similar things to me:
Setting properties on the SW registration object, e.g. setting self.registration.foo to a function within the service worker and doing the following in the page:
navigator.serviceWorker.getRegistration().then(function(reg) { reg.foo; })
Results in TypeError: reg.foo is not a function. I presume this is something to do with the lifecycle of a ServiceWorker meaning you can't modify it and expect those modification to be accessible in the future, so any interface with a SW likely has to be postMessage style, so perhaps just using fetch is the best way to go...?
So it turns out that you can't actually call a method within a SW from your app (due to lifecycle issues), so you have to use a postMessage API to pass serialized JSON messages around (so no passing callbacks etc).
You can send a message to the controlling SW with the following app code:
navigator.serviceWorker.controller.postMessage({'hello': 'world'})
Combined with the following in the SW code:
self.addEventListener('message', function (evt) {
console.log('postMessage received', evt.data);
})
Which results in the following in my SW's console:
postMessage received Object {hello: "world"}
So by passing in a message (JS object) which indicates the function and arguments I want to call my event listener can receive it and call the right function in the SW. To return a result to the app code you will need to also pass a port of a MessageChannel in to the SW and then respond via postMessage, for example in the app you'd create and send over a MessageChannel with the data:
var messageChannel = new MessageChannel();
messageChannel.port1.onmessage = function(event) {
console.log(event.data);
};
// This sends the message data as well as transferring messageChannel.port2 to the service worker.
// The service worker can then use the transferred port to reply via postMessage(), which
// will in turn trigger the onmessage handler on messageChannel.port1.
// See https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
navigator.serviceWorker.controller.postMessage(message, [messageChannel.port2]);
and then you can respond via it in your Service Worker within the message handler:
evt.ports[0].postMessage({'hello': 'world'});
To pass data to your service worker, the above mentioned is a good way. But in case, if someone is still having a hard time implementing that, there is an other hack around for that,
1 - append your data to get parameter while you load service-worker (for eg., from sw.js -> sw.js?a=x&b=y&c=z)
2- Now in service worker, fetch those data using self.self.location.search.
Note, this will be beneficial only if the data you pass do not change for a particular client very often, other wise it will keep changing the loading url of service worker for that particular client and every time the client reloads or revisits, new service worker is installed.

asp.net mvc azure "Error accessing the data store!"

I've started using the AspProviders code to store my session data in my table storage.
I'm sporadically getting the following error:
Description: Exception of type 'System.Web.HttpException' was thrown. INNER_EXCEPTION:Error accessing the data store! INNER_EXCEPTION:An error occurred while processing this request. INNER_EXCEPTION: ConditionNotMet The condition specified using HTTP conditional header(s) is not met. RequestId:0c4239cc-41fb-42c5-98c5-7e9cc22096af Time:2010-10-15T04:28:07.0726801Z
StackTrace:
System.Web.SessionState.SessionStateModule.EndAcquireState(IAsyncResult ar)
System.Web.HttpApplication.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) INNER_EXCEPTION:
Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive(HttpContext context, String id, Object lockId) in \Azure\AspProviders\TableStorageSessionStateProvider.cs:line 484
System.Web.SessionState.SessionStateModule.GetSessionStateItem()
System.Web.SessionState.SessionStateModule.PollLockedSessionCallback(Object state) INNER_EXCEPTION:
Microsoft.WindowsAzure.StorageClient.Tasks.Task1.get_Result()
Microsoft.WindowsAzure.StorageClient.Tasks.Task1.ExecuteAndWait()
Microsoft.WindowsAzure.StorageClient.TaskImplHelper.ExecuteImplWithRetry[T](Func`2 impl, RetryPolicy policy)
Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive(TableServiceContext svc, SessionRow session, Object lockId) in \Azure\AspProviders\TableStorageSessionStateProvider.cs:line 603
Microsoft.Samples.ServiceHosting.AspProviders.TableStorageSessionStateProvider.ReleaseItemExclusive(HttpContext context, String id, Object lockId) in \Azure\AspProviders\TableStorageSessionStateProvider.cs:line 480 INNER_EXCEPTION:
System.Data.Services.Client.DataServiceContext.SaveResult.d__1e.MoveNext()
Anyone run into this? The only useful information I've found is this, which I'm hesitant to do:
If you want to bypass the validation, you can open TableStorageSessionStateProvider.cs, find ReleaseItemExclusive, and modify the code from:
svc.UpdateObject(session);
to:
svc.Detach(session);
svc.AttachTo("Sessions", session, "*");
svc.UpdateObject(session);
from here
Thanks!
So I decided to change this:
svc.UpdateObject(session);
svc.SaveChangesWithRetries();
to this:
try
{
svc.UpdateObject(session);
svc.SaveChangesWithRetries();
}
catch
{
svc.Detach(session);
svc.AttachTo("Sessions", session, "*");
svc.UpdateObject(session);
svc.SaveChangesWithRetries();
}
So, I'll see how that works...
I've encountered this problem as well and after some investigation it seems to happen more often when you have more than one instance and you try to make calls in rapid succession in the same session. (e.g. if you had an auto complete box and making ajax calls on each key press)
This occurs because when you try to access the session data, first of all the web server takes out a lock on that session. When the request is complete, it releases the lock. With the table service provider, it updates this lock status by updating a field in the table. What I think is happening is that Instance1 loads the session row, then Instance2 loads the session row, Instance1 saves down the updated lock status and when Instance2 attempts to save the lock status it gets an error because the object isn't in the same state as when it loaded it (the ETag doesn't match any more).
This is why the fix that you found will stop the error from occurring, because by specifying the "*" in the AttachTo, when Instance2 attempts to save the lock it will turn off ETag checking (and over write the changes made by Instance1).
In our situation we have altered the provider so that we can turn off session for certain paths (the ajax call that was giving us our problems didn't need access to session data, neither did the loading of images) which may be an option for you depending on what is causing your problem.
Unfortunately the TableStorageSessionStateProvider is part of the sample projects and so isn't (as far as I'm aware, but I'll happily be told otherwise) officially supported by Microsoft. It does have other issues, like the fact that it doesn't clean up it's session data once a session expires, so you will end up with lots of junk in the session table and blob container that you'll have to clean up some other way.