Selenium Webdriver : I am not able to switch to iframe - selenium

Here is the code that I have written.I have tried adding thread.sleep() but it still doesn't work also tried with chromedriver but same result
package com.thinksys.frames;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Iframes
{
public static void main(String[] args)
{
System.setProperty("webdriver.gecko.driver","C:\\Users\\thinksysuser\\Downloads\\geckodriver-v0.18.0-win64\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.irctc.co.in/eticketing/loginHome.jsf");
WebElement e = driver.findElement(By.id("google_ads_iframe_/37179215/DFP_NGET_01_HomePage_RHS_ATF_479x266_ENG_0"));
driver.switchTo().frame(e);
driver.findElement(By.xpath(".//*[#id='image-11']/a/img")).click();
}
}

It might caused by the special characters in the <ifram> id. Using partial id will provide two matches, so I suggest you use two portions of the name attribute
WebElement frame = driver.findElement(By.cssSelector("[name*='google_ads_iframe'][name*='DFP_NGET_01_HomePage_RHS']"));
driver.switchTo().frame(frame);
Edit
The images rotates, each on is visible for a few seconds only. To click on a specific image you need to wait for it to be visible. You can use explicit wait for it
WebDriverWait wait = new WebDriverWait(driver, 60, 50);
wait.until(ExpectedConditions.visibilityOfElementLocatedBy.xpath(".//*[#id='image-11']/a/img"))).click();
This will pole the DOM every 100 milliseconds until the image is visible or the time is up (60 seconds).

There is variations on browsers to display ads. I have opened in Firefox and not able to see the ad while its displaying in chrome. and the scenario while i do open the Chrome or Firefox browser using script there is no ad section.
based on this scenario you can check that weather frame is available or not if available then switch into it and wait till the image you gonna click get visible then click on it
You can try this way :
WebDriverWait wait = new WebDriverWait(driver, 120);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(driver.findElement(By.xpath("//iframe[starts-with(#id,'google_ads_iframe')][#title='3rd party ad content']"))));
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//div[#id='image-11']/a/img")))).click();
or
WebDriverWait wait = new WebDriverWait(driver, 120);
List <WebElement> adFrame = driver.findElements(By.xpath("//iframe[starts-with(#id,'google_ads_iframe')][#title='3rd party ad content']"))
if(adFrame.size()>0)
{
driver.switchTo().frame(adFrame.get(0));
wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath("//div[#id='image-11']/a/img")))).click();
}
else
{
System.out.println("Sorry there is no ads");
}

Related

Selenium couldn't find iframe using its id (Java)

