Enclose a list of tags (taghelper) by a parent tag - asp.net-core

I need to achieve like below
<MyTagList>
<MyTag></MyTag>
<MyTag></MyTag>
</MyTagList>
When ever I use MyTag in design time, it need to be enclosed automaticaly by MyTagList or MyTag should error that it must be enclosed by MyTagList

You can't do this today at design time. You can however do it partially at runtime by utilizing TagHelperContext.Items. By using the Items property you can ensure that each tag is enclosed by a parent tag and throw if it's not. Insert an indicator into the Items bag in your parent element and verify that it exists in child elements.
As for supporting this in the future there are two issues open to add design time support:
https://github.com/aspnet/Razor/issues/255
https://github.com/aspnet/Razor/issues/474
Hope this helps!

Related

Capybara: Find element by attribute containing something NOT

I am having the following issue in my Capybara environment:
I need to search for an element. This element contains an attribute, which is unique. The attribute is changed asynchronously.
I need the content of this attribute, but when I just search for the attribute I am getting a nil.
I could wait until the attribute has the property, but since this is Capybaras job, I thought there might be a possible selector, which can search for something like:
find('button[uniqueattribute] != nil')
Any ideas how to do this?
Thanks already!
If the attribute is being added to the button element (didn't have the attribute originally) then you can just do
find('button[attribute_name]')
which will wait (up to Capybara.max_default_wait_time seconds for a button element with that attribute to be on the page - https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors. To wait and then get the contents/value of that attribute you could do
find('button[attribute_name]')['attribute_name']
If you just want to wait until the attribute is either not there or not blank then you can do
find('button:not([attribute_name=""])')
If you need to ensure the attribute is there, but isn't blank it would be
find('button[attribute_name]:not([attribute_name=""])')
I found a possible solution:
You can check the length of an element by Xpath (which is awesome) with string-length.
So in my case the solution was:
find(:xpath, ".//button[#unique_attribute_name[string-length() != 0]]")
Now Capybara waits until the attribute has a value. If there are more pretty solutions, just tell me.

How to Identify Elements in Salesforce Lightning for Selenium

I am trying to automate Salesforce lightning using Selenium, but getting issues with identifying elements. Reason, its having dynamic IDs , and other attributes are either very long , or they are not unique.
For eg ,
<a id="170:1968;a" class="textUnderline outputLookupLink slds-truncate forceOutputLookup"
data-refid="recordId"
data-recordid="0059E000001aOCSQA2"
data-special-link="true"
href="#/sObject/0059E000001aOCSQA2/view"
target="_blank" rel="noreferrer"
title="" data-aura-rendered-by="170:1968;a" data-aura-class="forceOutputLookup"/>
In above code , ID is dynamic , Class is not unique, and all the Lookup elements are associated with it. Also the absolute path is not much trusted , and hence I am trying to find any concrete option to handle these elements. Any help will be highly appreciated.
Here, you could try using the contains method if at least a part of the id attribute value is static.
From your code, you could try
//a[contains(#id,"a")]/ //--extended xpath--
From the given html code, the 'a' in the id attribute of the a tag looks static, while the rest changes.
You can ask the developers to provide an id to the lightning component using aura:id
Then the dynamic id won't be generated.
You can try with field labels and fetch its parent node(s), and then fetching childs or brother nodes to locate related texts/text boxes etc.
Eg. You are in Account Edit/New page, and you want to fill in a value to the text box for Account Name field. So you can firstly try with //*[text()='Account Name']/parent::* to find an element that covers BOTH the field label and the text box.
And then you can check if the text box is a 'brother' or a 'child'. If it's a 'child' then try with //*[text()='Account Name']/parent::*(/parent::*)//*[attributes for the text box];
If it's 'brothers' then try with //*[text()='Account Name']/parent::*(/parent::*)/following-sibling::*[attributes for the text box]
You can use this logic to locate all type of fields in all standard lightning pages.

The method getKids() is undefined for the type PDField

https://issues.apache.org/jira/browse/PDFBOX-2148
When there are multiple copies with the same field name, the getFullyQualifiedName for each kid in the list of PDField objects returns the name of the parent, followed by .null. So if the parent field is called Button2 and it has 4 instances the result of printing out all the names will be:
Button2.null
Button2.null
Button2.null
Button2.null
According to the comments to the question, the OP refers to PDFBox 2.0.x versions, in particular 2.0.6.
getKids()
The method getKids() is undefined for the type PDField
In PDFBox 2.0.6 there are two immediate sub-classes of PDField. Different variants of the former (1.8.x) getKids() method are implemented in there:
PDNonTerminalField - the method retrieving the kids in this class is getChildren() and returns a List<PDField>, a list of form fields.
PDTerminalField - the method retrieving the kids in this class is getWidgets and returns a List<PDAnnotationWidget>, a list of widget annotations.
name of the parent, followed by .null
When there are multiple copies with the same field name, the getFullyQualifiedName for each kid in the list of PDField objects returns the name of the parent, followed by .null
This is not the case in PDFBox 2.0.x.
In the sample document attached to the PDFBox issue PDFBOX-2148 PDFBox now correctly finds only a single field which appropriately is named "Button2". This field is a PDTerminalField and has 4 widget annotations. The class of the latter, PDAnnotationWidget, has no getFullyQualifiedName method, so there are no ".null" names.
Thus, this problem is gone.
FQN of duplicate fields
(from the OP's comment responding to "What exactly is your question?")
how to get Fully Qualified Name of duplicate fields in pdfbox
There are no duplicate fields in (valid) PDFs, for a given name there is at most a single field which may have multiple widgets. Widgets do not have individual FQNs.
Thus, what you call "duplicate fields" in your example document actually is a single field with multiple widgets; the name of that field is "Button2" and can be retrieved using getFullyQualifiedName().
which page which form field
(from the OP's comments to this answer)
but how to get current page no in pdfbox.. for example there are 3 page and in page 2 there is a form field so how can i get which page which form field ?
All PDAnnotation classes, among them PDAnnotationWidget, have a getPage() method returning a PDPage instance.
BUT: As specified in ISO 32000-1, annotations (in particular form field widgets) are not required to have a link to the page on which they are drawn (except for screen annotations associated with rendition actions).
Thus, the above mentioned method getPage() may return null (probably more often than not).
So to determine the respective pages of your widgets, you have to approach the problem the other way around: Iterate over all pages and look for the annotation widgets in the respective annotation array.
For PDFBox 1.8.x you can find example code in this stackoverflow answer. With the information given in the previous parts of this answer it should be easy to port the code to PDFBox 2.0.x.
checkbox and radio button
(also from the OP's comments to this answer)
one more issue if i am using checkbox and radio button both then field.getFieldType() output is Btn for both. how to identify it?
You can identify them by inspecting the field flags which you retrieve via fields.getFieldFlags():
If the Pushbutton flag is set (PDButton.FLAG_PUSHBUTTON), the field is a regular push button.
Otherwise, if the Radio flag is set (FLAG_RADIO), the field is a radio button.
Otherwise, the field is a check box.
Alternatively you can check the class of the field object which for Btn may be PDPushButton, PDRadioButton, or PDCheckBox.
Beware: If a check box field has multiple widgets with differently named on states, this check box field and its widgets act like a radio button group! And not only in theory, I've seen PDFs with such check box fields in the wild.
To really be sure concerning the behavior of the fields, you therefore also should compare the names of the on states of all the widgets of a given check box.

How do I set value of DateTextBox?

So basically I have these two DateTextBoxes and I want to copy the value from one to another? Sounds easy, right? Still, it is not...
I tried to do it this way:
dojo.byId("datetextbox1").value = dojo.byId("datetextbox2").value;
it actually looks like the value changes as the content of the field changes, but it doesn't really. When I inspect the element with firefox it still contains the old value in the code and when I try to submit the form, the old value is sent!
So my question is: how should I change that damn value?
You'll want to set the value on the widget and not directly on the node.
dijit.byId("datetextbox1").set('value', dijit.byId("datetextbox2").get('value'));
dijit.byId grabs widgets, dojo.byId grabs dom nodes

Selenium RC Having problems with XPath for a table

I'm trying to select an element given by:
/html/body[#id='someid']/form[#id='formid']/div[#id='someid2']/div[#id='']/div[#id='']/div[#id='']/table/tbody[#id='tableid']/tr[7]/td[2]
Now the html of that row I'm trying to select looks like this:
<tr>
<td class="someClass">some text</td>
<td class="someClass2">my required text for verifying</td>
</tr>
I need to check whether my required text for verifying exists in the page.
I used selenium.isTextPresent("my required text for verifying"); and it doesnt work
So now I tried with selenium.isElementPresent("//td[contains(text(),'my required text for verifying')]")
This works sometimes but occassionally gives random failures.
Tried with selenium.isElementPresent(//*[contains(text(),'my required text for verifying')]) too..
How do I verify this text on the page using selenium?
The problem is not with the page taking time to load. I took screenshots before the failure occurs and found that the page was fully loaded so that shouldnt be the problem.
Could someone please suggest any way to select this element or any way to validate this text on the screen?
Try locating it by CSS:
assertText(selenium.getText("css=.someClass2"), "my required text for verifying");
The above should give a better failure message than isElementPresent, but you can still use that with CSS locators:
assertTrue(selenium.isElementPresent("css=.someClass2"));
If there is an issue with the load times you could try waiting for the element to be present:
selenium.waitForCondition("var value = selenium.isElementPresent('css=.someClass2'); value == true", "60000");
Some other XPath locators that might work for you, if you prefer not to use CSS locators:
//td[contains(#class, 'someClass2')
xpath=id('tableid')/tr[7]/td[2]
xpath=id('tableid')/descendant::td[contains(#class, 'someClass2')][7]
I've never heard of selenium; but your initial XPath is unnecessarily fragile and verbose.
If an element has an id, it's unique; using such a long XPath just to select a particular element is unnecessary; just select the last element with the id. Further, I see that you're occasionally selecting xyz[#id=''] - if you're trying to select elements without id attributes, you can do `xyz[not(#id)] instead.
Assuming your initial XPath is basically correct, it would suffice to do something like this:
//tbody[#id='tableid']/tr[7]/td[2]
However, using a specific row and column number like that is asking for trouble if ever anyhow changes details of the html. Also, it's atypical to have id's on tbody elements, perhaps the table element has the id?
Finally, you may be running into space-normalization issues. In xml, multiple consecutive spaces are often considered equivalent to a single space, and you're not accounting for that. In particular, if the xhtml is pretty-printed and contains a line-break in the middle of your sought-after text, it won't work.
//td[contains(normalize-space(text()),'my required text for verifying')]
Finally, text() explicitly selects
child text nodes - so the above xpath won't select elements where the text isn't the immediate child of td (e.g. <td><b>my required text for verifying</b></td>) won't match. Perhaps you mean to look up the concatenated text vale of all descendents:
//td[contains(normalize-space(string(.)),'my required text for verifying')]
Finally, type conversion can be implicit in XPath, so string(.) can be replaced by . in the above, leading to the version:
//td[contains(normalize-space(.),'my required text for verifying')]
This may be slow on large documents since it needs to normalize the spaces and perform a string search for each td element. If you run into perf problems, try to be more specific about which td elements need to be inspected, or, if you don't care where the text occurs, try to reduce the number of "calls" to normalize-space by normalizing the entire doc in one go (e.g. via /*[contains(normalize-space(.),'my required text for verifying')]).