I am trying place the assertion function in Page object file to avoid multiple .should in my script file, below is my code:
Elements.flow.getheader().should('have.text', 'Confirm Funding Summary')
Elements.flow.getblueinfotext().should('have.text', 'Warning')
Elements.flow.getvelocitytext().should('have.text','Velocity')
Elements.flow.getheading1().should('have.text', 'Complete')
Elements.flow.getheading2().should('have.text', 'Learn ')
Elements.flow.getheading3().should('have.text', 'Introduce')
Elements.flow.getheading4().should('have.text', 'Verified')
How can I get the element/web locator in my function dynamically to assert the text
validateText(expectedText) {
dynamicelement.should('have.text','expectedText')
})
Related
I'm making a program that will automatically open the launch meeting page to take me to my next ZOOM class on time, and our schools have 'a days' and 'b days', each with a different schedule, so I have an HTML page that has two buttons, one that will trigger the schedule for an A day and another that triggers the schedule for a B day. I'm testing the functions that will open the new tab and run that function from the HTML, but when I run it from the HTML, I get an error message in my executions that says cannot call DocumentApp.getUI from this context. My code is here, if you put it into GAS you can see for yourself.
Part of my code came from this answer
My code.gs file
function doGet() {
return HtmlService.createHtmlOutputFromFile('index.html');
}
function openUrl( url ){
var html = HtmlService.createHtmlOutput('<html><script>'
+'window.close = function(){window.setTimeout(function(){google.script.host.close()},9)};'
+'var a = document.createElement("a"); a.href="'+url+'"; a.target="_blank";'
+'if(document.createEvent){'
+' var event=document.createEvent("MouseEvents");'
+' if(navigator.userAgent.toLowerCase().indexOf("firefox")>-1){window.document.body.append(a)}'
+' event.initEvent("click",true,true); a.dispatchEvent(event);'
+'}else{ a.click() }'
+'close();'
+'</script>'
+'<body style="word-break:break-word;font-family:sans-serif;">Failed to open automatically. Click here to proceed.</body>'
+'<script>google.script.host.setHeight(40);google.script.host.setWidth(410)</script>'
+'</html>')
.setWidth( 90 ).setHeight( 1 );
DocumentApp.getUi().showModalDialog( html, "Opening ..." );
}
function LaZoom(){
openUrl('https://op97-org.zoom.us/j/9622570589');
}
My HTML file
<!DOCTYPE html>
<html>
<button onclick = 'aDay()'>A day</button>
<button onclick = 'bDay()'>B day</button>
</html>
<script>
function aDay(){
google.script.run.LaZoom();
alert('ran')
}
</script>
You can easily do this client side using window.open instead of going back and forth between server and client.
function aDay(){window.open('A_URL')}
I am having a <label id=ajaxtest>Not ajax</label> in the HTML page. After 5 seconds the label get changed to <label id=ajaxtest>Called ajax</label>
I am using nightwatch and trying to assert the text whether "Called ajax" is coming. I am new to nightwatch and kind of stuck how I can go. I tried few steps using asynch function and getText the label and nothing seems to work.
'Should display "Called ajax" message': (client) => {
home
.waitForElementVisible('#ajaxlabel',1000)
.assert.containsText('#ajaxlabel', 'not ajax');
client
.executeAsync(function(done) {
(function fn(){
// tried getText() here but the code is not working..
return done("Finally");
})();
}, [], function(result) {
console.log("Inside Final:"+result.value);
});
You can probably use the before/after methods to accomplish this.
home.expect.element('#ajaxlabel').text.to.contain('Called ajax').after(5000);
I'm really struggling with getting the percentage value of progress that is continuously being updated in a function on my controller to appear in template GSP page using remoteFunction.
This is my controller code and "progressData" is sent from a service to constantly update the current progress of a task:
def progress(progressData) {
def statusToView = progressData
[statusToView: statusToView]
}
and in my _progress.gsp page:
<g:javascript>
setInterval( "refreshMe();", 300 );
function refreshMe(){
${remoteFunction(action:'progress', controller:'data')}
}
</g:javascript>
The controller is expecting the property progressData which is doesn't get from the remoteFunction, and so I'm guessing I have to think to do this another way but I'm just at a bit of a loss now. Plus I'm not getting the value statusToView within the GSP because of this.
As you pointed out, your action progress is actually waiting for the progressData param, which is not passed.
If your progressData value is stored somewhere in your gsp page, you should change your remoteFunction in this way or similar:
$remoteFunction(action: 'progress', controller: 'data', update: [success: 'great', failure: 'ohno'], params: '\'progressData=\' + progressData')
Regarding update: [success: ... ], here you can find the description of the various attributes.
I'm using Node.js, Express and Jade and I'm trying to figure out how to post, validate & process form data.
In my jade file I create a contact form:
div#contact-area
form(method='post',action='')
label(for='name') Name:
input(type='text',name='name',id='name')
label(for='email') Email:
input(type='text',name='email',id='email')
input(type='submit',name='submit',value='Submit').submit-button
I'm then utilising the module 'express-validator' to validate the form as follows:
var express = require('express')
,routes = require('./routes')
,http = require('http')
,path = require('path')
,expressValidator = require('express-validator')
;
var app = express.createServer();
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'jade'); //not needed if we provide explicit file extension on template references e.g. res.render('index.jade');
app.use(express.bodyParser());
app.use(expressValidator);
app.use(express.methodOverride());
app.use(app.router);
});
//display the page for the first time
app.get('/mypage', function(req,res){
res.render('mypage', {
title: 'My Page'
});
});
//handle form submission
app.post('/mypage', function(req,res){
req.assert('name', 'Please enter a name').notEmpty();
req.assert('email', 'Please enter a valid email').len(6,64).isEmail();
var errors = req.validationErrors();
if( !errors){
sendEmail(function(){
res.render('mypage', {
title: 'My Page',
success: true
});
});
}
else {
res.render('mypage', {
title: 'My Page',
errors: errors
});
}
});
So there are three scenarios where my pages is rendered, and each one has access to different local variables:
When the page is loaded for the first time (errors=undefined,success=undefined)
When the form is submitted and there are errors (errors=array,success=undefined)
When the form is submitted and there are no errors (errors=undefined,success=true)
So my main problems are that:
When my Jade page is loaded, it seems to throw an error when I attempt to access a variable that doesn't exist. For example, I want to see if the variable 'success' is set, and if it is I want to hide the form and display a "thanks" message. Is there an easy way to handle a variable in Jade that will either be undefined or a value?
When the form has been submitted and there are validation errors, I want to show an error message (this isn't a problem) but also populate the form with the variables that were previously submitted (e.g. if the user provided a name but no email, the error should reference the blank email but the form should retain their name). At the moment the error message is displayed but my form is reset. Is there an easy way to set the input values of the fields to the values in the post data?
You can fix that by using locals.variable instead of just variable. Also you can use javascript in jade.
-locals.form_model = locals.form_data || {};
I used two ways to solve this problem. The first one is to re-render the view and you pass the req.body as a local. I have a convention that my forms use form_model.value for their field values. This method is works well for simple forms but it starts to breakdown a little when you form is relying on data.
The second method is to pass your req.body to session then redirect to a route that renders the form. Have that route looking for a certain session variable and use those values in your form.
Inside your jade file add error msg and then run your code.
Simply update your jade code with below code:
div#contact-area
ul.errors
if errors
each error, i in errors
li.alert.alert-danger #{error.msg}
form(method='post',action='')
label(for='name') Name:
input(type='text',name='name',id='name')
label(for='email') Email:
input(type='text',name='email',id='email')
input(type='submit',name='submit',value='Submit').submit-button
I have two Ajax calls. I need to make sure that a JS function is executed between these two calls.
Is it possible to trigger the execution of a client-side JS function via the AJAX response? Or how would you do this kind of thing?
EDIT My code, after doing what was suggested by the first answer (onComplete):
^ (html jQuery ajax
callback: [ :text | id := self createNewAnnotation: text ]
value: (self html jQuery: '#annotationText') value;
onComplete: ((JSStream on: 'displayAnnotation("', id, '")'),
(self html jQuery ajax
callback: [ :text | finalText := text ]
value: (self html jQuery: '#text') html)
);
What this is supposed to do: on the first callback, the value of the #annotationText field is passed to createNewAnnotation, which saves the annotation and returns the ID.
Next, I want to pass that ID to the client-side JS function displayAnnotation().
In this example, this can't yet work, as the code around JSStream on: is not in a block and thus has the initial value of id. How can I pass that result of the server-side method as parameter to the client-side function?
In Seaside, you probably would use the jQuery bindings to execute ajax calls. If you want to make sure that two ajax calls are chained and some other JS code is executed in between, the code would follow these lines:
renderContentOn: html
html span
onClick: (html jQuery ajax
callback: [...1st ajax callback...];
onComplete: ((JSStream on: '... some JS code ...'),
(html jQuery ajax callback: [...2nd ajax callback...]));
with: 'Click this to trigger the calls'.
This will render a span that, when clicked, will execute the 1st ajax call. If that one completes, the JS code and the second ajax call will be executed.
EDIT:answer to the additional question:
If you want the 'id' that is passed on to the call of displayAnnotation to be computed by the first callback, you can only generate that call after the first callback has executed. The value can be passed between ajax callbacks via temporary variables or instance variables (because of closures). The following piece of code makes the chaining via onComplete: explicit. Afterwards, I give an example where less ajax calls are made.
^ (html jQuery ajax
callback: [ :text | id := self createNewAnnotation: text ]
value: (html jQuery: #annotationText) value;
onComplete:
(html jQuery ajax
script:[:s | s << ((JSStream on: 'displayAnnotation("', id, '")')]
onComplete:
(html jQuery ajax
callback: [ :text | finalText := text ]
value: (html jQuery: #text) html)))
You can also reduce the number of ajax calls if you understand how Seaside callbacks work. In summary, the block that produces the response of the callback is always invoked last. This allows to group a number of callback blocks in a single call. Such as:
^ (html jQuery ajax
callback: [ :text | id := self createNewAnnotation: text ]
value: (html jQuery: #annotationText) value;
script:[:s | s << ((JSStream on: 'displayAnnotation("', id, '")')];
onComplete:
(html jQuery ajax
callback: [ :text | finalText := text ]
value: (html jQuery: #text) html)))
The XMLHttpRequest object has a onreadystatechange event. When the object reaches a readyState of 4, you can make your second AJAX request by binding an anonymous function to that event. If you want a more detailed response please post what you have tried and some code and the SO community will be more than willing to give you a more detailed answer.