I am working on the task from 'Automation on Java' course.
In scope of this task I need to create a test which should interact with elements from this page https://cloud.google.com/products/calculator
I need to create a script which will fill some specific fields from this page.
As I can see there are few iframes on this page.
First of all, I need to fill the 'Number of instances' field.
I see that element which I am interested in (//input[#id='input_90']) is located inside the iframe (id = 'myFrame').
enter image description here
enter image description here
Based on that, I create a method, which should switch me to this iframe using its id value:
public void switchFrameToMyFrame() {
driver.switchTo().frame("myFrame");
}
But when I am trying to run this specific test
#Test
#Order(2)
#DisplayName("Fill Calculation Form")
public void fillCalculationForm() {
driver.get("https://cloud.google.com/products/calculator");
pricingCalculatorPage.switchFrameToMyFrame();
I am getting this error message:
org.openqa.selenium.NoSuchFrameException: No frame element found by name or id myFrame
I tried several approaches how I can swich to another frame:
//using if value of the iframe
driver.switchTo().frame("myFrame");
//using xpath of the element inside the iframe
driver.switchTo().frame(driver.findElement(By.xpath("//input[#id='input_90']")));
//I tried to add this row in case if my test ends before the page iframe is loaded on the page
fluentWait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(myFrame));
//I even tried to create a method which should find the index of the iframe using its id, but seems like it found the wrong index. After I switched to iframe using the index value which I got from this method, driver was not able to find the element inside the iframe. It could be because of the iframe index is wrong
public void findIframeIndex() {
int size = driver.findElements(By.tagName("iframe")).size();
for (int i = 0; i < size; i++) {
driver.switchTo().frame(i);
int total = driver.findElements(By.xpath("//iframe[#id='myFrame']")).size();
System.out.println(total);
driver.switchTo().defaultContent();
}
}
I've read a lot of information about how I can deal with iframes but I didn't found what I need to do in my specific case.
Could anyone help me to understand how I can interact at least with the 'Number of instances' field?
There are 2 iframes (nested iframes), 'Number of instances', and other associated fields inside the second iframe. So you have to switch to the outer iframe and then inner iframe, try the below code:
imports:
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
code:
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(15));
driver.get("https://cloud.google.com/products/calculator");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// switch to the first iframe
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath(".//*[starts-with(#name,'goog_')]")));
// switch to the second iframe
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("myFrame")));
driver.findElement(By.id("input_90")).sendKeys("56");
After entering all the values, you can switch to the first iframe using:
driver.switchTo().defaultContent();
The desired element is within nested iframe so you have to:
Induce WebDriverWait for the first frameToBeAvailableAndSwitchToIt.
Induce WebDriverWait for the second frameToBeAvailableAndSwitchToIt.
Induce WebDriverWait for the desired elementToBeClickable.
You can use the following locator strategies:
import java.time.Duration;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
driver.get("https://cloud.google.com/products/calculator");
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("iframe[src^='https://cloud.google.com/frame/products/calculator']")));
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("myFrame")));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#ng-model='listingCtrl.computeServer.quantity' and #aria-label='quantity' and #name='quantity']"))).sendKeys("4");
Browser Snapshot:

Verify the mouse hover menu items list in Selenium [duplicate]

I tried the below code but it is not mouse hovering and clicking on 'Member login'
WebElement lgn = driver.findElement(By.id("ctl00_HyperLinkLogin"));
WebElement ssm = driver.findElement(By.xpath("//a[contains(text(), 'SpiceCash/SpiceClub Members')]"));
WebElement cgm = driver.findElement(By.xpath("//a[contains(text(),'Member Login')]"));
Actions a1 = new Actions(driver);
a1.moveToElement(lgn).moveToElement(ssm).moveToElement(cgm).click().build().perform();
To invoke click() on the element with text as Member login, first you have to Mouse Hover over the element with text as LOGIN / SIGNUP, then Mouse Hover over the element with text as SpiceCash/SpiceClub Members then induce WebDriverWait for the element with text as Member Login to be clickable and you can use the following solution:
Code Block:
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Spicejet_member_login {
public static void main(String[] args) {
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("http://www.spicejet.com/");
new Actions(driver).moveToElement(new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("a.link#ctl00_HyperLinkLogin")))).build().perform();
new Actions(driver).moveToElement(new WebDriverWait(driver, 5).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//li[#class='hide-mobile']/a[contains(.,'SpiceCash/SpiceClub Members')]")))).build().perform();
new WebDriverWait(driver, 7).until(ExpectedConditions.elementToBeClickable(By.xpath("//li[#class='hide-mobile']//ul/li/a[#href='https://book.spicejet.com/Login.aspx' and contains(.,'Member Login')]"))).click();
}
}
Browser Snapshot:
You can try to add waits between your moveToElement() calls
WebDriverWait wait = new WebDriverWait(WebDriverRunner.getWebDriver(), 10);
wait.until(ExpectedConditions.visibilityOf(element))
where the "element" is your menu that should appear on hover.
Or you can use ready solution Selenide framework which is built on top of the Selenium and has built in hover method and waits which help to handle page dynamics
By this link you can find an example of hover() method usage.

how handle auto suggest in "from" and "destination" box for this website "https://www.goibibo.com/" in selenium

