Visual Studio Coded UI: Select HTML Element by CSS Selector - coded-ui-tests

I have run into a problem selecting an item within Microsoft's CodedUI framework. I have a page full of items that can be added/removed via selecting a checkbox. The checkboxes do not have unique id on them, and I am having trouble selecting other than the first item when looking for a particular Tag/class combination. Is there some trick to doing this that isn't immediately obvious.

There are a couple different options here:
1. You could select the object by selecting the item related to it
<div id="parent">
<label id="checkbox1234">MyCheckBox</label>
<input checked="false"></input>
</div>
... could be selected as:
HtmlDiv parent = new HtmlDiv(browserWindow);
parent.SearchProperties["innerText"] = "MyCheckBox";
HtmlCheckBox target = new HtmlCheckbox(parent);
target.SearchProperties["TagName"] = "INPUT";
return target;
or
HtmlLabel sibling = new HtmlLabel(browserWindow);
sibling.SearchProperties["id"] = "checkbox1234";
UITestControlCollection col = sibling.GetParent().GetChildren();
foreach (UITestControl control in col)
{
if (control.ControlType.ToString().Equals("HtmlCheckBox"))
{
return (HtmlCheckBox)control;
}
}
You can use these test utilities created by Gautam Goenka. They worked wonders for me as far as identifying the content of an object and using it for assertions. Still, if you don't have any meaningful way of identifying the objects based on content, this won't help you either. When all else fails, add some useful identifying properties to the HTML.

Related

How to display search box in all the frontend page sidebar typo3

