I am trying to write a simple code to go to rpachallenge.com, switch to the Movie Search Tab, search for a movie, then download the three resulting movies' title card image, title, and description to a JSON file. So far I'm able to do everything up to and including searching, but I'm unable to find a unique valid locator for the title cards.
When I inspect the page, each of the three resulting movies has code like the following:
<div _ngcontent-c3 class="cardItem">
<div _ngcontent-3 class="col s4 ">
<!--bindings={"ng-reflect-ng-if":"/d5NXSklXo0qyIYkgV94XAgMIckC.j"}-->
<div _ngcontent-c3 class="card col s12"> =
<div _ngcontent-c3 class="card-image">
<img _ngcontent-c3 src="http://image.tmdb.org/t/p/w500//d5NXSklXo0qyIYkgV94XAgMIckC.jpg">
<!--bindings={ "ng-reflect-ng-if": "true" >-->
...
</div>
<div _ngcontent-c3 class="card-content">
<span _ngcontent-c3 class="card-title activator">Dune </span> =
...
<p _ngcontent-c3> Paul Atreides, a brilliant and gifted young man born into a great dest...</p>
</div>
</div>
</div>
</div>
where all of the code is the same except (d5NXSklXo0qyIYkgV94XAgMIckC.j), the image source (http://image.tmdb.org/t/p/w500//d5NXSklXo0qyIYkgV94XAgMIckC.jpg), movie title (Dune), and shortened movie description (Paul Atreides, a brilliant...).
When I try locating the image using its class="card-image", I get the error
WebDriverException: ... {"code":-32000,"message":"Cannot take screenshot with 0 height."}
After looking into it, I see that I get this error because multiple elements are tagged this way. However, I cannot find a unique locator for the title card image or any of the other elements I am looking for, as all three of the movies that show up look like they have the same code.
I think this should be doable with keywords from the Selenium Library but I am brand new to this and couldn't find what I needed. Here is my code, including some things that I have tried and commented out. As you can see I have no idea what I'm doing... Any help would be much appreciated.
*** Settings ***
Documentation Searches for given movie on RPA Challenge site
... and saves resulting data in JSON.
Library OperatingSystem
Library RPA.Browser.Selenium
Suite Teardown Close All Browsers
*** Variables ***
${RPA_Challenge_URL} https://rpachallenge.com
${img_URL} http://image.tmdb.org
${movie} Dune
*** Keywords ***
Open RPA Challenge Page
${use_chrome} = Get Environment Variable USE_CHROME ${EMPTY}
IF "${use_chrome}" != ""
Open Available Browser ${RPA_Challenge_URL} browser_selection=Chrome
... download=${True} # forces Chrome and matching webdriver download
ELSE
Open Available Browser ${RPA_Challenge_URL} # opens any available browser
END
Switch to Movie Search Tab
Click Link xpath://a[text()='Movie Search']
Search for Given Movie
Input Text name:searchStr ${movie}
Press Keys name:searchStr ENTER
Wait Until Page Contains Element css:div[class='card-image']
# WebDriverException: ... {"code":-32000,"message":"Cannot take screenshot with 0 height."}
Save Movie Card Image
# Assign ID to Element //ul[@class='card-image' and ./li[contains(., '_ngcontent-c3')]] movie_cover
Capture Element Screenshot css:div[class='card-image']
# Capture Element Screenshot xpath://a[contains(text(), 'image.tmdb.org'.)]
# Capture Element Screenshot xpath://a[tag:img]
# Capture Element Screenshot css:div[class='card-image' and contains(text(), 'image')] # invalid
# Element with locator 'css:div[class='card-title-activator']' not found.
Save Movie Title
Capture Element Screenshot css:div[class='card-title-activator']
# Return JSON
# print(driver.find_element_by_xpath("//div[@id='json']").text)
# Does the above need to go in a .py file?
*** Tasks ***
Return movie information from RPA Challenge site
TRY
Open RPA Challenge Page
Switch to Movie Search Tab
Search for Given Movie
# Save Movie Title
Save Movie Card Image
EXCEPT
${err_ss} = Set Variable ${OUTPUT_DIR}${/}error.png
Capture Page Screenshot ${err_ss}
Fail Checkout the screenshot: ${err_ss}
END
You can use FOR
loop (documentation) to get titles, descriptions etc. I was able to get, for example, all the movie titles as a list with this code:
Get movie titles
# on a 'Search for Movies' page
${mymovietitles} Create List # creates an empty list
${titleselements}= SeleniumLibrary.Get WebElements xpath=//span[@class='card-title activator'] # targets all 3 (Dune) movie titles
FOR ${titleelement} IN @{titleselements}
${title}= SeleniumLibrary.Get Text ${titleelement}
Collections.Append To List ${mymovietitles} ${title}
END
Log To Console My movie titles are ${mymovietitles}
OUTPUT: ...My movie titles are ['Dune', 'Dune', 'Dune: Part Two']
I used SeleniumLibrary
(and Collections library for lists) but you can use similar keywords in RPA.Browser.Selenium
too. Also, make sure the browser window size is big enough for the header menus to be visible.