I see the following step in noraUI sources
#And("I expect to have {page-element} with the text {string}(\\?)")
public void expectText(Page.PageElement pageElement, String textOrKey, List<GherkinStepCondition> conditions) throws FailureException, TechnicalException {
this.expectText(pageElement, textOrKey, new Object[0]);
}
I would like to use this step but I can't pass {page-element} for this step. How it should look like?
According to doc I see that it should starts with $, but this step keeps undefined from feature file
What about something like this?
#And('I expect to have $pageElement with the text $string
public void expectText(String pageElement, String string) {
// code to check if the pageElement exists and if it matches the string
}
After reading the doc I've got the solution
We still can't pass object inside of cucumber file because step will be marked as "undefined"
As it is, noraUI has it's own step parser and if I write this step inside of my feature file:
When I click on $google.GoogleHomePage-searchButton
This step will be defined inside of noraUi and this pageObject will be resolved from .ini file of nora configs
Related
I would like to know if it is possible to retrieve the name of a variable.
For example if I have a method:
def printSomething(def something){
//instead of having the literal String something, I want to be able to use the name of the variable that was passed
println('something is: ' + something)
}
If I call this method as follows:
def ordinary = 58
printSomething(ordinary)
I want to get:
ordinary is 58
On the other hand if I call this method like this:
def extraOrdinary = 67
printSomething(extraOrdinary)
I want to get:
extraOrdinary is 67
Edit
I need the variable name because I have this snippet of code which runs before each TestSuite in Katalon Studio, basically it gives you the flexibility of passing GlobalVariables using a katalon.features file. The idea is from: kazurayam/KatalonPropertiesDemo
#BeforeTestSuite
def sampleBeforeTestSuite(TestSuiteContext testSuiteContext) {
KatalonProperties props = new KatalonProperties()
// get appropriate value for GlobalVariable.hostname loaded from katalon.properties files
WebUI.comment(">>> GlobalVariable.G_Url default value: \'${GlobalVariable.G_Url}\'");
//gets the internal value of GlobalVariable.G_Url, if it's empty then use the one from katalon.features file
String preferedHostname = props.getProperty('GlobalVariable.G_Url')
if (preferedHostname != null) {
GlobalVariable.G_Url = preferedHostname;
WebUI.comment(">>> GlobalVariable.G_Url new value: \'${preferedHostname}\'");
} else {
WebUI.comment(">>> GlobalVariable.G_Url stays unchanged");
}
//doing the same for other variables is a lot of duplicate code
}
Now this only handles 1 variable value, if I do this for say 20 variables, that is a lot of duplicate code, so I wanted to create a helper function:
def setProperty(KatalonProperties props, GlobalVariable var){
WebUI.comment(">>> " + var.getName()" + default value: \'${var}\'");
//gets the internal value of var, if it's null then use the one from katalon.features file
GlobalVariable preferedVar = props.getProperty(var.getName())
if (preferedVar != null) {
var = preferedVar;
WebUI.comment(">>> " + var.getName() + " new value: \'${preferedVar}\'");
} else {
WebUI.comment(">>> " + var.getName() + " stays unchanged");
}
}
Here I just put var.getName() to explain what I am looking for, that is just a method I assume.
Yes, this is possible with ASTTransformations or with Macros (Groovy 2.5+).
I currently don't have a proper dev environment, but here are some pointers:
Not that both options are not trivial, are not what I would recommend a Groovy novice and you'll have to do some research. If I remember correctly either option requires a separate build/project from your calling code to work reliable. Also either of them might give you obscure and hard to debug compile time errors, for example when your code expects a variable as parameter but a literal or a method call is passed. So: there be dragons. That being said: I have worked a lot with these things and they can be really fun ;)
Groovy Documentation for Macros
If you are on Groovy 2.5+ you can use Macros. For your use-case take a look at the #Macro methods section. Your Method will have two parameters: MacroContext macroContext, MethodCallExpression callExpression the latter being the interesting one. The MethodCallExpression has the getArguments()-Methods, which allows you to access the Abstract Syntax Tree Nodes that where passed to the method as parameter. In your case that should be a VariableExpression which has the getName() method to give you the name that you're looking for.
Developing AST transformations
This is the more complicated version. You'll still get to the same VariableExpression as with the Macro-Method, but it'll be tedious to get there as you'll have to identify the correct MethodCallExpression yourself. You start from a ClassNode and work your way to the VariableExpression yourself. I would recommend to use a local transformation and create an Annotation. But identifying the correct MethodCallExpression is not trivial.
no. it's not possible.
however think about using map as a parameter and passing name and value of the property:
def printSomething(Map m){
println m
}
printSomething(ordinary:58)
printSomething(extraOrdinary:67)
printSomething(ordinary:11,extraOrdinary:22)
this will output
[ordinary:58]
[extraOrdinary:67]
[ordinary:11, extraOrdinary:22]
I've been asked to include a link in an error message when the Email address for a registration is already in use.
The validation for this property is done with a IValidatableObject.Validate function on the model. My validate function looks like so...
Public Overridable Function Validate(validationContext As ValidationContext) As IEnumerable(Of ValidationResult) Implements IValidatableObject.Validate
Dim results = New List(Of ValidationResult)()
....
If Not EmailAvailable(Email) Then
results.Add(New ValidationResult("The email address is not available. Forgot Password?", {"Email"}))
End If
Return results
End Function
In my views, I'm using a custom "MyValidationSummary" extension function to format the errors nicely.
The extension function does this...
....
Dim ul = New TagBuilder("ul")
For Each key In helper.ViewData.ModelState.Keys
For Each e In helper.ViewData.ModelState(key).Errors
Dim li = New TagBuilder("li") With {
.InnerHtml = helper.Encode(e.ErrorMessage)
}
ul.InnerHtml += li.ToString()
Next
Next
container.InnerHtml += ul.ToString()
Return New MvcHtmlString(container.ToString())
I know I could just remove helper.Encode, and just output the message as raw html, but this feels a bit hacky.
I'm trying to find a nice way to be able to selectively include html in the messages, while still retaining the default behaviour of encoding plain text messages.
What I thought of doing, is create a custom ValidationResult class, which optionally would include a HTMLString property, so that I can, if I choose, include HTML in the messages.
I can do this, but I don't know if there is any way to get at this custom ValidationResult from MyValidationSummary.
update:
For the time being, I've just added a placeholder tag into the error message, which I then substitute with the actual link in my MyValidationSummary extension method. It's very hacky, but it will work until I've found a better way to do it.
I am trying to write a groovy script which loads the custom properties for a test suite using information from a properties file.
The properties file has around 6 different attributes
I have had a look at quite a few different methods i.e Loading from Properties test step and trying to expand the properties with groovy, but have not been successful.
If anyone could advise on how to achieve this, it would be much appreciated.
Thanks in advance.
Here is the groovy script which reads a property file and set them at test suite level:
def props = new Properties()
//replace the path with your file name below. use / instead of \ as path separator even on windows platform.
new File("/absolute/path/of/test.properties").withInputStream { s ->
props.load(s)
}
props.each {
context.testCase.testSuite.setPropertyValue(it.key, it.value)
}
The above script load test suite level for the current suite where the groovy script is present.
Unfortunately, in my case I want to have the properties in the same order as the input file, ie. sorted, and this methode does not work.
I wanted to load a 'Project properties' file containing sorted properties and each time I used this method it stored them unsorted.
I had to use a more straightforward method (see below). If anyone knows about a more elegant/practical way to do it, I'm interested
def filename = context.expand( '${#TestCase#filename}' )
def propertiesFile = new File(filename)
assert propertiesFile.exists(), "$filename does not exist"
project = testRunner.testCase.testSuite.project
//Remove properties
project.propertyNames.collect{project.removeProperty(it)}
//load the properties of external file
propertiesFile.eachLine {
line->
firstIndexOf = line.indexOf('=') // properties as set as key=value in the file
key = line.substring(0, firstIndexOf)
value = line.substring(firstIndexOf+1)
project.setPropertyValue(key, value)
}
What is the difference between the following Groovy/Gremlin snippets? (both saved as *.groovy files and run with ./gremlin.sh -e [filename].groovy)
class user
{
String username
static void main(String[] args)
{
user mtm = new user()
mtm.username = "MuffinTheMan"
println mtm.username
}
}
and
class User
{
String username
static void main(String[] args)
{
User mtm = new User()
mtm.username = "MuffinTheMan"
println mtm.username
}
}
The first gives 3 compilation errors similar to this one:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script1.groovy: 7: Apparent variable 'mtm' was found in a static scope but doesn't
refer to a local variable, static field or class. Possible causes:
You attempted to reference a variable in the binding or an instance variable from
a static context.
You misspelled a classname or statically imported field. Please check the spelling.
You attempted to use a method 'mtm' but left out brackets in a place not allowed
by the grammar.
# line 7, column 14.
user mtm = new user()
The second compiles and runs just fine and outputs:
MuffinTheMan
It turns out the only difference is that the class name in the first begins with a lower case letter, while the class name in the second begins with an uppercase letter. There's a bit of discussion here, but it's difficult to find a lot of good info on the issue. I decided to post this because I was beating my head against the wall (not literally) trying to figure out why my code (class name having its first letter in lowercase) wouldn't compile, and perhaps others may have this issue.
If anyone else has a better link to a more full/clear discussion on the issue, post it!
I would like to modify a label. I create it at the top:
JLabel curStatus;
and then in a method that starts up all of the gui...
curStatus = new JLabel("");
jfrm.add(curStatus);
then for the method that takes a string, and puts it as the status of the jlabel:
public void setCurStatus(String inCurStatus) {
curStatus.setText("hi!"); <<< ERROR ON THIS LINE...
curStatus.setVisible(true);
}
I get this error:
Exception in thread "main" java.lang.NullPointerException
from the code snippet, it is clear that jLabel is null when you set the text.
Obvious and only possible reason is : your GUI initialization code is not being executed before setting text. There cant be other reason at all.
You look again, and make sure that those initializations happen at the very first (call it in the top of constructor)
either remove the #param from the method or use
curStatus.setText(inCurStatus); // instead of curStatus.setText("Hi");
and pass "Hi" as an argument when you call the method.