How Can I Verify Text Amount in Katalon - katalon-studio

I'm trying to verify a text in Katalon and my script isn't working.
Here's my element:
<span id="overviewTabStoreCredit" class="h2 strong amountCredit text-danger">-$100.00</span>
Here's my script:
def StoreCreditAmount = '-$100.00'
TestObject StoreCreditTO = findTestObject('Baseline/Page_Side Menu/Page_Customers/Page_Customer Card/span_Verify Credit Limit')
WebUI.verifyElementAttributeValue(StoreCreditTO, 'text', StoreCreditAmount, GlobalVariable.G_Timeout_Tiny, FailureHandling.CONTINUE_ON_FAILURE)
When running the script, I get an error message, "Object does not have attribute 'text'"
I also tried this to character it by class instead of text:
def StoreCreditAmount = 'h2 strong amountCredit text-danger'
TestObject StoreCreditTO = findTestObject('Baseline/Page_Side Menu/Page_Customers/Page_Customer Card/span_Verify Credit Limit')
WebUI.verifyElementAttributeValue(StoreCreditTO, 'class', StoreCreditAmount, GlobalVariable.G_Timeout_Tiny, FailureHandling.CONTINUE_ON_FAILURE)
I got this error:
Has attribute 'class' with actual value 'text-success h2 strong amountCredit' instead of expected value 'h2 strong amountCredit text-danger' even though the value is correct.

'Text' might not be an attribute. You can getText() from the element and then compare with the expected result. Sometimes, the value you see might not from Text, but from the attribute 'value'.

When you look at your tag there is no "text" attribute:
<span id="overviewTabStoreCredit" class="h2 strong amountCredit text-danger">
Some elements (like text-boxes) have hidden "value" elements for input text, but that is not the case here.
I believe what you want to do is check that the text between your tags equals a certain amount, in this case: "-$100.00".
To check the text between your opening/closing tags for your element use
WebUI.getText(). So your code could grab the text between the tags of your element, and then do an assert (or do it in one step) to finish your validation. I'll show it in two for readability:
def testStoreCreditAmountText = '-$100.00'
TestObject storeCreditTO = findTestObject('Baseline/Page_Side Menu/Page_Customers/Page_Customer Card/span_Verify Credit Limit')
def actualStoreCreditAmountText = WebUI.getText(storeCreditTO)
WebUI.verifyMatch(testStoreCreditAmountText, actualStoreCreditAmountText, false)
I hope that helps!

Related

How to debug in TYPO3 if <f:debug> returns strings instead of object?

In a custom TYPO3 8.7.12 extbase extension I am unable to f:debug items in templates.
We are in the listAction controller and simply do:
$institutions = $this->institutionRepository->findAll();
$this->view->assignMultiple([
'institutions' => $institutions,
// ... pagination limit ...
]
);
And in the template:
<f:debug>
{institutions}
</f:debug>
This returns
sometimes the string 'Array' in the fluid debugger (can't reproduce now)
When the code is on 3 lines: #1273753083: Cannot cast object of type "TYPO3\CMS\Extbase\Persistence\Generic\QueryResult" to string.
Or also #1273753083: Cannot cast object of type "TYPO3\CMS\Extbase\Persistence\Generic\LazyObjectStorage" to string.
When the code is on 1 line: #1234386924: Cannot create empty instance of the class "TYPO3\CMS\Extbase\Persistence\ObjectStorage" because it does not implement the TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface.
If I loop through {institutions} with f:for and then f:debug:
<f:for each="{institutions}" as="institution" iteration="i">
<f:debug>
{institution}
</f:debug>
</f:for>
I get the first property of the object, e.g. the name.
EDIT: this is due to a __toString() magic method in the model. If I remove it, instead I get the namespace and uid STUBR\Extension\Domain\Model\Institution:55 – this looks again as if the object isn't rendered.
Wait... php.net says The __toString() method allows a class to decide how it will react when it is treated like a string. So could something be treating (typecasting?) the object as a string?
Working with the properties is normal, the issue just occurs when trying to print the whole object.
Where should I look? Lazy loading? There are some lazy loading properties, but not that many. Or maybe something is missing from the class? Or is there a workaround.
PS:
Unable to print_r or var_dump the query result, I get a memory limit error.
I saw https://wiki.typo3.org/Exception/CMS/1234386924 but initStorageObjects() is already called in the constructor
To answer the question;
<f:debug>{institutions}</f:debug>
will be parsed as an object, but any whitespace inside will make it parse as a string so.
The following methods do the same job as <f:debug> and work similarly in my case:
\TYPO3\CMS\Core\Utility\DebugUtility::debug(
$var = $variable,
$header = 'Institutions',
$group = ''
);
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump(
$variable,
$title = 'Institutions',
$maxDepth = 8,
$plainText = FALSE,
$ansiColors = TRUE,
$return = FALSE,
$blacklistedClassNames = NULL,
$blacklistedPropertyNames = NULL
);
execute in list or show action in controller.
It's less convenient than with f:debug (because you have to do the work in two different places, e.g. when you're in a loop in the template, you have to go to the controller and build that loop again), but it's a helpful workaround.
EDIT: I found it's sufficient to do
<f:debug>{var}</f:debug>
on one line

