Xcode 9.3 staticText element query limits 128 characters for UI testing - xcode-ui-testing

In Xcode 9.3, when I try to run UI test cases it started giving me below exception where ever it found lengthy messages exceeding 128 characters -
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid query - string
identifier "lengthy message more than 128 characters..." exceeds
maximum length of 128 characters. You can work around this limitation
by constructing a query with a custom NSPredicate that specifies the
property (label, title, value, placeholderValue, or identifier) to
match against.'
Workaround given is to use custom NSPredicate something like below,
let predicate = NSPredicate(format: "label BEGINSWITH 'Empty '")
let label = app.staticTexts.element(matching: predicate)
XCTAssert(label.exists)
But If we use predicate like above, we might not be able to assert the entire text message.Is there any other possible way where we can assert the entire text? Please let me know.
Thanks, Cheers:)

Why don't you use LIKE instead of BEGINSWITH. LIKE matches entire text.
let predicate = NSPredicate(format: "label LIKE 'Your lengthy text that you want to match...'")
let label = app.staticTexts.element(matching: predicate)
XCTAssert(label.exists)
EDIT: After reading OP's comment, I'm suggesting alternative approach:
If using Interface Builder, add accessibility identifier to your Label (or TextView). You can do it by selecting label that holds lengthy text and opening Identity inspector that is on the right side of Xcode. From there, find Accessibility area and add lengthyTextLabel to Identifier section.
If using ViewController to manipulate views, just write this:
lengthyLabel.accessibilityIdentifier = "lengthyTextLabel"
And in your tests, you can get your element by writing this:
let lengthyText = app.staticTexts.element(matching: .any, identifier: "lengthyTextLabel")
This way you can find your long text with: lengthyText.label.

Related

My flow fails for no reason: Invalid Template Language? This is what I do

Team,
Occasionally my flow fails and its enough test it manually to running again. However, I want to avoid that this error ocurrs again to stay in calm.
The error that appears is this:
Unable to process template language expressions in action 'Periodo' inputs at line '0' and column '0': 'The template language function 'split' expects its first parameter to be of type string. The provided value is of type 'Null'. Please see https://aka.ms/logicexpressions#split for usage details.'.
And it appears in 2 of the 4 variables that I create:
Client and Periodo
The variable Clientlooks this:
The same scenario to "Periodo".
The variables are build in the same way:
His formula:
trim(first(split(first(skip(split(outputs('Compos'),'client = '),1)),'indicator')))
His formula:
trim(first(split(first(skip(split(outputs('Compos'),'period = '),1)),'DATA_REPORT_DELIVERY')))
The same scenario to the 4 variables. 4 of them strings (numbers).
Also I attached email example where I extract the info:
CO NIV ICE REFRESCOS DE SOYA has finished successfully.CO NIV ICE REFRESCOS DE SOYA
User
binary.struggle#mail.com
Parameters
output = 7
country = 170
period = 202204012
DATA_REPORT_DELIVERY = NO
read_persistance = YES
write_persistance = YES
client = 18277
indicator_group = SALES
Could you give some help? I reach some attepmpts succeded but it fails for no apparent reason:
Thank you.
I'm not sure if you're interested but I'd do it a slightly different way. It's a little more verbose but it will work and it makes your expressions a lot simpler.
I've just taken two of your desired outputs and provided a solution for those, one being client and the other being country. You can apply the other two as need be given it's the same pattern.
If I take client for example, this is the concept.
Initialize Data
This is your string that you provided in your question.
Initialize Split Lines
This will split up your string for each new line. The expression for this step is ...
split(variables('Data'), '\n')
However, you can't just enter that expression into the editor, you need to do it and then edit in in code view and change it from \\n to \n.
Filter For 'client'
This will filter the array created from the split line step and find the item that contains the word client.
`contains(item(), 'client')`
On the other parallel branches, you'd change out the word to whatever you're searching for, e.g. country.
This should give us a single item array with a string.
Initialize 'client'
Finally, we want to extract the value on the right hand side of the equals sign. The expression for this is ...
trim(split(body('Filter_For_''client''')[0], '=')[1])
Again, just change out the body name for the other action in each case.
I need to put body('Filter_For_''client''')[0] and specify the first item in an array because the filter step returns an array. We're going to assume the length is always 1.
Result
You can see from all of that, you have the value as need be. Like I said, it's a little more verbose but (I think) easier to follow and troubleshoot if something goes wrong.

UFT/QTP - Extract Values From List Within WebEdit

