I'm writing some simple tests for my React components using TestUtils and I'm finding that both the TestUtils.FindRenderedDOMComponentWithClass and TestUtils.FindRenderedDOMComponentWithTag methods are pretty limiting. I'd like to find a component using the typical CSS selector (i.e. tag.class [attr]) but it doesn't seem like this is an option.
Is there a simple way to find an element with a specific attribute? If not are there any useful tools for finding components apart from TestUtils?
I find it useful to simply use the browser's Element.querySelector()/querySelectorAll() method on DOM elements.
You can just call for example like this:
var domElement = FindRenderedDOMComponentWithClass('myClass');
var firstTextInput = domElement.querySelector('input[type="text"]');
React.TestUtils does not offer component searches with CSS selectors so I went with a lightweight extension of the base TestUtils class called react-testutils-addition. It offeres a find() method which parses the CSS selector style input and uses TestUtils.findAllInRenderedTree to find the component.
Related
Hi I come from bootstrap and Im trying to learn some vuetify. I had some questions about the framework that I couldnt find the answer to in the vuetify docs.
What is a prop? (1)
What is the difference between adding a prop and adding it as a class attr? (2)
Is there a list where I can find all the props and helper classes for the components? (3)
For example: I was trying to make a container take the full width of the screen and couldnt find any property that the vuetify docs indicated that would make my container act like, this so I had to look online. I finally read on a stack overflow post that there was a prop called full-height that did exactly what I wanted. The problem was the conatiner docs said nothing about this prop in relation to the container itself. I also looked around the customization and the styles and animations tabs on the docs and could find anything about it. Where are all these props and helper classes defined?
Vuetify uses Vue.js components, so you should be familiar with them.
However, I'll try to answer your 3 questions:
Props are a way to pass data to components. Say, for example, you are building a header component which needs to get the title from the page in which you put it in. Then, you can just declare a title property and then use that inside the component. You can then pass it like your standard HTML attributes, e.g. <the-title title="Main Page" /> If the component is called TheTitle. For more thorough information, There is a whole page about props inside the official Vue.js docs.
In your use case, a class is useful when you have the appropriate CSS styling for it, otherwise it wouldn't do anything. My suggestion would be to use props for styling individual components where you don't have the same style anywhere else and classes for cases where a style repeats itself. If the style is local to the component, make sure you add scoped to the style tag to avoid applying it anywhere else.
Vuetify has a nice API explorer which you can use to browse the entire collection of components. Each one has an API section where you can see all the details, including information about the props and other stuff.
I'm newest in web.
I want customize default scroll-bar in ag-grid. I try use ngx-scrollbar for this. In sources ngx-scrollbar I found that ngx-scrollbar using ng-content for wrapping elements(link to github source file). If wrap ag-grid-angular element then scrolling even doesn't shows because content doesn't overflow ag-grid-angular content because oveflow happen in div with class .ag-body-viewport where using stock srolls. In order to achieve needed effect I wish pass DOM element with class .ag-body-viewport to ng-content of ngx-scrollbar. Is it possible?
More info here github issue but I don't use Nice Scroll or Perfect Scrollbar
I want use ngx-scrollbar because it has capability of customization.
UPDATE
I can pass DOM element to ng-content using next sintax(agGridViewport is native element):
<ng-scrollbar>
{{ agGridViewport }}
<ng-scrollbar>
but it pass element like a copy of real DOM object but I want pass this like a refence.
Now I got UI like a stack style:
[rendered real ag-grid-angular]
[rendered ng-scrollbar with his content]
But it isn't that I need. Also I got bad rendering with artifacts and even some components doesn't appear. Now I want to try use Renderer2 for putting ng-scrollbar element between two DOM elements in tree(.ag-body-viewport-wrapper and .ag-body-viewport). But I think it's very bad idea because Renderer2 doesn't have methods for putting elements between DOM elements in tree and my code will be very unlify and complicated :( It's must be like injection.
No, I can not do injection in DOM with Angular tools. It's bad idea do it and it is not possible now. AgGrid doesn't support customization with tools like ngx-scrollbar which using ng-content for wrapping components and other elements. May be better way using other tools which working by another way or using webkit customization which supports not all web browsers.
UPDATE
Also I try to use smooth-scrollbar. I managed to get better result. I bind him to element .ag-body-viewport. It works fine but it scrolling only content of grid without header be careful. smooth-scroll bar doesn't have options for horizontal and vertical scrollbar as a different units. I know how issue can be solve. Vertical scrollbar must be bind to .ag-body-viewport and horizaontal scrollbar must be bind to .ag-root. If your can find scrollbar which let you do it that you can solve this problem. May be I write special component for Angular in near future and then add link to this answer. If you do it faster you can add yourself link or you can add link to already existing packages.
I have spied an input text box using the Application Modeller of Blue Prism and was able to successfully highlight the text box using the below XPath:
/HTML/BODY(1)/DIV(4)/main(1)/DIV(1)/DIV(1)/DIV(1)/DIV(2)/DIV(1)/DIV(1)/DIV(2)/IFRAME(1)/HTML/BODY(1)/DIV(2)/FORM(1)/DIV(3)/TABLE(2)/TBODY(1)/TR(1)/TD(1)/DIV(1)/DIV(1)/DIV(1)/DIV(2)/DIV(1)/DIV(1)/DIV(1)/DIV(1)/DIV(1)/DIV(1)/DIV(1)/DIV(1)/DIV(1)/SPAN(1)/DIV(1)/DIV(2)/DIV(1)/DIV(1)/DIV(1)/DIV(1)/DIV(1)/TABLE(1)/TBODY(1)/TR(1)/TD(1)/INPUT(1)
I wanted to use a more robust XPath and to achieve that I was trying to use the below XPath:
//*[#id="CT"]/div/div/div/div[1]/div[1]/table/tbody[1]/tr/td/input[1]
The above XPath was identifying the element correctly in Chrome but was getting the below error message when trying the same in Blue Prism:
Error - Highlighting results - Object reference not set to an instance of an object.
Let me know if I am doing anything incorrectly.
Sorry for replying to a pretty old one! The workaround we've devised for this scenario (where making the path dynamic requires too long of a loop / search) is to use Jquery snippets. If the page is using jquery it is trivial to execute these queries very quickly using the blue prism capability of executing javascript functions.
And we put in an enhancement request, because it'd be supremely useful functionality.
Update: As a user points out below, the vanilla js querySelector method is probably safer and more future proof than using jquery if it is possible to be used.
Blue Prism does not fully support the XPath spec; alas the construct you're attempting to use here won't work.
Alternatively, you can set the Path attribute of an application modeler entry to be Dynamic, which allows you to insert dynamic parameters from the process/object level to pinpoint elements you'd like to interact with.
Unfortunately Blue Prism doesn't actually use "real" XPaths, but only an extremely limited subset: Absolute paths without wildcards. (Note: It is technically possible to match the XPath to a string with wildcards, but this seemingly causes BP to check every single element in the document, and is so slow it is almost never the right solution.)
For cases where an element can't be robustly identified via the BP application modeler (maybe because it requires complex or dynamic selectors), my workaround is to inject a JS snippet. JS can select elements much more reliably, and it can then generate the BluePrism path for that element.
Returning data from JS to BluePrism is not trivial, but one of the nicer solutions is to have JS create a <script id="_output"> element, put JSON inside it, then have BluePrism read the contents of this element.
For a project i am currently working on i need to be able to pass an elements absolute path/ selector to a ajax request.
I found this stackoverflow answer which shows how this can be achieved using jQuery, which i would love to use, however the project requires the use of prototype.
I was thinking about using:
.previousSiblings().size()
for indexing the current element, but not sure what to replace:
name += ':eq(' + index + ')';
(particularly :eq) for the path selector string.
I need to be able to select the same element again using prototypes $$('path') selector.
This jsfiddle should help you
http://jsfiddle.net/s7aWH/
I took the answer from the other stackoverflow answer and ported to PrototypeJS
the jQuery .index() is similar to the Prototype .indexOf()
and you can still use the ':eq()' CSS selector but you need to increment by one
Dojo custom widgets can be internationalized via the _templated mixin following the steps outlined here and here. Then placeholders within the widget template like this: ${i18n.username} are automatically replaced with the appropriate language translation.
What is the simplest way to do similar nls language substitution outside of a widget? Ideally, I would like to add an attribute to a tag to have all the placeholders within substituted, including nested tags. Is there some type of container widget that already does this?
Or does Dojo development assume everything will be in a (custom) widget? I need to localize already existing code which doesn't use widgets.
The best solutions I have found so far are:
Using dojox.mobile.i18n, which is a "a thin wrapper around dojo.i18n, and has ability to replace strings, such as CDATA or attribute values, in dojo markup." However I'm afraid this is limited to a certain subset of mobile tags/widgets.
Disabling automatic parsing and manually searching/replacing the appropriate text before explicitly calling the parser in dojo.addOnLoad().
I assumed that the notation in the external html is ${i18n.username}.This will find any node that has class="i18nReplace" and replace the innerHTML of the node. I didn't test any of this, but I hope you can use it as a starting point.
dojo.require("dojo.i18n");
dojo.require("dojo.query");
dojo.requireLocalization("myI18n", "myI18N"); // This will need to be modified to get your i18n files
dojo.addOnLoad(function() {
var i18n = dojo.i18n.getLocalization("myI18n", "myI18N");
dojo.query(".i18nReplace").forEach(function(node, index, arr){
node.innerHTML = dojo.replace(node.innerHTML, { i18n: i18n } );
// blindly doing this, does not support nested tags.
// you could add conditional logic to check for children
// and if they exist separately process them, otherwise
// replace the html.
});
});