#helper.repeat in PlayFramework

I don't understand how to describe #helper.repeat in play2.2.1.
#helper.form(action = routes.Application.send) {
#helper.repeat(
field = form1("input"), min = 3
) {fld =>
#helper.inputText(
field = fld, '_label ->"input"
)
}
}
It is the part fld => #helper.inputText(field = fld) that I can't understand.
What does it mean?
I know Java, so I assume it is a functional writing, but in above code, where does the variable fld come from?
And why the tip of the arrow indicates #helper.inputText(field = fld)?
why is fld the value of field in #helper.inputText?
I have googled, but I couldn't find an enough explanation for a beginner.
I am not sure of Scala's grammar.
Please explain above code for a beginner?
Original Answer
This seems to be a bit overcomplicated. There is no need to assign values by hand. Usually you would write a repeater like this:
#helper.repeat(form1("input"), min = 3) { fld =>
#helper.inputText(fld, '_label ->"input")
}
In functional programming this is a so called higher-order function. You may know other scala built in higher-order functions like map, filter or foreach. #helper.repeat is very similar to foreach. form1("input") refers to a collection of values you want to display. min = 1 tells the repeater to show at least one field. Finally within { fld => ... } you iterate over all values defined in your collection.
In other words: { fld => ... } is just an anonymous function that takes a single Field parameter (fld) and displays a text input for that specific field.
Follow Up
Ok, I'm trying to follow up your questions from the comments. Let's start by the signature of helper.repeat. There is no magic involved here, it's just a regular Scala function:
helper.repeat(field: Field, min: Int)(fieldRenderer: (fld: Field) => Html): Seq[Html]
In Scala, functions can have multiple parameter lists. Here we have two. The first parameter list takes two parameters: field and min. The second parameter list takes a single function as parameter: fieldRenderer. fieldRenderer itself takes again a single parameter (fld) and returns Html.
The important thing is, you are not passing "data" but a function instead. To clear this up:
The signature fieldRenderer: (fld: Field) => Html
is equal to def fieldRenderer(fld: Field): Html
This means, you can do anything within this function, as long as it returns Html. That's exactly what happens in the example at the very top. You pass a Field and return Html. You do that by calling #helper.inputText.
Now repeat first gets a List[Field] from field you pass as first parameter. This list corresponds to the String List of your container class. Also repeat ensures there is at least one element in that list. This is, because you passed 1 as min. Then the function fieldRenderer is applied to all elements in our list.
A pseudo code implementation of repeat could look like this:
def repeat(field: Field, min: Int)(fieldRenderer: (fld: Field) => Html): Seq[Html] {
val list: List[Field] = field.getFields
var output: List[Html] = List()
for (i = 0; i < list.length; i++) {
val element: Field = list.get(i)
val html: Html = fieldRenderer(element)
output += html
}
return output
}

SelectField renders unicode syntax