I am attempting to capture all the list items in the WebList elements throughout the entire application, however, while below code works on the WebLists, it does not work on this WebEdit.
When you click on the WebEdit, a long list of values appear (similar to a WebList) and as you type for your value, the list becomes shorter. That is how the WebEdit was set up.
But now, how do I get the values in this list?
Here is the code I have for the WebLists:
Code
Set WebLink = Browser("browser").Page("page")
listval = WebLink.WebElement("xpath:= ((//*[contains(text(), 'Name')]))[1]/following::SELECT[1]").GetROProperty("all items")
listvalues = split(listval,";")
For j = LBound(listvalues,1) To UBound(listvalues,1)
'Print listvalues(j)
writeToTextFile(listvalues(j))
Next
ExitTest
The short answer is: it depends on the implementation.
The long one:
There is no universal widget for comboboxes (Like there is for edit fields or lists / selects, radiobuttons etc) => there is no universal solution but only guidelines.
You need to spy on those objects that appear in the combobox, see their XPath and / or other properties (the css classname they belong to, for example) and then execute a second query that selects all such items. Afterwards you have to extract the value of the selected elements; which might be as simple as getting the innertext Property or you may need to dig even deeper in the HTML hierarchies.
You would need to pay careful attention for synchronisation(Waiting until all search result elements appear), Filtering (using the XPath, Description Objects and ChildObjects method on your WebPage) and then extraction( getting the property /element that contains the actual value of that WebElement)
So again: These combobox solutions are not universal therefore without seeing their code the best what one can provide to you is universal guidelines which should work in most of the situations. (You would need some familiarity with Web Programming and the UFT Framework / Robot)

XC UITesting with Dynamic Labels

I'm trying to assert that the value of a label (which is populated dynamically) contains a substring as part of the result of a UITest.
My issue is that XCTAssert doesn't seem to allow for substrings or approximate matches (from what I can find anyway). Does anyone have any advice on how I might write the following to find a match for "hours ago" instead of the specific "xx hours ago"?
At present I'm only able to get this to work with exact matches (as below).
//Set up an expectation
let textToFind = app.staticTexts["13 hours ago"]
let exists = NSPredicate(format: "exists == true")
expectationForPredicate(exists, evaluatedWithObject: textToFind, handler: nil)
//Give the app time to get network data & Update UI
waitForExpectationsWithTimeout(5, handler: nil)
//Assert that we get results
XCTAssert(textToFind.exists)
Change the query that finds your UI element to do so by a method other than its name. The UI test recording feature in Xcode can help you work through this — see the WWDC2015 session introducing UI testing for an example of doing this.
Once you've found your UI element without using its name, your expectation test can use a predicate that tests the name for a substring.
Or:
Explicitly use a query to find app's subelement matching a predicate (see elementMatchingPredicate in XCUIElementQuery) rather than subscripting, then you can use your exists test to verify that it's there. Again, see the WWDC session for examples.

UITextField binding to a decimal. Can I automatically turn empty string to zero

I have a very standard binding set up in android on a UITextView
local:MvxBind="Text Quantity"
Where Quantity is an int property.
If I enter 123 say, that gets assigned and the setter is called. As I delete that text, 123 -> 12 -> 1 -> empty string, the setter is called for each number but not for the empty string infact the following exception occurs:
MvxBind:Error: 48.84 SetValue failed with exception - FormatException: Input string was not in the correct format
Is there a way of automatically converting the empty string value to 0 in the binding? Will I need a value converter for this? Is this in fact a bug?
Thanks in advance.
This area has been discussed recently in https://github.com/slodge/MvvmCross/issues/350 with some nullable additions in https://github.com/slodge/MvvmCross/issues/373 - people are welcome to contribute their opinions (and/or code) there.
The current 'status quo' is that MvvmCross will parse and represent valid decimal numbers. However, if the number isn't valid - eg if it's string.Empty or a set of non-numeric characters - then MvvmCross won't interpret these as zero (should "" be zero? should "asdf" be zero? should "123.456.7" be zero? should "1234asd" be zero? perhaps all of these should actually be NaN?).
If people need specific behaviour then it's easy for them to implement this behaviour - e.g. using a custom control (subclassed UITextField), using a value converter, using a custom binding (or overriding the default binding), using a string property on the viewModel, etc.
My personal opinion is that this topic really comes under the Validation heading. In general, MvvmCross doesn't provide many hooks for Validation at present. It's been proposed for a long time - https://github.com/slodge/MvvmCross/issues/133 - but no-one has shown much interest. There are some simple validation samples in the WithErrors demo within https://github.com/slodge/MvvmCross-Tutorials/tree/master/ApiExamples. Within the apps I've written we've generally written and sub-classed UI controls to help reduce the need for validation - and in general we've tried to avoid the need for as much text input as we can (users don't like seem to like using keypads on phones)

Query html tag with XPath

I am writing the selenium test.
I have a label there "Assign Designer" and the select box followed right after the label.
Unfortunetely, select box has the dynamic id and I can not query it by id or any other it's attribute.
Can I build the XPath query that returns "First select tag after text 'Assign Designer'"?
PS. Selenium supports only XPath 1.0
This would be something like:
//label[text() = 'Assign Designer']/following-sibling::select[1]
Note that:
The // shorthand is quite inefficient, because it causes a document-wide scan. If you can be more specific about the label's position, I recommend doing so. If the document is small, however, this won't be a problem.
Since I don't know much about Selenium, I used "label". If it is not a <label>, you should use the actual element name, of course. ;-)
be sure to include a position predicate ([1], in this case) whenever you use an axis like "following-sibling". It's easily forgotten and if it is, your expressions may produce unexpected results.

Resources