How to test pointer-events: none with Protractor and Jasmine? - css

Under certain circumstances I am setting the css property "pointer-events:none" to avoid an element being clickable (it is a complex element which cannot be disabled one by one and which it is wrapped by a div and this div has the pointer-events to none)
So what used to be clickable and tested like that, it is not anymore.
When I try to test it I always get this:
Failed: unknown error: Element is not clickable at point (167, 407). Other element would receive the click:...
Which is expected because as the element is not clickable, the parent element gets the click.
My question is, how to test with Protractor/Jasmine an element which is not clickable by setting this property (pointer-events)?
By the way, the commonly used methods isEnabled and isDisplayed, both of them return true.
I also thought about creating a test which expected the error (although I would prefer a cleaner solution), with toThrow() or ToThrowError() but it didn't work at all.
Thanks

You can try special EC for this -
http://www.protractortest.org/#/api?view=ExpectedConditions.prototype.elementToBeClickable
Example:
var isClickable = protractor.ExpectedConditions.elementToBeClickable($('your element here'));
expect(isClickable()).toBeFalsy('Element expected not to be clickable');
I met the same problem - how i do assertion that i cannot click on element -
myElement.click().then(
() => {
fail("Element should not be clickable for Observer");
},
(err) => {
expect(err.message.toString()).toMatch("Element is not clickable at point");
});
Putting error callback and asserting that correct error was thrown.

Related

I have two iframes I need one

How do I take an iframe if I have two with the same classes and neither eq() nor first() works when I use cy.iframe().
Here is the error:
Each radio is made up of a 'form' and inside each one contains the respective iframe.
But I only want to take the one that is checked
*
This is my script
I'm guessing you're using cypress-iframe since cypress doesn't have a built-in iframe command available.
As you can tell, iframe() allows passing a selector. If your iframe tags are identical in their attributes so you cannot use attributes to select, or you just want to use the order, note that you have to use that as part of the selector. Instead use a selector that has the order part of it such as :first or :nth-child(n)
// will NOT work
cy.iframe().first()
cy.iframe().eq(1)
// will work
cy.iframe("iframe:first")
// for 2nd item use 2, since it uses a 1 based index
cy.iframe("iframe:nth-child(2)")
I can't see why cy.iframe('iframe:first') would not work, but if you have independent parent elements, e.g the <form> element mentioned, it's possible to pre-select the correct parent and apply cy.iframe() using that parent as "root" element.
The .within() command changes the root element:
cy.visit('/', {
onBeforeLoad(win) {
cy.stub(win.console, 'log').as('consoleLog')if you
}
})
cy.get('#consoleLog').should('be.calledWith', 'Iframe Loaded')
cy.get('iframe').eq(0)
.parent()
.within($iframeParentElement => {
cy.iframe()
.should('have.length', 1) // expected <body> to have a length of 1 ✅
.find('input#data')
.should('have.length', 1) // expected <input#data> to have a length of 1 ✅
})
I also added a check on the "IFrame Loaded" console message that Tokenex emits, so as to delay <iframe> commands until loading is complete.

CSS Change Each Cursor