We have developed a site with typo3 v8.7.11. We want to display the search box in the sidebar section, for this we installed the indexed_search extension. B
How to display a search box in all the frontend page sidebar section?
Edit:
The search and form action of the SearchController are both non-cacheable. This means that you would place a non-cacheable plugin on each of your pages, if you used my old answer. This harms performance and could have other side-effects.
Nowadays I usually simply include a search form on each of my pages by including this in my Fluid Template:
<form action="{f:uri.action(controller: 'Search', action: 'search', extensionName: 'indexedsearch', pluginName: 'Pi2', pageUid: searchPid)}" method="POST" role="search">
<input type="text" name="tx_indexedsearch_pi2[search][sword]" spellcheck="false" autocomplete="off" />
<button type="submit">Search</button>
</form>
I hand over the searchPid variable via TypoScript like this:
page.10.variables.searchPid = TEXT
page.10.variables.searchPid.value = <Pid where search results should be displayed>
Old answer:
My tip would be to create a TypoScript object that actually includes the plugin, like this:
lib.headerSearch = USER
lib.headerSearch {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = IndexedSearch
pluginName = Pi2
vendorName = TYPO3\CMS
switchableControllerActions {
Search {
1 = form
2 = search
}
}
features {
requireCHashArgumentForActionArguments = 0
}
view < plugin.tx_indexedsearch.view
view.partialRootPaths.10 = Path/To/Partial/
view.templateRootPaths.10 = Path/To/Template/
settings =< plugin.tx_indexedsearch.settings
}
Then, in your template, include it like this
<f:cObject typoscriptObjectPath="lib.headerSearch" />
Note that you should create a new "Search.html" Template in Path/To/Template/Search/ for this TS-Plugin, so that it does not interfere with the regular plugin. Also, be careful if you include the search slot on the same page as the search Plugin itself.
you have multiple options:
copy the HTML of the form from the search plugin in the normal content and insert it in your page-(html-)template.
create a special BE-column, insert the search-plugin into this column and render this column inherited in all pages
make a special page not visible in FE, where you insert the search-plugin and include this special CE in the rendering of every page (use a CONTENT object in typoscript to select that special CE)
include and configure the plugin in typoscript. (see answer of Thomas Löffler)
I prefer option 2 as it is most flexible and does not need any special page or content IDs, which might change with time (option 3). It also can handle any kind of CE.
Option 1 needs manual fixing if there are changes in the plugin rendering after an update for example.
Option 4 is not possible for each plugin or CEs at all to inherit. If you can configure the plugin with typoscript it is a fine option because you do not need any record (from tt_content)
for option 2:
temp.inheritedContent = CONTENT
temp.inheritedContent {
table = tt_content
select.orderBy = sorting
// -- use your own column id: --
select.where = colPos = 100
select.languageField = sys_language_uid
slide = -1
}
Use a TYPO3 extension, which can be a copy (fork) of the newly developed version of macina_searchbox
Template Module: Add "Macina Searchbox" under "include static from extensions" .
Use this or a similar TypoScript to include it, where '6' in this example is the search page. Use your own page id instead.
Constants:
lib.macina_searchbox {
pidSearchpage = 6
}
Setup:
10 = TEMPLATE
10.template = FILE
10.template.file = fileadmin/template/template.html
10.workOnSubpart = DOKUMENT
10.marks {
SUCHE < lib.macina_searchbox
LOGO = TEXT
LOGO.value = <img src="fileadmin/template/img/logo.png">
NAVI= HMENU
NAVI {
Then you can edit the Fluid template files in the folders below macina_searchbox/Resources/Private/ to modify the output of the searchbox. This method is necessary in order that the search result list will not be shown on the page. You must instead insert an Indexed Search plugin on your search page, which has id=6 in this example. SUCHE is the marker in the main template of the website. Use your own marker.
The easiest way is to copy the given plugin from indexed_search to a variable you use in your template.
When you e.g. use FLUIDTEMPLATE:
page.10 = FLUIDTEMPLATE
page.10.variable.searchBox < plugin.tx_indexedsearch
After that you can assign a separate template and make other modifications by changing page.10.variable.searchBox with the possible configuration here: https://docs.typo3.org/typo3cms/extensions/indexed_search/8.7/Configuration/Index.html

Select UI Element by filtering properties in coded ui

I have a web application. And I am using coded ui to write automated tests to test the application.
I have a dropdown with a text box. Which on entering values in the textbox, the values in the dropdown gets filtered based on the text entered.
If I type inside textbox like 'Admin', I will get below options like this:
And I need to capture the two options displayed.
But using IE Developer tool (F12), I am not able to capture the filtered options, because the options that are displayed do not have any unique property (like this below). And the options that are NOT displayed have a class="hidden" property
Any way to capture the elements that are displayed by applying some kind of filter like 'Select ui elements whose class != hidden'
Thanks in advance!!
HI please try below code will it works for you or not.By traversing all those controls that have class ="hidden"
WpfWindow mainWindow = new WpfWindow();
mainWindow.SearchProperties.Add(HtmlControl.PropertyNames.ClassName, "hidden");
UITestControlCollection collection = mainWindow.FindMatchingControls();
foreach (UITestControl links in collection)
{
HtmlHyperlink mylink = (HtmlHyperlink)links;
Console.WriteLine(mylink.InnerText);
}
I'm not sure there is a way to do it by search properties, but there are other approaches.
One way would be to brute force difference the collections. Find all the list items, then find the hidden ones and do a difference.
HtmlControl listControl = /* find the UL somehow */
HtmlControl listItemsSearch = new HtmlControl(listControl);
listItemsSearch.SearchProperties.Add(HtmlControl.PropertyNames.TagName, "li");
HtmlControl hiddenListItemsSearch = new HtmlControl(listControl);
hiddenListItemsSearch.SearchProperties.Add(HtmlControl.PropertyNames.TagName, "li");
hiddenListItemsSearch.SearchProperties.Add(HtmlControl.PropertyNames.ClassName, "hidden");
var listItems = listItemsSearch.FindMatchingControls().Except(hiddenListItemsSearch.FindMatchingControls());
You will only be able to iterate this collection one time so if you need to iterate multiple times, create a function that returns this search.
var listItemsFunc = () => listItemsSearch.FindMatchingControls().Except(hiddenListItemsSearch.FindMatchingControls());
foreach(var listItem in listItemsFunc()){
// iterate 1
}
foreach(var listItem in listItemsFunc()){
// iterate 2
}
The other way I would consider doing it would be to filter based on the controls which have a clickable point and take up space on the screen (ie, not hidden).
listItemsSearch.FindMatchingControls().Where(x => {
try { x.GetClickablePoint(); return x.Width > 0 && x.Height > 0; } catch { return false; }
});

Highlight Duplicate list item in SharePoint 2013

I have a SharePoint 2013 (The Cloud version) custom list where 1 column is a text field where contact numbers are keyed in.
How can I get SharePoint to highlight duplicate values in that column so that every time a new item is added to the list, I'll know if the contact number has been used previously?
Ideally, here's what I'd get if I were to enter 816's details for the 2nd time:
CNO....Name.......Issue
816.....Blink........Login Problem (highlighted in red)
907.....Sink.........Access Denied
204.....Mink.........Flickering Screen
816.....Blink........Blank Screen (highlighted in red)
I've been struggling with this for awhile and would be very grateful for any advice. Thanks!
Since SharePoint 2013 uses Client Side Rendering (CSR) as a default rendering mode I would recommend the following approach. Basically the idea is to customize List View on the client side as demonstrated below.
Assume the Requests list that contains RequestNo column.
The following JavaScript template is intended for highlighting the rows when list item with RequestNo column occurs more then once:
SPClientTemplates.TemplateManager.RegisterTemplateOverrides({
OnPostRender: function(ctx) {
var rows = ctx.ListData.Row;
var counts = getItemCount(rows,'RequestNo'); //get items count
for (var i=0;i<rows.length;i++)
{
var count = counts[rows[i]["RequestNo"]];
if (count > 1)
{
var rowElementId = GenerateIIDForListItem(ctx, rows[i]);
var tr = document.getElementById(rowElementId);
tr.style.backgroundColor = "#ada";
}
}
}
});
function getItemCount(items,propertyName)
{
var result = {};
for(var i = 0; i< items.length; i++) {
var groupKey = items[i][propertyName];
result[groupKey] = result[groupKey] ? result[groupKey] + 1 : 1;
}
return result;
}
How to apply the changes
Option 1:
Below is demonstrated probably one of easiest way how to apply those changes:
Open the page in Edit mode
Add Content Editor or Script Editor web part on the page
Insert the specified JavaScript template by enclosing it using
script tag into web part
Option 2:
Save the specified JavaScript template as a file (let's name it duplicatehighlight.js) and upload it into Site Assets library
Open the page in Edit mode and find JSLink property in List View web part
Specify the value: ~sitecollection/SiteAssets/duplicatehighlight.js and save the changes.
Result
SharePoint has some basic conditional formatting for Data View Web Parts and XSLT List Views, but the conditions you can use are rather limited. You can compare a field in the current item with a value that you specify. There are no formulas to count the number of items with the same name or similar, which would be the approach to use to identify duplicates.
If you need to identify duplicates, you may want to create a view that groups by the CNO number. Grouping will also include an item count, so you can run down the list and spot groups with more than one item.

Alloy user interface (access a tag value)

I'm working with liferay portal 6.2. And I want to get the value of the text in a tag with alloy user interface.
exemple:
<div>
<p> Paragraph </p>
"value"
</div>
the desired result is: value
please help.
AlloyUI, being an extension of YUI3, uses get/set methods to access and manipulate the properties/attributes of the object (YUI3 Node / AlloyUI Node) that is returned when looking up elements from the page.
Some examples can be reviewed in this documentation as well as this documentation.
In general you'll need something unique (i.e. id, css class) to the div in order to fetch only that element. Once you have that element, divNode.get('text') will give you all of the text within the element. There is not a means to easily "skip" the paragraph contents within the div without the value being contained within some other markup. If you have control over the markup and can do this, that would be the best option. Otherwise you are left to using the replace function to strip out the paragraph contents from the text.
<script>
AUI().use('aui-base', function(A) {
var paragraphText = A.one('#myDiv>p').get('text');
var divText = A.one('#myDiv').get('text')
var onlyValue = divText.replace(paragraphText, "").trim()
console.log(onlyValue)
})
</script>

How can I know an object is not visible when any of parent object is not visible in an HTML page using java script?

Let say I have an text box in an HTML page as follows.
<DIV style = "display:none;">
<DIV style = "display:inline;">
<INPUT type = "text" style = "display:inline;">
</DIV>
</DIV>
In this case, the text box will not be visible to the user. How can I identify that text is not currently visible to the user.
Dont say that, I should travel up to the parent objects to find out if they are set to not visible. I have bunch of fields to be validated like this and this would reduce the application performance.
Is there any other way to find out as this object is not visible to the user?
Thanks in advance.
If you don't need it to be pure JavaScript I would suggest using jQuery. Using the :visible or :hidden selector will accomplish what you want:
if ( $('yourElement').is(":hidden") ) {
// The element is not visible
}
http://api.jquery.com/visible-selector/
http://api.jquery.com/hidden-selector/
If you need pure JavaScript and you don't want to travel up through every ancestor element, you could try checking the element's offsetWidth and offsetHeight. If the element is hidden because of an ancestor element, they should both be 0. Note: I've always used jQuery for this, so I don't know how reliable this is.
var yourElement = document.getElementById('yourElementsId');
if ( yourElement.offsetWidth == 0 && yourElement.offsetHeight == 0) {
// The element is not visible
}
https://developer.mozilla.org/en-US/docs/DOM/element.offsetWidth
https://developer.mozilla.org/en-US/docs/DOM/element.offsetHeight

Resources