how handle auto suggest in "from" and "destination" box for this website "https://www.goibibo.com/" in selenium.
please help
I tired using the basic method but unable to get the X path of the auto suggestion drop down
Unable to click on the drop down
package basic;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class goibibo {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
WebDriver driver = new ChromeDriver();
driver.get("https://www.goibibo.com/");
new WebDriverWait(driver, 20)
.until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#id='gosuggest_inputSrc']")))
.sendKeys("Mum");
List<WebElement> myList = new WebDriverWait(driver, 20).until(
ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//*[#id=\"react-autosuggest-1\"]")));
for (WebElement element : myList) {
if (element.getText().contains("Mumbai"))
;
element.click();
}
}
}
Chrome Browser
First how to Find XPATH of auto populate box in Chrome Browser open your website than click on Inspect element and click on source Tab now, click for opening your auto populate box and Press **F8** **Key for pause debugger**. Then click on your Element tab and you can easily get your xpath refer below snap for more information. so it will freeze your HTML.
Now click on Elements an Create your own xpath.
Fire Fox Browser
Second how to find xpath of Auto Populate box in Firefox - Open your Firefox and Right click and click on inspect elements on your website. there is option of animation so it will open all your DOM Expanded like below image. so by reading this dom structure you can create easily your XPATH.
Not how to find Elements from auto populate box. Refer below code snippet for that.
package com.software.testing;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Testingclass extends DriverFactory {
private static WebDriver driver = null;
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "your driver path");
driver = new ChromeDriver();
driver.get("https://www.goibibo.com/");
new WebDriverWait(driver, 20)
.until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#id='gosuggest_inputSrc']")))
.sendKeys("A");
Thread.sleep(1000);
List<WebElement> myList = new WebDriverWait(driver, 20).until(ExpectedConditions.presenceOfAllElementsLocatedBy(
By.xpath("//div[#class='dib marginL10 pad0 textOverflow width90']/div/span")));
for (int i = 0; i < myList.size(); i++) {
System.out.println(myList.get(i).getText());
if (myList.get(i).getText().equals("Ahmedabad")) {
myList.get(i).click();
break;
}
}
}
}
Don't forgot to use break after your conditional statement else it
will thrown an exception.
So you can try one solution please find the below screenshot,
As you can see in screenshot if i type M in text box then dropdown shows the record respect to letter 'M' and if you see in source the <ul> which is dynamic as you see just below <input> so you need to handle that dropdown by it's locator it is dynamic hence first you need to pass some text in text box and after that you need to select the element from the drop down using Select in selenium you use selectByVisibleText("") or what ever or you can use List<Element> you can store all the respected sources (Mumbai, Mysore ,etc)coming from dropdown and use it wisely
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#id='gosuggest_inputSrc'"]))).sendKeys("M");
List<WebElement> myList = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("Xpath of the dynamic drop down")));
for (WebElement element:myList) {
if(element.getText().contains("Mumbai"));
element.click();
}
I gave you an idea let me know if you need any further help
I have automated it through selenium with python. Its collecting all suggested cities in a list and then clicking the required one.
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.goibibo.com/")
driver.implicitly_wait(3)
listCity = []
driver.find_element_by_xpath("//input[#id='gosuggest_inputSrc']").send_keys("JA")
cities = driver.find_elements_by_xpath("//div[#class='mainTxt clearfix']//preceding-sibling::span")
for city in cities:
listCity.append(city.text)
for city in cities:
if "Jagdalpur" in city.text:
city.click()
break
print(listCity)
print(len(listCity))
Use below code it will work
Webelement ele=driver.findelement()
Actions ob = new Actions(driver);
ob.moveToElement(ele);
ob.click(ele);
Action action = ob.build();
action.perform();

How to handle calendar for "departure" box and "return" box in Selenium? [duplicate]