I have a website I'm building and I want to have a custom cursors specified for each property like hand, wait, pointer, default, move and so on...
I'm build an operating system website so I want to have custom cursors.
Here is the CSS code.
* {
cursor:url("../.drive/system/visual/cursors/pointer.png"),pointer;
cursor:url("../.drive/system/visual/cursors/hand.cur"),hand;
cursor:url("../.drive/system/visual/cursors/pointer.cur"),default;
cursor:url("../.drive/system/visual/cursors/move.cur"),move;
cursor:url("../.drive/system/visual/cursors/move.cur"),all-scroll;
cursor:url("../.drive/system/visual/cursors/horizontal-resize.cur"),col-resize;
cursor:url("../.drive/system/visual/cursors/horizontal-resize.cur"),e-resize;
cursor:url("../.drive/system/visual/cursors/horizontal-resize.cur"),w-resize;
cursor:url("../.drive/system/visual/cursors/vertical-resize.cur"),row-resize;
cursor:url("../.drive/system/visual/cursors/vertical-resize.cur"),n-resize;
cursor:url("../.drive/system/visual/cursors/vertical-resize.cur"),s-resize;
cursor:url("../.drive/system/visual/cursors/diagonal-resize-1.cur"),se-resize;
cursor:url("../.drive/system/visual/cursors/diagonal-resize-1.cur"),nw-resize;
cursor:url("../.drive/system/visual/cursors/diagonal-resize-2.cur"),sw-resize;
cursor:url("../.drive/system/visual/cursors/diagonal-resize-2.cur"),ne-resize;
cursor:url("../.drive/system/visual/cursors/move.cur"),grab;
cursor:url("../.drive/system/visual/cursors/move.cur"),grabbing;
cursor:url("../.drive/system/visual/cursors/unavailable.cur"),no-drop;
cursor:url("../.drive/system/visual/cursors/unavailable.cur"),not-allowed;
cursor:url("../.drive/system/visual/cursors/text.cur"),vertical-text;
cursor:url("../.drive/system/visual/cursors/text.png"),text;
cursor:url("../.drive/system/visual/cursors/wait.cur"),wait;
cursor:url("../.drive/system/visual/cursors/help.cur"),help;
cursor:url("../.drive/system/visual/cursors/precision-select.cur"),crosshair;
}
The only cursor that happens to load is the one at the bottom (crosshair)
I've also specified some PNG cursors aswell and they did not change the outcome.
I tried putting this into html,body{} and div{} but again nothing worked.
I want something like on Windows93 but without JavaScript
If there is no CSS-only method then I can accept JavaScript ones. But please only vanilla-js.Thanks!
The cursor values are overwriting each other. This means that the last value is the only one that works, as it is the last one to overwrite the cursor value.
The word that follows the URL is a fallback keyword. This means that if the image cannot be found or rendered, the cursor specified by the keyword will be drawn.
For example, with the property cursor: url("../.drive/system/visual/cursors/precision-select.cur"), crosshair;, the browser will attempt to draw the cursor specified in the URL, but if it cannot it will use the default crosshair cursor.
To get the browser to display different cursors you will need to specify the cursor for each element. For your default cursor you would have:
* {
cursor:url("../.drive/system/visual/cursors/pointer.cur"),default;
}
To get a pointer over links you might then do:
a {
cursor:url("../.drive/system/visual/cursors/pointer.png"),pointer;
}
For crosshairs on a particular element you might try:
.target-element {
cursor:url("../.drive/system/visual/cursors/precision-select.cur"),crosshair;
}
You need to specify the cursor property for each element that you wish to have a changed/custom cursor. Using a universal selector for the default cursor ensures that you only specify the property for elements that require it.

Clicking a button based on the text

I am using TestCafe to test a locally run application without problems besides the below :
I have an element that looks as follows:
Upload file
When the test attempts to click the element by using
.click(Selector('.btn').withText('Upload file'))
the following error is given
1) The specified selector does not match any element in the DOM tree.
  | Selector('.btn')
 > | .withText('Upload new file')
Any hint would be appreciated as to what could be wrong.
I've checked a button click on the Bootstrap site with a similar button and it works as expected. Please see the following code:
 
import { Selector } from 'testcafe';
fixture `bootstrap`
.page `https://getbootstrap.com/docs/4.2/components/buttons/`;
test(`click button`, async t => {
await t.click(Selector('.btn').withText('Success'));
});
 
I recommend you check your site and ensure that:
The button's offsetWidth and offsetHeight are greater than zero.
The button does not have styles like display:none or visibility: hidden.
The button contains exactly the same text as you are searching for.
 
