Capybara integration testing 'TextAngular' input - angularjs

Using TextAngular for a rich text input box in a AngularJS/ Rails environment.
Running integration tests with Capybara/Selenium & Capybara-Webkit.
Tried to create an integration test that inputs text into the text area for a test. However, I have not been able to successfully do this.
The thing that has prevented me is the text input box id changes ever time the test loads or page loads. So I used the below class, which is used in the text angular tests. With:
find('textarea.ta-html.ta-editor')
I used this as i know it works and the javascript tests written for text angular used this. text angular github tests
However, when i try and set the text area with a text value:
find('textarea.ta-html.ta-editor').set("Upgraded to SSD")
I get:
Failure/Error: find('textarea.ta-html.ta-editor').set("Upgraded to SSD")
Selenium::WebDriver::Error::ElementNotVisibleError:
Element is not currently visible and so may not be interacted with
How can I set a value for the text area using Capybara?

The element that matches textarea.ta-html.ta-editor is hidden on the page and is not the element a user interacts with. By design Capybara generally requires you to interact with the elements a user would interact with so you need to call #set on the visible element which is the previous sibling to the element you're attempting to interact with and matches div[contenteditable]. You don't show your HTML but hopefully you have a containing element you can scope to so you can do
find('<container_selector> div[contenteditable]').set(...)
or
find('<more_general_container_selector>', text: '<label text or something else in the container>').find('div[contenteditable]').set(....)
If you only have one of this type of field on the page you can probably get away with
find('.text-angular div[contenteditable]').set('Upgraded to SSD')
Note: If using the selenium driver it has a limitation that it can only interact with the main contenteditable element and not with the children that get created inside it. I'm not sure if the other capybara drivers have the same issue.

Related

Cannot get XPath selector to work using Robocorp Selenium library

I am attempting web automation with a platform called Robocorp using the Selenium library.
When I run my program, I have no issues until I encounter this page where I am trying to get the program to click on the icon that says SQL.
I want the <a> element with the #href attribute.
Here are some (of many) XPaths I have tried that have all failed:
xpath://a[contains(#href,'sql_form.jsp')]
xpath://*[text()='SQL']
xpath://a[#target='frame2]
Snapshot of the element:
I circled the element in red ^^^
I cannot get the selector to be recognized on this page. I have tried adding delays, waiting until the element is active, waiting until the element is visible, etc.
Nothing seems to work.
Here is an image of the elements I am trying to select.
(The link in the href element takes me to the page I am trying to access).
I thought that the third one would for sure work but is still failing.
I am using a platform called Robocorp which only needs the raw selector to work (CSS or XPath)
I was unaware that iframe needed to be handled differently or that it even existed
https://robocorp.com/docs/development-guide/browser/how-to-work-with-iframes
I first needed to switch frames.
To identify the element with text as SQL you can use you can use either of the following locator strategies:
Using Wait Until Element Is Visible:
Wait Until Element Is Visible xpath=//a[starts-with(#href, 'sql_form.jsp') and #target='frame2']/font[text()='SQL'] 10 seconds
Using Wait Until Element Is Enabled:
Wait Until Element Is Enabled xpath=//a[starts-with(#href, 'sql_form.jsp') and #target='frame2']/font[text()='SQL'] 10 seconds
References
You can find a couple of relevant detailed discussions in:
How to click a row that has javascript on click event in RIDE
Robot Framework: Wait Until Element Is Visible vs. Element Should Be Visible, which one is better to use?

Appium: Element is not interactable error is getting displayed while tapping on the checkbox

Tried: xpath= //*[#id="mktoCheckbox_52362_0"],
Console Error: Element is not interactable.
Tried: Xpath= //[#id="mktoForm_2768"]/div[10]/div[1]/div[2]/div[2]/label,
console error: Element is not interactable.
Tried: xpath= //*[text()='I agree to the '],
clicking on 'License Agreement' link and open pdf file in other tab.
Applied all the above xpath but still got no result. Please provide some solution to this problem.
Assuming you're trying to automate this page: https://info.couchbase.com/couchbase_server_mobile.html
If you want to open the license agreement in a new tab - the relevant XPath would be
//a[text()='License Agreement']
If you want to tick the checkbox associated with the license agreement you need this one:
//input[#name='termsandConditions']
In both case it's better to use Explicit Wait to ensure that the element is clickable prior to attempting to interact with it via i.e. ExpectedConditions.elementToBeClickable() function
Going forward if you're working on mobile automation you can consider using Appium Studio which provides Copy Unique XPath feature, it can make your life easier when it comes to defining an element locator

Is it possible to uniquely identify DOM elements in React code?

