How to refer slot element from its slotted element in lit-element? - polymer

I have a component named 'stack-item' which have a slot , its html will look like this
<div>
<div>1<div>
<div class='slot-style'><slot></slot></div>
</div>
I have used this component like this
<stack-item>
<another-component></another-component>
</stack-item>
From 'another-component' how do i get the element reference for class ='slot-style' for calculating the slot width and other properties ?
I wrote a workaround
let slotElement =this.shadowRoot.host.parentElement.shadowRoot.querySelector('slot').parentElement;
but is there a clean way of achieving this?

I don't know if this can be considered dramatically simpler, but the scenario you give indicates that you already know the host component is stack-item and that component has a slot wrapper with the class name 'slot-style'. Given that you can obtain a reference like this (this works from within the component as well as the host document):
let slotElement = document.querySelector("stack-item").shadowRoot.querySelector(".slot-style");
//display width
console.log(slotElement.clientWidth);

this.shadowRoot.host is equivalent to this.
So you could try:
this.parentElement.shadowRoot.querySelector( 'div.slot-style' )

Related

How to get a web element with a class attribute with several values

This is my problem: i have this html
as you can see there are two <div class="sc-fjhmcy dbJOiq flight-information"></div> and, i want to get the element using the class attribute, but only with the flight-information value, because
I think the part that is written as nonsense code ("sc-fjhmcy dbJOiq...) change daily
I have already tried with this xmlpath, $x('//div[contains(#class, "flight-information)"'], but its not working,
What could I do?...
I checked your code and I think that there is no big issue with this.
You need to use one class name to get the element, not two names, as below.
$(".sc-fjhmcy")
Then, this will be run correctly.
Best regards

Parent node in react-testing-library

The component that I have testing renders something this:
<div>Text<span>span text</span></div>
As it turns out for testing the only reliable text that I have is the 'span text' but I want to get the 'Text' part of the <div>. Using Jest and react-testing-library I can
await screen.findByText(spanText)
This returns an HTMLElement but it seems limited as I don't have any of the context around the element. For example HTML methods like parentNode and previousSibling return null or undefined. Ideally I would like to get the text content of the parent <div>. Any idea how I can do this with either Jest or react-testing-library?
A good solution for this is the closest function.
In description of closest function is written: Returns the first (starting at element) including ancestor that matches selectors, and null otherwise.
The solution would look like this:
screen.getByText("span text").closest("div")
Admittedly, Testing Library doesn't communicate clearly how to do this. It includes an eslint rule no-direct-node-access that says "Avoid direct Node access. Prefer using the methods from Testing Library". This gives the impression that TL exposes a method for a situation like this, but at the moment it does not.
It could be you don't want to use .closest(), either because your project enforces that eslint rule, or because it is not always a reliable selector. I've found two alternative ways to tackle a situation like you describe.
within():
If your element is inside another element that is selectable by a Testing Library method (like a footer or an element with unique text), you can use within() like:
within(screen.getByRole('footer')).getByText('Text');
find() within the element with a custom function:
screen.getAllByText('Text').find(div => div.innerHTML.includes('span text'));
Doesn't look the prettiest, but you can pass any JS function you want so it's very flexible and controllable.
Ps. if you use my second option depending on your TypeScript config you may need to make an undefined check before asserting on the element with Testing Library's expect(...).toBeDefined().
But I have used HTML methods a lot and there was no problem yet. What was your problem with HTML methods?
You can try this code.
const spanElement = screen.getElementByText('span text');
const parentDiv = spanElement.parentElement as HTMLElement;
within(parentDiv).getElementByText('...');

How to access the style attribute of Primeng table

In an angular project, I need to test that the displayed table width of the primeng data table is set to the maxWidth value i assign to it. To do so, i want to call the [style] attribute to get the width and see if its equal to my maxWidth. However, i do not know how to call attributes like this. How do i go about this? Currently i have no clue if I'm going in the correct direction.
I have tried several things but I am not sure of the syntax for it.
<p-table class="p-table" ... [style] = "{width: maxWidth}" >
it('should implement maxwidth', () => {
const widthDebug: DebugElement = fixture.debugElement;
const tableWidth = widthDebug.query(By.css('.ui-table .ui-widget'));
const ptable: HTMLElement = tableWidth.nativeElement;
expect(ptable.textContent).toContain("width: " + component.maxWidth);
});
expected: success (ptable.textContent contains "width: component.maxWidth")
actual: TypeError: cannot read property 'nativeElement' of null
I see that it's now two months after you asked your question, so it's probably too late for my answer to help, but I stumbled across this post while looking up something else about PrimeNG, so I might as well give it a shot.
The problem here is that nativeElement is defined on Dialog class instances of the Angular p-table component. It's not defined on any particular DOM element.
By.css('.ui-table .ui-widget') is going to find a DOM element for you, not an Angular class instance. In particular what will be found is a <div> inside the <p-dialog> DOM element, and it's this <div> that receives the style set via [style]=....
As your code is written above tableWidth.style.width would contain (as a string) the value of maxWidth that you're expecting to find.

How to check if a class mixin has been applied to a Polymer element?

I would like to check if a mixin has been applied to a custom element, but I don't think I can use 'instanceof', since a mixin is not properly a base class (I tried, of course).
I would need to enforce that an element added to a collection can be only of a kind with a particular class mixin applied...
Any suggestions?
Not sure I understand you question correctly.
I assume you want to check something like MyCustomElement has already apply MyMixin or not?
You can check from the instance
let instance = new MyCustomElement()
console.log(instance instanceof MyMixin)
This will only work when MyMixin is a class not a factory function. If you follow documentation you need to change it.
Another way, you can declare some static function in MyMixin. Then you can call from MyCustomElement to check it.

How can I click on a div button with selenium webdriver?

I have this button:-
<div class="dsk-col-1-4 card new">
<div class="div_center_div">
<span class="icon icon_plus-black-symbol"></span>
<h2>Create</h2>
</div>
</div>
But I tried with find element by classname:-
driver.findElementByClassName("dsk-col-1-4 card new").click();
But it does not work.
Any help?
Move to your element and click. Example:
new Actions(driver).MoveToElement(yourElement).Click().Perform();
The "by class name" locator usually expects a single class name to be passed:
driver.findElementByClassName("card").click();
If you want to use multiple classes, go with a "by CSS selector"
driver.findElementByCssSelector(".card.new").click();
Note that the dsk-col-1-4 class is not a very good choice for an element locator - this looks very much like a layout-oriented class name which not only have a higher probability to b changed, but also does not bring any information about the element and it's purpose. card and new on the other hand are a better fit.
Ok so I couldn't understand exactly Which element you want to click on,
So based on my assumption , try below Xpaths :
1) if it is <div class="dsk-col-1-4 card new"> that you want to click
//div[contains(#class,'dsk-col-1-4 card new')]
2) If it is that you want to click,
//span[contains(#class,'icon icon_plus-black-symbol')]
3) If it is <h2>Create</h2> that you want to click,
//h2[text()='Create']
Hope this Helps!!
Within your locator you're passing multiple class names, and although they are both assigned to the element the findElementByClassName function realy only works when it is a single class name. The way I'd do it would be to use findelement(By.Xpath()), in this instance you'd need to use
webDriver.findElement(By.xpath("//div[contains(#class,'dsk-col-1-4 card new')]")).click();