How to locate Button followed by card_header-title containing specific text in sample html - robotframework

How to select Actions Button followed by the Div class containing known Text ( for example, card_header-title"Addresses" in this case) in Robot Test Framework?
The page contains several span table sections and each of them has its own actions and show-history buttons. To select the specific Actions button, I could use its xpath, but I am trying to access all sections in a for loop and the xpath of actions button in one section changes from the other, so hard coding is not an option for me. Would someone please help.
<div class="attribute-group-header card__header">
<h3 class="attribute-group-title card__header-title">Addresses</h3>
<div class="floatright">
<input type="button" class="action small btn" value="Actions">
<input type="button" class="showHistory action small btn" value="ShowHistory">
</div>
</div>

I know you say you don't want to use Xpaths but maybe one of these examples could help. I don't see any other way of achieving what you're asking for other than having id's supplied on the buttons.
You could use an xpath locator that first finds the text of the "attribute-group-title card__header-title" element and then selects the following sibling div, followed by the input:
//*[contains(text(),'Addresses')]/following-sibling::div[1]//input[#value='Actions']

Related

a11y - Should a list of buttons be a tablist or keep as a list of buttons?

I've got a list of buttons that filter a catalog in a SPA app. The structure looks like this:
<div>
<button>filter 1</button>
<button>filter 2</button>
<button>filter 3</button>
</div>
<div>
{results}
</div>
Clicking each of button causes new results to be fetched from a server and then updated in the area {results}.
We've got an accessibility expert that is insisting that we change the above structure to be a tablist, but I don't see how it would work, as from my understanding, a tablist needs tabs and a corresponding tabpanel. The buttons could be the tabs, but what of the tabpanel? I don't have the data pre-existing, it must be fetched when the buttons are clicked.
How would I update the above to make it comply with accessibility?
It kind of feels like a tablist because clicking on the buttons essentially changes your view but there is not an accessibility reason that you have to use the tablist design pattern.
I agree that you'd sort of be "forcing" it into the pattern since you only have one panel that updates rather than three separate panels.
It's perfectly fine to have a group of 3 buttons all update the same container and not use a tablist.
Is it obvious to the non-sighted user that they have 3 buttons to choose from? If not, it might be nice to have them contained in a list. You can use a real <ul> and turn off the bullet point styling or use role="list" and role="listitem".
<div role="list">
<span role="listitem">
<button>filter 1</button>
</span>
<span role="listitem">
<button>filter 2</button>
</span>
<span role="listitem">
<button>filter 3</button>
</span>
</div>
I used <span> containers for the buttons to keep the inline nature of your original example.
Next, is it obvious to the non-sighted user that the page has updated when the button was selected? It might be as simple as saying "selecting a button will update the results" or it might be obvious from the button labels. Depending on your situation, aria-live might be needed. But that's going beyond the extend of your original question.

Can't locate element using Selenium2Library due to ui-widget-overlay

I am trying to click a button/element on a popup window using Selenium2Library in Robotframework:
Click Element name=OK
But I get the following error in Robotframework:
ValueError: Element locator 'name=OK' did not match any elements.
I Believe this is happening due to an ui-widget-overlay that does not disappear. Below are snippets from the html code, containing the Ok button and the ui-widget-overlay:
<button type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" role="button" aria-disabled="false"><span class="ui-button-text">OK</span></button>
<div class="ui-widget-overlay" style="width: 1793px; height: 620px; z-index: 1005;"></div>
I know that I can successfully click element using xpath, but the xpath is dynamic in this case and I want to use a fixed value. Also, "Click Button" keyword did not work either.
Please let me know how I can go about this.
Have you tried looking at the class attribute of the button? To me it sounds like that might provide a more stable xpath or css reference. For example //button[contains(#class, 'ui-button')]
You've misinterpreted the text of the button (OK) to be itsname attribute. An attribute is part of the XML/HTML tag, e.g. it should have been something like:
<button class="some values" name"OK">
, which it's not in the sample.
As you are looking for the particular button by it's visible text, this xpath locator would match it:
xpath=//button[span[#class="ui-button-text" and text()="OK"]]
The expression reads "match a button element having as a direct child a span with that class and text"

ReactJS. The component's state won't change if click is performed on nested html element

