I want to test every link on a WEBSITE. I googled a lot but there were only solutions to test every link on a WEBPAGE.
How I wanted to do it:
If the script clicks on a link, the script looks on the new webpage if there is a new link. If there is a new link then the script clicks it and repeats the steps(look and click) untill he cannot find a link. In that case the script navigates back until he finds a new link to click.
Does anyone have a solution for me? I am using Java.
You can use a recursive function to open a link, findElements by Html tag name , and call the function again for each of these links in the list. Be aware that, this can go on for a while, you might run out of memory etc because all web pages normally have links.
I think using jsoup library is a better choice for this purpose than to navigate via UI using Selenium.
For more info please follow this tutorial : https://www.javatpoint.com/jsoup-tutorial :)
Try this code
links = browser.find_elements_by_tag_name('a')
for link in links:
try:
response = requests.head(link.get_attribute('href'), allow_redirects=True)
assert response.status_code in (200, 201, 301, 302, 304, 308)
except Exception as e:
print("Broken link detected " + str(link.get_attribute('href')))
Related
I have some Selenium sessions where, if certain events occurs, I spawn a new browser and leave the old one as is so I later on can manually intervene. The problem is that it is hard to distinguish between such a deserted browser session and the one that is currently running.
Ideally I would like to add a badge to the browser icon that is displayed in the application switcher (cmd-tab) and the dock (but other solutions/suggestions are also welcome, like add something to the name of the browser). Is that possible?
Using Java on a Mac. A solution can be platform specific.
You can use below execute_script (This python code use java equalent)
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get(
"https://stackoverflow.com/questions/9943771/adding-a-favicon-to-a-static-html-page")
head = driver.find_element_by_tag_name("head")
link = driver.find_element_by_css_selector('link[rel="shortcut icon"]')
driver.execute_script('''var link = document.createElement("link");
link.setAttribute("rel", "icon");
link.setAttribute("type", "image/png");
link.setAttribute("href", "https://i.stack.imgur.com/uOtHF.png?s=64&g=1");
arguments[1].remove();
arguments[0].appendChild(link);
''',head,link)
time.sleep(70000)
you can use link element on head tag to add favicon. THe above code is an exaple where stackoverflow site will showup with my avatar
Output:
You should find the current link the website uses, remove it and replace it with your new link as shown in the code
// opening the base URL
driver1.get(baseUrl+"/");
// opening a new tab
driver1.findElement(By.cssSelector("Body")).sendKeys(Keys.COMMAND + "t");
driver1.get("my URL");
// getting back to the first tab
driver1.findElement(By.cssSelector("body")).sendKeys(Keys.COMMAND, Keys.SHIFT, "{");
// I want to signup by clicking the sign up button
driver1.findElement(By.xpath("/html/body/div[1]/header/div[2]/button")).click();
The error that I get after running is :
"Error communicating with the remote browser. It may have died."
But when I run the same code without the navigation, the button click works fine, then it means there is no problem with the xpath.
The information which browser you are using would be very interesting. And the webdriver doesn't need to control the visbile Tab. So i wouldn't let the Browser change the Tab and I would use the "switchTo" Method of the webdriver.
More information to this topic is here.
As #Kikkirej mentuined, i see no reason to use sendKeys to switch between opened tabs. Use Selenium instead, it is a much better approach.
Edit: in addition, try to provide more information, especially the most basic part - the browser you are automating.
I am trying to retrieve a JSON element, the problem is that in the source code it doesn't exist, but I can find it via inspect element.
I have tried with
C.driver.findElement(By.id("ticket-parsed"))
and via XPath
C.driver.findElement(By.xpath("//*[#id=\"ticket_parsed\"]"));
and I can't find it.
Also
C.driver.switchTo().frame("html5-frame");
System.out.println(C.driver.findElement(By.id("ticket_parsed")));
C.driver.switchTo().defaultContent();
i get
[[ChromeDriver: chrome on XP (1f75e50635f9dd5b9535a149a027a447)] -> id: ticket_parsed]
on
driver.switchTo().frame(0) or driver.switchTo().frame(1)
i get that the frame doesn't exists
and at last i tried
WebElement frame = C.driver.findElement(By.id("html5-frame"));
C.driver.switchTo().frame(frame.getAttribute("ticket_parsed"));
an i got a null pointer exception
Here's an image of the source:
what am I doing wrong?
Well!
The element #ticket-parsed is in iFrame. So, you can click it without getting into an iframe.
Here is the code to switch to iFrame,
driver.switchTo().frame("frame_name");
or
driver.switchTo().frame(frame_index);
In your case,
driver.switchTo().frame("html5-frame");
After switching into the iframe, you can click that element using either XPath or CSS.
C.driver.findElement(By.id("ticket-parsed"))
NOTE:
After completing the operation inside the iframe, you have to again return back to the main window using the following command.
driver.switchTo().defaultContent();
I didn't found a solution with my excising setup,but i did found a js command which gets the object correctly
document.getElementById("html5-frame").contentDocument.getElementById("ticket_parsed")
you can integrate js commands like this
JavascriptExecutor js=(JavascriptExecutor)driver;
js.executeScript(*yourCommandHere*);
if you want to get the output of the command just add the word return before your command (in this specific situation it didn't work but in any other situation it did)
*TypeOfData* foo = js.executeScript(return *yourCommandHere*);
at last because of limited time i had to use unorthodox methods like taking screenshots and comparing the images if they are exactly the same
Thanks for the help
I have my webpage opened using RFT. In that page, I have a link I want to click.
For that I am using
objMap.ClickTabLink(objMap.document_eBenefitsHome(), "Upload Documentation", "Upload Documentation");
The current page link name is "Upload Documentation"
I know that objMap.document_eBenefitsHome() takes it back to the initial page, what can I use in that place which uses the "current page opened" ?
Many thanks in advance.
There are some alternatives that could solve your problem:
Open the Test Object Map; select from the map the object that represents the document document_eBenefitsHome; modify the .url property using regular expression, so that the URLs of the two pages you cited in your question match the regex.
Find dinamically the document object using the find method. Once the page containing the link you want to click was fully loaded, try to use this code to find the document: find(atDescendant(".class", "Html.HtmlDocument"), false). The false boolean value allow the find method to search also among object that are not previously recorded.
I am using htmlunit in jython and am having trouble selecting a pull down link. The page I am going to has a table with other ajax links, and I can click on them and move around and it seems okay but I can't seem to figure out how to click on a pulldown menu that allows for more links on the page(this pulldown affects the ajax table so its not redirecting me or anything).
Here's my code:
selectField1 = page.getElementById("pageNumSelection")
options2 = selectField1.getOptions()
theOption3 = options2[4]
This gets the option I want, I verify its right. so I select it:
MoreOnPage = selectField1.setSelectedAttribute(theOption3, True)
and I am stuck here(not sure if selecting it works or not because I don't get any message, but I'm not sure what to do next. How do I refresh the page to see the larger list? When clicking on links all you have to do is find the link and then select linkNameVariable.click() into a variable and it works. but I'm not sure how to refresh a pulldown. when I try to use the webclient to create an xml page based on the the select variable, I still get the old page.
to make it a bit easier, I used htmlunit scripter and got some code that should work but its java and I'm not sure how to port it to jython. Here it is:
try
{
page = webClient.getPage( url );
HtmlSelect selectField1 = (HtmlSelect) page.getElementById("pageNumSelection");
List<HtmlOption> options2 = selectField1.getOptions();
HtmlOption theOption3 = null;
for(HtmlOption option: options2)
{
if(option.getText().equals("100") )
{
theOption3 = option;
break;
}
}
selectField1.setSelectedAttribute(theOption3, true );
Have a look at HtmlForm getSelectedByName
HtmlSelect htmlSelect = form.getSelectByName("stuff[1].type");
HtmlOption htmlOption = htmlSelect.getOption(3);
htmlOption.setSelected(true);
Be sure that WebClient.setJavaScriptEnabled is called. The documentation seems to indicate that it is on by default, but I think this is wrong.
Alternatively, you can use WebDriver, which is a framework that supports both HtmlUnit and Selenium. I personally find the syntax easier to deal with than HtmlUnit.
If I understand correctly, the selection of an option in the select box triggers an AJAX calls which, once finished, modifies some part of the page.
The problem here is that since AJAX is, by definition, asynchronous, you can't really know when the call is finished and when you may inspect the page again to find the new content.
HtmlUnit has a class named NicelyResynchronizingAjaxController, which you can pass an instance of to the WebClient's setAjaxController method. As indicated in the javadoc, using this ajax controller will automatically make the asynchronous calls coming from a direct user interaction synchronous instead of asynchronous. Once the setSelectedAttribute method is called, you'll thus be able to see the changed made to the original page.
The other option is to use WebClient's waitForBackgrounfJavascript method after the selection is done, and inspect he page once the background JavaScript has ended, or the timeout has been reached.
This isn't really an answer to the question because I've not used HtmlUnit much before, but you might want to look at Selenium, and in particular Selenium RC. With Selenium RC you are able to control the interactions with a page displayed in a native browser (Firefox for example). It has developer API's for Java and Python amongst others.
I understand that HtmlUnit uses its own javascript and web browser rendering engine and I'm wondering whether that may be a problem.