how handle auto suggest in "from" and "destination" box for this website "https://www.goibibo.com/" in selenium.
please help
I tired using the basic method but unable to get the X path of the auto suggestion drop down
Unable to click on the drop down
package basic;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class goibibo {
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
WebDriver driver = new ChromeDriver();
driver.get("https://www.goibibo.com/");
new WebDriverWait(driver, 20)
.until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#id='gosuggest_inputSrc']")))
.sendKeys("Mum");
List<WebElement> myList = new WebDriverWait(driver, 20).until(
ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//*[#id=\"react-autosuggest-1\"]")));
for (WebElement element : myList) {
if (element.getText().contains("Mumbai"))
;
element.click();
}
}
}
Chrome Browser
First how to Find XPATH of auto populate box in Chrome Browser open your website than click on Inspect element and click on source Tab now, click for opening your auto populate box and Press **F8** **Key for pause debugger**. Then click on your Element tab and you can easily get your xpath refer below snap for more information. so it will freeze your HTML.
Now click on Elements an Create your own xpath.
Fire Fox Browser
Second how to find xpath of Auto Populate box in Firefox - Open your Firefox and Right click and click on inspect elements on your website. there is option of animation so it will open all your DOM Expanded like below image. so by reading this dom structure you can create easily your XPATH.
Not how to find Elements from auto populate box. Refer below code snippet for that.
package com.software.testing;
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Testingclass extends DriverFactory {
private static WebDriver driver = null;
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "your driver path");
driver = new ChromeDriver();
driver.get("https://www.goibibo.com/");
new WebDriverWait(driver, 20)
.until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#id='gosuggest_inputSrc']")))
.sendKeys("A");
Thread.sleep(1000);
List<WebElement> myList = new WebDriverWait(driver, 20).until(ExpectedConditions.presenceOfAllElementsLocatedBy(
By.xpath("//div[#class='dib marginL10 pad0 textOverflow width90']/div/span")));
for (int i = 0; i < myList.size(); i++) {
System.out.println(myList.get(i).getText());
if (myList.get(i).getText().equals("Ahmedabad")) {
myList.get(i).click();
break;
}
}
}
}
Don't forgot to use break after your conditional statement else it
will thrown an exception.
So you can try one solution please find the below screenshot,
As you can see in screenshot if i type M in text box then dropdown shows the record respect to letter 'M' and if you see in source the <ul> which is dynamic as you see just below <input> so you need to handle that dropdown by it's locator it is dynamic hence first you need to pass some text in text box and after that you need to select the element from the drop down using Select in selenium you use selectByVisibleText("") or what ever or you can use List<Element> you can store all the respected sources (Mumbai, Mysore ,etc)coming from dropdown and use it wisely
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#id='gosuggest_inputSrc'"]))).sendKeys("M");
List<WebElement> myList = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("Xpath of the dynamic drop down")));
for (WebElement element:myList) {
if(element.getText().contains("Mumbai"));
element.click();
}
I gave you an idea let me know if you need any further help
I have automated it through selenium with python. Its collecting all suggested cities in a list and then clicking the required one.
from selenium import webdriver
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.goibibo.com/")
driver.implicitly_wait(3)
listCity = []
driver.find_element_by_xpath("//input[#id='gosuggest_inputSrc']").send_keys("JA")
cities = driver.find_elements_by_xpath("//div[#class='mainTxt clearfix']//preceding-sibling::span")
for city in cities:
listCity.append(city.text)
for city in cities:
if "Jagdalpur" in city.text:
city.click()
break
print(listCity)
print(len(listCity))
Use below code it will work
Webelement ele=driver.findelement()
Actions ob = new Actions(driver);
ob.moveToElement(ele);
ob.click(ele);
Action action = ob.build();
action.perform();

NoSuchElementException: no such element: Unable to locate element while trying to click dropdown element on amazon.co.uk through Selenium

