iMacros Tag Line properties - vba

I'm trying to create a macro to log in to a company owned web page. When I record putting the cursor into the User Name text box, the following command is recorded:
TAG POS=1 TYPE=INPUT:TEXT FORM=ACTION:/pdp/qnyfy/resumeSAML50/pdp/startSSO.ping
The problem is that the "qnyfy" part of the tag line changes. The next time I try to record this tag line, every thing is the same except that "qnyfy" changes to something else; which renders my VBA code useless for logging into this web page.
Is there a way to extract this information first, find out what that 5 characters should be and then re-build a string to use the correct tag line?
Windows 7
Excel 2016
iMacros 10.3
Thanks for the help........

OK, #OP opened some parallel Thread on the iMacros Forum (iMacros Tag Line Properties), which allows me to simplify a bit this Answer and to remove a few of the original IF-IF-IF...
(The parallel Thread contains a bit more (Background) Info and more precise Sols/Scripts applied to this specific Script, for those interested...)
First, FCI (Full Config Info) was originally not completely clear, now it is:
=> iMB v10.3, 'Scripting Interface' v10.3, Win7.
("iMacros v10.3" could have meant 'v10.3 for CR 'Free'/'PE'' also...)
(The 'TAG' Statement is truncated is this Thread, it is complete + complete Script in the parallel Thread...)
Several Solutions, I'll go from "simplest" to "more complex":
1- The 'FORM' Parameter can probably simply completely be removed. It is usually not needed, unless there are several Forms on the Page with similar HTML Elements, here the 'INPUT' Field.
2- Same like '1', but using for example the 'CLASS' Attribute or any Attr(s) that might identify this 'INPUT' Field uniquely if there are several Forms on the Page with similar (but not identical) 'INPUT' Fields. (Or by adjusting the 'POS=n' if they are identical...)
3- Same like '1' or '2', but combined with 'Relative Positioning', on some HTML Element that can be identified "easily" and uniquely to be used as the Anchor, either inside ('3a') the same 'FORM' or 'DIV' (=> this 'INPUT' probably has some 'Label' next to it like some "Login:" for example), or just outside ('3b') if that Form has some Name/Title for that "Section", usually in 'H2' or 'H3' Type.
4- Simply replace the dynamic part ("qnyfy") with a Wildcard:
TAG POS=1 TYPE=INPUT:TEXT FORM=ACTION:/pdp/*/resumeSAML50/pdp/startSSO.ping
Sols [1-4] probably provide a "Shortcut" to probably achieve the desired Result, but they actually don't really answer #OP's Qt which was "How to identify/extract/isolate this "qnyfy" 5 Letter String...?"
5- Using first one of [1-4] Methods, manage to tag some Element that will be inside that 'FORM', either the 'INPUT' Field itself or one Element that could be used as Anchor in '3a' (with Anchor Inside the Form), and then use 'Double Relative Positioning' (more Info on the iMacros Forum where I've several times already completely explained the Principle) to identify and tag and extract (=HTM) the complete 'Containing 'DIV'' (or could be 'SPAN', but there will very probably be some (outer) 'DIV' also) containing the 'FORM' to then isolate the "qnyfy" part using 'EVAL', stg like...:
SET !EXTRACT_TEST_POPUP NO
TAG POS=1 TYPE=INPUT:TEXT FORM=ACTION:/pdp/*/resumeSAML50/pdp/startSSO.ping ATTR=CLASS:* EXTRACT=TXT
TAG POS=R-1 TYPE=DIV ATTR=TXT:* EXTRACT=TXT
SET !EXTRACT NULL
TAG POS=R1 TYPE=DIV ATTR=TXT:*&&CLASS:* EXTRACT=HTM
SET Form_ID EVAL("var s='{{!EXTRACT}}'; var x,y,z; x=s.split('ACTION:/pdp/'); y=x[1].split('/'); z=y[0]; z;")
PROMPT EXTRACT:<BR><BR>{{!EXTRACT}}<BR><BR>Form_ID:<SP>_{{Form_ID}}_
6- This one actually comes between '4' and '5', it would be by using '3b' to first locate some Anchor outside the 'FORM' and its 'Containing 'DIV'', then only one Level of 'Relative Positioning' would be needed... (And the 'EVAL()' Statement remains the same...)
That's it...! It would help / add some "Reliability" if for example the Class of the Containing 'DIV' can be identified/added.
Not relevant for iMB v10.3 anymore:
And if "iMacros v10.3" meant "iMacros for CR v10.3 'Free'", you'll need to use ['!VAR1'-'!VAR3'] instead of 'Form_ID' as User Defined Vars are not supported in the 'Free' Version...
[All Solutions/Scripts not tested of course...! Hum, I had previously mentioned that I could directly think of 3 or 4 Solutions, here are already 6, ah-ah...!, and there are also different possible Variants on all 6 of them...]
7- In the parallel Thread on the iMacros Forum, I also mentioned and explained about a Sol_7 using the 'EVENT' Mode with or without ID, which wouldn't be of use for this User as the 'EVENT' Mode was not supported in iMB v10.3.
Rmk:
Sol_5 and Sol_6 can actually be used to deal with Dynamic ID's, same Principle...!
>
I might one day have to delete this Answer as I am currently (re)using each time my last 5/5 'Answer_Credit', I each time have to delete some previous Answer, to be able to post a 5th one, as most Users on the 'iMacros' Tag-Channel usually never follow up on their Threads and don't do "+1" or "Accept Solution"..., and all my previous Answers also usually all get downvoted anyway by some "angry" User(s), so I never manage to pass the Threshold for more than 5 Answers, ah-ah...!, tja...!
(No big deal probably as I actually never or very-very rarely answer Threads on SOF as I don't like the Rep-Pts System, I only answered this one because #OP is a "nice User" that I knew from the iMacros Forum, ah-ah...!)
(I still don't know what the 'community wiki' CB means below posting an Answer...?)

Related

Apex, Dynamic action, Confirm action, not picking up correct text - what am I missing?

I'm obviously missing something and hoping someone might be able to help.
I've an Interactive Grid, and a button.
When the button is pressed the dynamic action on the button has 2 steps.
Action 1 - Execute Javascript to take a value from one of the IG cells and put it into a page item.
Action 2 - Confirm Action - Are you sure you wish to delete &P10_JOB_ID.
I've made the page item, &P10_JOB_ID, visible and I can see the value has correctly been changed to the value from the IG.
I write P10_JOB_ID into a database table - I get the correct value
But the confirm message isn't picking up the correct value from P10_JOB_ID.
Namely it uses the value in P10_JOB_ID when the page starts, but then as I move around the IG pressing the button and changing the value of P10_JOB_ID, the text in the confirm message never changes.
Can anyone suggest what I might have missed, I'm baffled.
Thanks a lot
Substitutions like &P10_JOB_ID. are made when the page is rendered, not dynamically, so reflect the value at time of page load.
You will need to use Javascript to perform the conform action, something like:
apex.page.confirm ('Are you sure you wish to delete ' + $v('P10_JOB_ID') + '?', 'DELETE');
$v is an APEX Javascript function that returns the current value of a page item.
I used 'DELETE' as an example of a request value; you may want to do something different here.
Ok - having the setting of value and confirm as 2 separate actions is what causes the problem.
As per fac586
That is the expected behaviour. Static text substitutions are performed once during page show processing. They are not evaluated dynamically in the browser at runtime as values change.
Drop the second action and extend the first to display the confirm dialog using the apex.message.confirm JS API method, accessing the item value using the $v shorthand method.

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.

Capybara, selecting 1st option from dropdown?

I've done a search and most of the related google results have returned just in general selecting an element from a dropdown. However the ID's in this case for the elements in the dropdown are dynamically generated unfortunately.
This is for a base test case, so I basically just need to select for example the first one. The text is also the same for the elements in the dropdown (not sure if that helps).
Is there such an example of this?
Im using cucumber with caybara(using selenium driver) integration
You can find the first option element and then use the select_option method to select it.
For example, if the select list has an id "select_id", you can do:
first('#select_id option').select_option
As #TomWalpole mentions, this will not wait for the element to appear. It would be safer to do one of the following:
first('#select_id option', minimum: 1).select_option
or
find('#select_id option:first-of-type').select_option
Alternatively you can get the first element text then select it by select function:
first_element = find("#id_of_dropdown > option:nth-child(1)").text
select(first_element, :from => "id_of_dropdown")
After two days of searching and reading, this article was amongst one of a few that was helpful. Hopefully, this can help someone else!
I created a few methods like so, excuse the naming..I changed it.
def some_dropdown(id, text)
dropdown = find(id).click
dropdown.first('option', text: text).select_option
end
def select_form
within 'content#id' do
some_dropdown('#id', text)
click_link_or_button 'Submit'
end
end
I also referenced this.
I've tried to select an option from a modal dropdown. After trying all listed methods, and many other from other threads - I totally gave up and instead of using clicks or select_option just used keyboard keys
find(:select, "funding").send_keys :enter, :down, :enter
In case it still complains - try:
find(:select, "funding", visible: false).send_keys :enter, :down, :enter
Worked like a charm, selecting first option from a dropdown.

What is an HTMLSelectElement and an HTMLInputElement?

I'm attempting to learn VBA by reading through someone's code and understanding what happens every step of the way. However, I'm confused at to what these two elements are:
What is a HTMLSelectElement?
What is a HTMLInputElement?
See the W3C HTML Specs:
HTMLSelectElement
HTMLInputElement
I assume they correspond to select and input HTML tags. A select tag is also called a drop-down list, and input tags can be used for multiple things (checkbox, radio button, text, password).

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')]).