Assigning ID to all elements of a page in angular automatically
We have been working on a React project for which we are doing e2e testing using 'Mocha-Nightwatch'. As a UI automation tester I needed something to access the elements, there were following options for me:
1) Using the "CSS selector", which is ugly and long as you mentioned.
2) Using The "X-path" of the element, which is again long and much more confusing
3) The best of all the "Id's" for elements [because they are unique throughout the app]. But the problem was when we gave id an element, React web pack will append a alphas numeric string to the id each time you build the application,making a unique id every time. So again id's failed in this scenerio.
4) The thing which we settled for was "Classes" for the elements which we wanted to access in testing.
As far is going the id or classnames is concerned, there is no shortcut in doing it. You need to give meaningful names for the id/classnames, some tool [which may or may not exist] will add some random id to all the elements which is not at all needed, and just increases the space complexity of your application.
The better solution is take up module by module and add class or id's[id they are not made dynamic by Webpack in you case] names by yourself.
The approach we used was we taught the automation tested how to add class names or id's, and how to inspect in the chrome dev tools, if the id's/classes really exist or not. But the limitaion of this is, the tester may add some classes or id which may conflict with your functionality. to solve this you can use a proper naming convention, for e.g. we use .test-something-something or #test-something-somethig as our convention for naming the test id's and classes.
Here is a sample from your selectors file:
usernameInput: '.test--auth-username > input',
passwordInput: '.test--auth-password > input',
loginButton: '.test--auth-submit > button',
loginError: '.test--auth-error',
inputError: '.test--inputField-errorText',
Hope this helps,
Cheers
How to set the id attribute of a HTML element dynamically with angularjs (1.x)?
ngAttr
directive can totally be of help here, as introduced in the official documentation
https://docs.angularjs.org/guide/interpolation#-ngattr-for-binding-to-arbitrary-attributes
For instance, to set the id
attribute value of a div
element, so that it contains an index, a view fragment might contain
<div ng-attr-id="{{ 'object-' + myScopeObject.index }}"></div>
which would get interpolated to
<div id="object-1"></div>
Dynamically assign element id inside ngFor
You can use {{ 'wave' + i }}
instead of wave{{i}}
. Make it as Angular Experession. This is the full ngFor
:
<li *ngFor="let episode of episodes; let i = index">
<div id="{{ 'wave' + i }}"></div>
</li>
It works and creates the div
with the correct id
document.getElementById("wave1")
Output will be like this:
<div id="wave1">wave1</div>
but remember your code will start from wave0
as i = index
starts from 0.
Adding ID attribute to all HTML elements of a web application?
To do reliable frontend tests, you need to be able to identify certain elements without using overly specific selectors (which you need, if you have no reference elements). A selector like body div:nth-of-type(4) ul li:nth-child(5) a
to check a certain link is not only obviously ugly, but also prone to changes in the markup. A small change could break half of your testsuite. To avoid this, there are several ways to make your test engineer's life easier:
The bad way
would be to assign id
s to all your page elements...
The good way
is the following approach:
- Make use of the new semantic tags like
<nav>
,<header>
,<footer>
,<main>
, and<section>
.
With these elements you can build the basic structure of your page. - Assign
id
s to important/unique page elements. Use them sparingly, use meaningful names and keep in mind thatid
s represent unique elements (may only occur once on the page)! - Use the
class
attribute to group more than one elements with similar characteristics (for example navigation elements, external/internal anchors, interaction elements,...) - Avoid
name
attributes, or use only if necessary. HTML5 deprecated this attribute on certain elements like the<a>
, so I would avoid it altogether. It's not necessary considering all the other options you have.
Finally, you should have a pair programming session with your test engineer to get a better feeling, what his needs are, so you don't plaster the page with useless markup.
Should I use ids to locate elements?
The general rule is to use IDs whenever possible assuming they are unique across the DOM and not dynamically generated. Quoting Jim Holmes:
Whenever possible, use ID attributes. If the page is valid HTML, then
IDs are unique on the page. They're extraordinarily fast for
resolution in every browser, and the UI can change dramatically but
your script will still locate the element.Sometimes IDs aren't the right choice. Dynamically generated IDs are
almost always the wrong choice when you're working with something like
a grid control. You rely on an id that is likely tied to the specific
row position and then you're screwed if your row changes.
Also, in general try to use the "data-oriented" approach: by.model
, by.binding
, by.repeater
locators, or if you rely on class names, choose them wisely: do not use layout-oriented classes like .col-xs-4
or .container-fluid
.
See also these related topics:
- Best Practices for Watir and Selenium Locators
- best way to detect an element on a web page for seleniumRC in java
AngularJS - ng-repeat to assign/generate a new unique ID
You can use $index
https://docs.angularjs.org/api/ng/directive/ngRepeat
<li ng-repeat="country in countries" data-show="????">
{{country.name}} has population of {{country.population}}
<div id="country-{{$index}}">
<p>Expand/collapse content
</div>
</li>
Angular 2 unique id for every component instance of jQuery
Suppose you have a checkbox,
<input class="styled-checkbox" id="{{checkboxId}}" type="checkbox">
<label for="{{checkboxId}}">{{checkboxLabel}}</label>
import { Component, Input } from '@angular/core';
@Component({
selector: 'checkbox',
templateUrl: './checkbox.component.html'
})
export class CheckboxComponent {
@Input() checkboxId:string;
@Input() checkboxLabel:string;
}
in parent -->
<checkbox [checkboxId]="Math.random().toString(36).substring(2)"></checkbox>
how can i change class by get element by id in angular 8 and change the style of div
Try so:
In template:
<div class="col-md-12" id="demo" #demo>
...
<td>
<i class="material-icons text-primary pointer" (click)="details(demo)">account_circle</i>
</td>
...
</div>
and in .ts
details(elem: HTMLElement) {
console.log(elem.className, 'before');
elem.className = 'col-md-6';
console.log(elem.className, 'after');
}
How to assign a different ID to every auto-generated button?
Well, i used javascript, and it worked.
groupinput.onclick = function(){ window.location.replace('pages/appviz.html?groupid=' + groupid);};
Related Topics
Prevent Form Submission on Enter Key Press
Mongodb Get Data to Display in HTML
Change Specific Button Text on Click Inside Ngfor
Formdata Created from an Existing Form Seems Empty When I Log It
How to Get the Index from a Json Object With Value
Best Way to Show a Loading Spinner/Gif While My React Component Is Fetching Via Ajax
How to Use Zindex in React-Native
Converting Text to Unicode in JavaScript
Delete Span Tag Along With Text in HTML Permanently
Property Does Not Exist on Type 'Never' Typescript/React
How to Access the Value of a Promise
Avoid a Link to Reload the Page in JavaScript
Save Only Date Without Timezone JavaScript
Jest Encountered an Unexpected Token: Syntaxerror: Unexpected Token {
Javascript - Remove Milliseconds from Date Object
Mobile Safari Sometimes Does Not Trigger the Click Event
How to Get the Ajax Response from Success and Assign It in a Variable Using Jquery