So, I have the IssuesList component, which is the list of issues that I get using ajax and github api, and DevStatus component, which sort of wraps the list up and contains all the logic, triggers state changes by two radiobuttons and so on.
My problem: When I click on one of the radiobuttons, the DevStatus component won't change state if the click was on the text inside the radiobutton. And when I click on the corners of the radiobuttons, the blue areas without text, the state changes perfectly.
Here's the structure of the radiobuttons:
<div className="btn-group" data-toggle="buttons">
<label className="btn btn-primary active"
onClick={this.onChangeRadioButton.bind(this)}
id={this.CLOSED_ISSUE_ID}>
<input type="radio" name="options"
autoComplete="off"
id={this.CLOSED_ISSUE_INPT_ID}
onChange={this.onInputChange.bind(this)} /> Closed Issues
</label>
<label className="btn btn-primary"
onClick={this.onChangeRadioButton.bind(this)}
id={this.OPEN_ISSUE_ID}>
<input type="radio" name="options"
autoComplete="off"
id={this.OPENED_ISSUE_INPT_ID}
onChange={this.onInputChange.bind(this)} /> Open Issues
</label>
</div>
Here's the codepen with the code and here's the full page view so you could better see and understand what I'm talking about.
Please, open the full page view and try to click on parts of the button that contain text and on ones that don't and you'll notice that as long as you click on parts without text - the state changes and if you click on text itself - the state doesn't change at all.
Could you please help me with that problem?
PS: removing onChange from the input element is not the solution.
Update 1
If you go to DevTools and inspect the radiobutton element, you'll see that inside the label tag there're input and weird span elements. The span element is not in the code I wrote, did React automatically add that? For some reason, the onClick event listener is not applied to those input and span elements.
Update 2
I've tried to add click event listener to the radiobutton in the console of dev tools and tried to figure out the target of the clicked element. When I click on the text - it is the span element and when I click on place without text - it is the label element and that's why the click event is not working.
Can my problem be solved using dangerouslySetInnerHTML, so that it won't create the unnecessary span?
Could you tell me please how to solve that?
React is creating a span because your text is not in any div. Also it would create a span if there was any white space (but in your case this is because there is no div around your text).
But the real problem here is the way you check your event. You need to check e.currentTarget instead of e.target
Then no need to use the ugly dangerouslysetinnerhtml!
React appeared to sometimes be adding span tags around text, no matter if there are the free white-spaces or not. The spans didn't allow the onClick event to fire when they were clicked on.
So, to force React not to render the spans, the dangerouslySetInnerHTML may be used:
noSpanRender(text) {
return { __html: `<input type='radio' name='options' autoComplete='off'/>${text}` };
}
render() {
return (
<div className="dev-status-page col-centered">
<div className="graphs">
<h1 className="text-center page-header">
Our Recent Closed and Opened Issues from GitHub
</h1>
</div>
<div className="issues col-centered">
<div className="btn-group" data-toggle="buttons">
<label className="btn btn-primary active"
onClick={this.onChangeRadioButton.bind(this)}
id={this.CLOSED_ISSUE_ID}
dangerouslySetInnerHTML={this.noSpanRender('Closed Issues')} />
<label className="btn btn-primary"
onClick={this.onChangeRadioButton.bind(this)}
id={this.OPEN_ISSUE_ID}
dangerouslySetInnerHTML={this.noSpanRender('Open Issues')} />
</div>
<IssuesList issues={this.state.issues} />
</div>
</div>
)
}
It was vital to avoid those span elements inside the input tag, so using dangerouslySetInnerHTML finally helped.

Add two different fonts to the same button

I have a button and on it I want to add two text labels whose font and size differ. I also want each text label to appear on its own line. For example, if my labels are ABCD and example, here's how I want them to appear on the button:
ABCD
example
Here is what I have tried. Is it possible to apply different styles to different parts of the value attribute?
<input style="width:170px; height:100px; font-size:90%; type="button" value="ABCD example">
You could use a button rather than an input and use two span tags inside. For example:
<button class="btn btn-primary" type="button">
<span style="font-size:14px;">ABCD</span>
<span style="font-size:10px;">example</span>
</button>
Live example at: http://jsfiddle.net/h6jq7ep2/
I've used inline styles just for simplicity, but obviously you could instead assign a class with the appropriate CSS to each span.
Try <button> element:
<button><span style="font-size:110%">ABCD</span> example</button>
It works about the same was as <input type="button">
you can not do this, you want to apply style on a part of the string, there is no simple way of doing this, you should use image instead. the is pure design purpose. just search online button image maker, you'll find a lot.

How do I bind a dynamic set of jQuery Mobile buttons using Knockout.js?

I'm using jQuery Mobile (jQM) and Knockout.js (ko) to develop an application. In this application, I need to generate a variable number of buttons that are defined by a constantly updating web service.
So, in my markup, I have:
<div id="answerPage-buttons" data-bind="foreach: buttonsLabels">
<button data-role="button" data-inline="true" data-theme="b" data-bind="text: text, click: $root.submitAnswer" />
</div>
buttonLabels is a list of short strings returned from the web service. It's defined as:
self.buttonLabels = ko.observableArray();
This all works fine when the buttons are not "jQM styled". However, when I style them using:
$("#answerPage-buttons").trigger("create");
problems arise during the update.
The issue seems to be that jQM wraps the buttons in a div (with a sibling span) to make them all nice and mobile looking. However, when the ko applies the updates via the bindings, it only removes the tags, leaving the surrounding stuff, and adds new button tags - which are then also styled by the jQM trigger call.
So, I end up with an ever-growing list of buttons - with only the last set being operational (as the previous ones are gutted by the removal of their button element, but all the styling remains).
I've managed to address this, I think, by placing the following call immediately after the observable is updated:
$("#answerPage-buttons div.ui-btn").remove();
However, my feeling is that there's probably a better approach. Is there?
I found a solution.
If I surround the buttons with a div, it seems to work - e.g.
<div id="answerPage-buttons" data-bind="foreach: buttonsLabels">
<div>
<button data-role="button" data-inline="true" data-theme="b" data-bind="text: text, click: $root.submitAnswer" />
</div>
</div>
I'm guessing this is because the markup added by jQM remains "inside" the markup replicated by ko. Without the div, jQM wraps the button tag, which was the immediate child of the tag that contains the ko foreach binding.

Resources