When dynamically creating choices for SelectField in WTForms, I get (u'Choice',) rendered in the dropdown list.
I suspect its something to do with unicode, but no idea how to get the correct string.
for example
form.group_id_name.choices = [(row, row) for row in db.session.query(entry.group_id_name).distinct()]
In my forms I have
group_id_name = SelectField('group_id_name')
I would like it to render
<select id="group_id_name" name="group_id_name"><option value="Choice1">Choice1</option><option value="Choice2">Choice2</option></select>
Instead I get
<select id="group_id_name" name="group_id_name"><option value="(u'Choice1',)">(u'Choice1',)</option><option value="(u'Choice2',)">(u'Choice2',)</option></select>
It's not anything to do with Unicode.
query() returns a sequence of column values for each row. For a query with only one column in it you get a length-1-tuple.
When you implicitly convert a tuple to a string as part of the template you get the Python code representation of the tuple, which looks like (somevalue,).
You want to include the string value of the column itself in the template, so you should access the first element of the sequence, eg:
form.group_id_name.choices = [(row[0], row[0]) for row in db.session.query(entry.group_id_name).distinct()]
or using unpacking assignment:
form.group_id_name.choices = [(name, name) for (name,) in db.session.query(entry.group_id_name).distinct()]

Convert type of KnockOutJs.linkObservableToUrl mapped value to bool

I'm working on single page application, which involves sorting.
I use
viewModel = new {
SortAsc = ko.observable(true)
};
ko.linkObservableToUrl(viewModel.SortAsc, "Asc", viewModel.SortAsc());
to achieve that mapping. And it works, but the problem is that mapping returns literal strings "false" and "true" instead of bool value. This causes a problem with checkbox, which is bound to that property:
<input type="checkbox" data-bind="checked: SortAsc" value="Ascending"/>
The question is, how can I make that value from url to be converted to correct type (normal bool), so my checkbox will be updated properly?
Ok, I found how to overcome that problem. Not very elegant, but works.
1. I assumed, that SortAsc will be a string property in my logic. So I left it bound to url like in the question text. Only initialized it with string, istead of bool ("true" intead of true).
2. I created writeable dependend observable, which will do the convertion:
viewModel.SortAscBool = ko.dependentObservable({
read: function () {
return this.SortAsc() === "true";
},
write: function (value) {
this.SortAsc(String(value));
},
owner: viewModel
});
and bound my checkbox to that prop. So now, when checkbox is checked, SortAscBool is changed and it sets literal value to SortAsc (I think this convertion is really not needed, but as a C# programmer I like it that way :)). And of course, when SortAsc changes, SortAscBool will also change and return the converted value to checked binding. And that is what was really needed.
Also, my first though was to simply create one way dependend observable, but then url will not be updated with values from checkbox.

Display empty textbox using Html.TextBoxFor on a not-null property in an EF entity

I am using Entity Framework (v4) entities. I have an entity called Car with a Year property of type integer. The Year property does not allow NULL. I have the following in my Create view:
<%= Html.TextBoxFor(model => model.Year) %>
I am required to return a new Car object (due to other requirements) in my HttpGet Create action in the CarController.
Currently, a zero is displayed in the Year textbox because the Year property does not allow NULL. I would like to display an empty textbox in the Create view. How do I do this?
Use Html Attributes Overload. In razor it would be:
#Html.TextBoxFor(model => model.Year, new { Value = "" })
Try this instead:
Html.TextBox("Year", "")
If you are using the strongly typed TextAreaFor helper, then there is no direct way to set a default value. The point of the strongly typed helper is that it binds the text area to a model property and gets the value from there. If you want a default value, then putting in the model would achieve that. You can also just switch to the non-strongly typed TextArea helper. It gives you more a bit more flexibility for cases like this:
#{
var defaultValue= "";
}
#Html.TextArea("Model.Description", defaultValue, new { Value = "added text", #class = "form-control", #placeholder = "Write a description", #rows = 5 })
Try this is you are trying to append to your field or want to modify an existing field with an empty TextBoxFor.
Html.TextBoxFor(model => model.Year, Model.Year="")