RSpec Issue with have_css - css

I'm using Rails 5.1.1, RSpec 3.5.0 & Capybara 2.7.1.
I want to have a test that checks for a navbar on the home page, according to some documents that I've found I should be using have_css for this. The example given is:
have_css("input#movie_title")
My understanding is that this would look for an input tag with an id of movie_title. Is that correct?
I'm trying this in my code:
have_css("div.navbar-default")
I get this error, however:
Failure/Error: expect(page).to have_css("div.navbar-default") expected to find css "div.navbar-default" but there were no matches
Why is this not working? I have a div with the class 'navbar-default', so this should work as far as I can work out.
Edit / Solved:
I realised my mistake. I have to expect statements, the navbar-default class is in a nav tag, not a div tag. The 2nd statement is in a div tag but wasn't running due to the error on the first one.
I've fixed it now, all working

The have_css matcher is applied to the parent container instead of the actual element. Is there a parent container?
Try something like this:
# Find the parent
parent = page.find('div#nav')
# Check for the nested div
expect(parent).to have_css(".navbar-default")

Related

Get value of "data-..." attribute with .css selector with Scrapy

I am trying to get the value of a data-attribute with scrapy:
response.css('.product-header-top div::attr("data-background-image")').get()
But I do not get the value of data-background-image and Python throws an error:
raise SelectorSyntaxError(cssselect.parser.SelectorSyntaxError: Got
pseudo-element
::FunctionalPseudoElement[::attr(['data-background-image'])] not at
the end of a selector
Here is the relevant HTML Code of the webpage:
<div data-background-image="/images/image.jpg" style="background-image: url("/images/image.jpg");"></div>
Thanks
UPDATE
F.Hoque is right and it works fine. The website is dynamic and renders the data-background-image with JS. So the ::attr("data-...") is working. Thanks for your help #F.Hoque!
Your CSS selection is working fine. There is a typo ); just remove it.
response.css('.product-header-top div::attr("data-background-image")').get()
Proven by Scrapy shell:
In [26]: sel.css('div::attr("data-background-image")').get()
Out[26]: '/images/image.jpg'

Material ui MaxwidthLG

Hello I'm having a problem with material ui css. I tried to override it but still doesn't work. I want my full div to get the full page but this is happening.
I want it to take the full width. but I can't edit the muicontainer
in your CSS:
div.MuiContainer-root.MuiContainer-maxWidthLg.css-1qsxih2 {
width:100vw!important;max-width:100vw!important;min-width:100vw!important;
}
You might want to try using this selector instead (dropping the last class that seems to be generated each time):
div.MuiContainer-root.MuiContainer-maxWidthLg

How to either select the attribute or wildcard over CSS selector

I have been trying for days to figure out how to grab a value using CSS selector with no luck. I am not exactly great at this type of thing and learning through looking via Google search on how this might be done. I know how to use Chrome, inspect, and then highlight the area of a page and do a Copy selector, but my problem is that 2 parts in the selector have values that change on every refresh.
#root > div > div > div.MuiDrawer-root.MuiDrawer-docked.jss400 > div > div > div > li.MuiListItem-root.jss425.MuiListItem-gutters > div.MuiListItemText-root > span
Then after a page refresh, you can see the values change after jss in 2 spots
#root > div > div > div.MuiDrawer-root.MuiDrawer-docked.jss73 > div > div > div > li.MuiListItem-root.jss98.MuiListItem-gutters > div.MuiListItemText-root > span
For example, here you can see each time I refreshed the page, the following 2 parts change each time:
div.MuiDrawer-root.MuiDrawer-docked.jssXXX
li.MuiListItem-root.XXX.MuiListItem-gutters
Screenshot of where the values are
I am trying to figure out the proper syntax to form a selector that will return 'THIS IS MY NAME' even when the value changes in the 2 spots point after the jss of each part pointed out above. This is where I am getting the selector from:
<span class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock">THIS IS MY NAME</span>
I was doing some Google searching trying to figure out how I could wildcard over those values or find another way of doing it. I found that you can use an attribute selector so I have been trying to figure that out, but I don't appear to be doing it correctly.
I have tried..
[class|="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock"]
I also tried Element.querySelector() but again, using that I can't seem to figure out how to either just wildcard or go straight to the attribute and grab the value next to it.
Any help would be really appreciated. Thanks all.
You probably don't need to define the selector in every detail - but if you want to, as in your first two examples, just leave out the bits that change (.jssxxx).
Here's a simple example, boiled down from your HTML, of the basic set of selectors (just the classes immediately attached to the element you are interested in). If that isn't enough to select what you want, i.e. not unique enough, add some more in before hand, but without the .jssxxx s.
const el = document.querySelector('.MuiTypography-root.MuiListItemText-primary.MuiTypography-body1.MuiTypography-displayBlock');
console.log('Selection gives: ' + el.innerHTML);
<span class="MuiTypography-root MuiListItemText-primary MuiTypography-body1 MuiTypography-displayBlock">THIS IS MY NAME</span>

Selecting elements by text with CSS3 selectors in CasperJS

I'm doing functional testing using CasperJS's test class, and can't seem to select elements by their text values. My goal is to check that a class of div is visible, and then check it has the value I expect.
I've tried using the CSS3 selectors mentioned on CaspersJS' selector page, but must be doing something wrong. None of the following work for me (all enclosed in ""):
div#myid[text()='sometext']
div#myid[text='sometext']
div#myid[text=sometext]
div#myid:contains('sometext')
div#myid:contains(sometext)
Any pointers as to how I can select a specific element based on it's text value?
Try:
var x = require('casper').selectXPath;
this.test.assertExists(x('//*[#id="myid"][text()="sometext"]'), 'the element exists');
Thanks for the comments above - I ended up going with using jQuery (as it was being loaded on the client) through evaluate() calls in the CasperJS tests.

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