If this does not help, It would be great if you share your project or website url to demonstrate the issue.
 
 
When TestCafe gives this error message: The specified selector does not match any element in the DOM tree, and I have no clue of what is happening, I take the following path:
I create a Selector variable that targets the element and hover over it before clicking on it:
const uploadFileButton = Selector('a.btn').withExactText('Upload file');
await t
.hover(uploadFileButton)
.click(uploadFileButton);
Notice that in the above code, I have tried to be as specific as possible when defining the Selector.
If, at runtime, you do not see the TestCafe cursor moving towards the target element (this means you don't run in headless mode), then you know that the Selector is wrong. It could be because the element has not mounted in the DOM at the time TestCafe tries to hover over it. To validate this point, modify the TestCafe code to:
const uploadFileButton = Selector('a.btn').withExactText('Upload file');
await t
.expect(uploadFileButton.exists)
.ok({timeout: 10000})
.hover(uploadFileButton)
.click(uploadFileButton);
If, at runtime, TestCafe stops on the .ok() line, then you know that the Selector is definitely wrong.
In this case, go to the developer tools and type the following command in the console:
var el = document.querySelectorAll('a.btn');
el <ENTER>
inspect the content of the el element. If you find the targeted button, then you should check the innerText property and you should check if there is no CSS rule that makes the text upper case or makes it invisible.

what is the proper way to interact with inner components within the shadowDom using lit-element?

I am trying to use paper-dialog within my custom component.
I want to be able to open the dialog from outside the component. What is the best way to do this? (all the examples work directly on the component)
Also the dialog requires me to call "open()" on it to open it.
In the examples I found I found:
this.$.dialog.open();
But this doesn't seem to work with lit-element
I got it to work using shadowRoot, not sure this is the best option:
render() {
return html`
<style>
</style>
<paper-dialog id="dialog">
<h2>Content</h2>
</paper-dialog>
`;
}
firstUpdated(changedProperties) {
console.log("firstUpdated called")
if (this.shown == "true")
{
// this.$.dialog.open();
this.shadowRoot.getElementById("dialog").open()
}
}
I added a property to my element called "shown"
static get properties() {
return {
shown: Boolean,
Thinking I could pass this from the outside into my component, but it doesnt seem to do the trick either (I can set it once with the custom element propery, but changes to it from the out side dont seem to work.
Generally, if you are aggregating a dialog within an element that has other UI elements then you shouldn't be showing/hiding the dialog from outside the element - the event that triggers the dialog should be raised and handled with the containing element.
That said, if it's absolutely necessary, then I prefer a "showDialog" method (not a property). Closing the dialog should be triggered by a dialog button or loss of focus, so you don't need to expose a close method.

Webdriver error: Element is not clickable at point (-99999800, 242.5) driving Facebox control via watir-webdriver

I'm using watir-webdriver with chrome to automate my tests and I'm kinda stuck now.
I have a form inside a facebox(defunkt.io/facebox). There are many checkboxes inside this form as you can see:
irb(main):113:0> b.checkboxes.size
=> 122
My problem is when i try to set one of this checkboxes I get the following error:
irb(main):111:0> b.checkbox(:id => 'week_0').set 1
Selenium::WebDriver::Error::UnknownError: Element is not clickable at point (-99999800, 242.5)
Backtrace:
0x8088d3a
0x8076225
0x807c718
0x807c9e7
0x807f6b7
0x808009d
0x8067c5c
0x8074931
0x8059fda
0x80d1d4d
0x80d3773
0x80d3aa3
start_thread [0x5e9e99]
0x10b973e
from /usr/local/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.14.0/lib/selenium/webdriver/remote/response.rb:50:in `assert_ok'
from /usr/local/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.14.0/lib/selenium/webdriver/remote/response.rb:15:in `initialize'
from /usr/local/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.14.0/lib/selenium/webdriver/remote/http/common.rb:58:in `new'
from /usr/local/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.14.0/lib/selenium/webdriver/remote/http/common.rb:58:in `create_response'
from /usr/local/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.14.0/lib/selenium/webdriver/remote/http/default.rb:64:in `request'
from /usr/local/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.14.0/lib/selenium/webdriver/remote/http/common.rb:39:in `call'
from /usr/local/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.14.0/lib/selenium/webdriver/remote/bridge.rb:450:in `raw_execute'
from /usr/local/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.14.0/lib/selenium/webdriver/remote/bridge.rb:428:in `execute'
from /usr/local/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.14.0/lib/selenium/webdriver/remote/bridge.rb:264:in `clickElement'
from /usr/local/lib/ruby/gems/1.9.1/gems/selenium-webdriver-2.14.0/lib/selenium/webdriver/common/element.rb:34:in `click'
from /usr/local/lib/ruby/gems/1.9.1/gems/watir-webdriver-0.3.9/lib/watir-webdriver/elements/checkbox.rb:25:in `set'
from (irb):111
from /usr/local/bin/irb:12:in `<main>'
What should I do to handle facebox with watir-webdriver on chrome?
EDIT:
I found the problem with a TIP from Chuck (look elements attribute at inspect element tool).
So I noticed the checkboxes had -999999px left position.
Solution:
browser.execute_script("$('[type=checkbox]').removeClass('ui-helper-hidden-accessible')")
(since this was the class that was causing the left negative shift)
I found the problem with a TIP from Chuck (look elements attribute at inspect element tool). So I noticed the checkboxes had -999999px left position.
Solution:
browser.execute_script("$('[type=checkbox]').removeClass('ui-helper-hidden-accessible')")
(since this was the class that was causing the left negative shift)
The error makes me think the thing may not be visible or active somehow. Is the script actually displaying the lightbox at the time it tries to interact with it? Do you need to insert a brief pause or wait for the checkbox to get rendered and the javascript code that 'pops up' the lightbox to finish it's thing?
If it is not visible then I could see it producing an error of the sort you are getting.
Likewise if the script is just going a little too quick, that could be the issue also.
Use the developer tools (in chrome you can right click an element and choose 'inspect element') and look at the properties (specifically position) of the element in question, and the elements further up the 'tree' (as it were) that contain it.
You might be able to brute force around this by changing the class, or altering the CSS for the class to temporarily to 'relocate' the object such that Watir believes it is visible. I've had to do something similar for stuff that used the hover state to hide or show menus, where for whatever reason 'onmouseover' events were not good enough for the browser to apply a different css psuedoclass. If you are already using jquery there's some pretty simple functions that can be called to do that sort of thing. (one of your devs might be able to help you out with it) You can use .execute_script to invoke code like that if it's needed.
Try this. It will move the element into view using Javascript. Worked for me.
module Watir
class Element
def move_into_view
browser.execute_script(%Q[
var element = arguments[0];
element.style.position = 'absolute';
element.style.left = '10px';
element.style.top = '10px';
return true;],
self )
end
end
end

Resources