I am using React Dev Tools to inspect a React App in Chrome. Here is a screenshot of what I see:
Now I would like to identify the highlighted input object in my React code, in order to modify the event that is called when I type in some input. My problem is that there are several input elements in the DOM. I can easily type in some random number in one of the input fields and then identify which element in the DOM I have modified by my input. But I do not know how to identify that element in the code since there are several input elements of the same type in the code. That makes it hard to identify the specific line or the specific element in the code that I modified in the DOM.
Is there a way to find a specific DOM element in the code? Or to modify my code such that I find out which element in the code has called the event handler?
I have tried to log this in the console in the event handler but this in my case returns a reference to the entire component and not the specific element that called the event handler.
Use React Dev Tools
As the main image of React Dev Tools shows, you can inspect the element on the screen and see the structure of the code. This will be a helpfull tool for you.
If you want to know exactly what field to change, just add so prop to the field like id='123' and you will be able to see it in the Dev Tools.
To learn how to install and use that Chrome plugin, you can do a little search and you will find it ;)
Edit: I said to add a prop field like id='123' but you can add any prop like elementIWantToSee='here'and with the Dev Tools you would easily find the element

BDD Testing angularJS directives

I am in a project where we are asked to “componentize” certain controls in angular directives (buttons, checkboxes, tooltip, …)
Very much of what angular-ui is doing…
We would also like to adopt BDD testing like it should. (= start with a BDD set of tests/specs before starting development, see below)
While the project is going further, there is discussion about WHAT part of the directive should be tested WHERE (e2e tests with protractor OR (unit) specs with use of compiled html).
A current “problematic/blurry” directive would be a “tooltip”.
Where do you test what…
The goal of this post should be to get a set of criteria of WHERE to write WHAT kind of tests/specs/whatever/….
A second goal would be to get a correct workflow of developing/testing:
For this I found an idea in this presentation from Julie Ralph
https://docs.google.com/presentation/d/17MoD75c2V26MBvimCMPlZdT-cYm7KZd3mLdng0io258/edit#slide=id.g2570824a9_033
• 1. Logic : Do the controller’s methods do what expected?
• 2. Correct Compilation : Correct DOM structure is generated
• 3. User Event Handling : Is the default tab displaying? Does clicking a tab change the tab?
In my opinion, BDD tests resort under the third (“user event handling”)
Development should start with this “set”.
1 and 2 should “grow” during development.
E2e tests (via protractor) should not by used for one directive, but to test interaction of directives (eg: a button and an input on a form)
Your input is very much appreciated and thank you in advance.

Dynamic Hyperlink in Livecycle Form

I am trying to figure out how to make a hyperlink in a Livecycle Form which points to a URL which will change on different days that the form is rendered. For example on one day I might want the hyperlink to point to:
mywebsite/mypage?option=XXX
and on another day I want it to point to:
mywebsite/mypage?option=YYY
The XXX and YYY can be passed into the form's data pretty easily as XML, but I just don't know how to make it so that the hyperlink is changed to correspond to this.
Any suggestions?
This can be accomplished with JavaScript in LiveCycle Designer. The following script, placed on the Form's docReady event will let you dynamically change the URL of a text object.
form1::docReady - (JavaScript, client)
// If this code is running on the server, you don't want it to run any code
// that might force a relayout, or you could get stuck in an infinite loop
if (xfa.host.name != "XFAPresentationAgent") {
// You would load the URL that you want into this variable, based on
// whatever XML data is being passed into your form
var sURL = "www.stackoverflow.com"; // mywebsite/mypage?option=xxx
// URLs are encoded in XHTML. In order to change the URL, you need
// to create the right XHTML string and push it into the Text object's
// <value> node. This is a super simple XHTML shell for this purpose.
// You could add all sorts of markup to make your hyperlink look pretty
var sRichText = "<body><p>Foo</p></body>";
// Assuming you have a text object called "Text1" on the form, this
// call will push the rich text into the node. Note that this call
// will force a re-layout of the form
this.resolveNode("Text1").value.exData.loadXML(sRichText, false, true);
}
There are a couple of caveats: URLs in Acrobat are only supported in Acrobat 9.0 and later. So if someone using an older version of Acrobat opens your form, the URLs won't work.
Also, as you can see from the "if (xfa.host.name !=...)" line, this code won't run properly if the form is being generated on the server, because forcing a re-layout of a form during docReady can cause problems on certain older versions of the LiveCycle server. If you do need to run this script on the server, you should probably pick a different event then form::docReady.
I a number of complaints from users in WorkSpace that clicking links opened them in the same tab so they lost their WorkSpace form, and there's no option to change that in Designer 11. I think the solution I came up with for that would work for you too.
I made buttons with no border and no background, and in their click event have this line (in Javascript, run at client)
app.launchURL("http:/stackoverflow.com/", true);
It would be easy to add some logic to choose the right URL based on the day and it doesn't cause any form re-rendering.
In some spots where the hyperlink is in line with other text, I leave the text of the link blue and underlined but with no hyperlink, and just place the button (no background, no border, no caption) over it. Does require positioned and not flowed subforms for that to work, so depending on your layout it could get a little clunky.
Wow, just realized I am super late to the party. Well, for anyone using ES4 facing a similar problem . . .
Ended up using a 3rd party component to manipulate the PDF's hyperlinks...wish there was a better solution as this one costs about $1000.

Resources