I am running an automated test in selenium/intelliJ/Java. The webdriver is supposed to click the drop down menu on the Amazon nav bar and then click one of the links within the drop down menu. It does both these things correctly, the drop down option leads to its link, however the selenium test itself fails, here is the error:
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"link text","selector":"Full Shop Directory"}
and here is my code:
package com.testing.webdriver;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.junit.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.WebElement;
import java.util.Random;
import java.util.concurrent.TimeUnit;
public class MyFirstTest {
WebDriver driver = new ChromeDriver();
#BeforeClass
public static void setupWebdriver() {
WebDriverManager.chromedriver().setup();
}
private static final By SHOP_BY_DEPARTMENT = By.cssSelector("#nav-link-shopall");
private static final By SHOP_ALL = By.cssSelector("#nav-flyout-shopAll > div.nav-template.nav-flyout-content.nav-tpl-itemList > a");
#Test
public void startWebdriver() {
driver.navigate().to("https://www.amazon.co.uk/");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
WebElement shopByDepartment = driver.findElement(SHOP_BY_DEPARTMENT);
shopByDepartment.click();
WebElement ShopAllNav = driver.findElement(By.linkText("Full Shop Directory"));
ShopAllNav.click();
Assert.assertTrue("matches current url",
driver.getCurrentUrl().matches("https://www.amazon.co.uk/gp/site-directory/ref=nav_shopall_fullstore"));
}
#After
public void breakdown() throws InterruptedException {
Thread.sleep(20000);
driver.close();
}
The test should be passing as it does what I'm telling it. I assume it's something to do with the link being in the drop down menu, as the error says, but I still don't know how I would rectify this.
To expand the Dropdown Menu on the Amazon nav bar you don't need to click() rather Mouse Hover inducing WebDriverWait and you can use the following solution:
Code Block:
System.setProperty("god.bless.you", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
options.addArguments("disable-infobars");
options.addArguments("--disable-extensions");
WebDriver driver = new ChromeDriver(options);
driver.get("https://www.amazon.co.uk/");
new Actions(driver).moveToElement(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div#nav-shop>a#nav-link-shopall")))).perform();
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("div.nav-catFlyout.nav-flyout div.nav-template.nav-flyout-content.nav-tpl-itemList a"))).click();
Assert.assertTrue(driver.getCurrentUrl().matches("https://www.amazon.co.uk/gp/site-directory/ref=nav_shopall_fullstore"));
driver.quit();
Console Output:
Starting ChromeDriver 2.45.615291 (ec3682e3c9061c10f26ea9e5cdcf3c53f3f74387) on port 41299
Only local connections are allowed.
Jan 25, 2019 5:41:24 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
What i have seen at amazon:
'full shop directory' is not (really a link text).
if the element is <a>this is a text</a> then i consider it for link text.
In your case the text is formed with a-lot of white-spaces **********Full Shop Directory********** and this flaky and can cause issues (possible in your case).
Correct your locator to be struct-safe and try again.
Example:
xpath: //a/span[#class='nav-text' and text()='Full Shop Directory']
Update:
Your test is written wrong or no idea what is your actual goal.
What you do:
click on nav menu and same view-page of 'full shop directory' is
getting open. links are different.
click on button from 'shop by department' (which is hidden)
assert urls...
Suggested Steps:
Move to 'shop by department' and trigger the dropdown.
click on 'full shop directory' button from dropdown.
wait for page to load
assert page url.
Code:
driver.navigate().to("https://www.amazon.co.uk/");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
WebElement shopByDepartment = driver.findElement(SHOP_BY_DEPARTMENT);
Actions ac = new Actions(driver);
ac.moveToElement(shopByDepartment).perform();
WebElement ShopAllNav = driver.findElement(By.linkText("Full Shop Directory"));
ShopAllNav.click();
Assert.assertTrue(driver.getCurrentUrl().matches("https://www.amazon.co.uk/gp/site-directory/ref=nav_shopall_fullstore"), "matches current url");
Code has been tested and confirmed as working.
You need to Wait for that particular component to be visible. After Its visibility then you can apply action on it.
You can try the code below.
WebElement ShopAllNav = driver.findElement(By.linkText("Full Shop Directory"));
WebDriverWait wait = new WebDriverWait(driver,200);
wait.until(ExpectedConditions.visibilityOf(ShopAllNav));
ShopAllNav.click();