Skip to content

Commit

Permalink
Browser tab management +semver: feature (#172)
Browse files Browse the repository at this point in the history
* add BrowserTabNavigation with unuit tests

* move js scripts to files
add possibility to open url in new tab with test

* #168 fix review issues

* #168 fix review comments

* #168 SwitchToTab -> SwitchToTab

* #168 SwitchToTab -> SwitchToLastTab
  • Loading branch information
knysh authored Apr 14, 2020
1 parent a013095 commit 075c2da
Show file tree
Hide file tree
Showing 12 changed files with 357 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
<EmbeddedResource Include="Resources\JavaScripts\GetViewPortCoordinates.js" />
<EmbeddedResource Include="Resources\JavaScripts\IsPageLoaded.js" />
<EmbeddedResource Include="Resources\JavaScripts\MouseHover.js" />
<EmbeddedResource Include="Resources\JavaScripts\OpenInNewTab.js" />
<EmbeddedResource Include="Resources\JavaScripts\ScrollBy.js" />
<EmbeddedResource Include="Resources\JavaScripts\ScrollToBottom.js" />
<EmbeddedResource Include="Resources\JavaScripts\ScrollToElement.js" />
Expand All @@ -56,6 +57,7 @@
<EmbeddedResource Include="Resources\JavaScripts\SelectComboBoxValueByText.js" />
<EmbeddedResource Include="Resources\JavaScripts\SetFocus.js" />
<EmbeddedResource Include="Resources\JavaScripts\SetInnerHTML.js" />
<EmbeddedResource Include="Resources\JavaScripts\OpenNewTab.js" />
<EmbeddedResource Include="Resources\JavaScripts\SetValue.js" />
<EmbeddedResource Include="Resources\Localization\en.json" />
<EmbeddedResource Include="Resources\Localization\ru.json" />
Expand Down
9 changes: 9 additions & 0 deletions Aquality.Selenium/src/Aquality.Selenium/Browsers/Browser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,15 @@ private INavigation Navigate()
return new BrowserNavigation(Driver);
}

/// <summary>
/// Provide interface to manage of browser tabs.
/// </summary>
/// <returns>instance of IBrowserTabNavigation.</returns>
public IBrowserTabNavigation Tabs()
{
return new BrowserTabNavigation(Driver);
}

/// <summary>
/// Handles alert.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using Aquality.Selenium.Core.Localization;
using OpenQA.Selenium.Remote;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Aquality.Selenium.Browsers
{
public class BrowserTabNavigation : IBrowserTabNavigation
{
private readonly RemoteWebDriver driver;

internal BrowserTabNavigation(RemoteWebDriver driver)
{
this.driver = driver;
}

private ILocalizedLogger Logger => AqualityServices.LocalizedLogger;

public string CurrentTabHandle
{
get
{
Logger.Info("loc.browser.get.tab.handle");
return driver.CurrentWindowHandle;
}
}

public IList<string> TabHandles
{
get
{
Logger.Info("loc.browser.get.tab.handles");
return driver.WindowHandles;
}
}

public void CloseTab()
{
Logger.Info("loc.browser.tab.close");
driver.Close();
}

public void OpenNewTab(bool switchToNew = true)
{
Logger.Info("loc.browser.tab.open.new");
AqualityServices.Browser.ExecuteScript(JavaScript.OpenNewTab);
if (switchToNew)
{
SwitchToLastTab();
}
}

public void OpenInNewTab(string url)
{
AqualityServices.Browser.ExecuteScript(JavaScript.OpenInNewTab, url);
}

public void SwitchToLastTab(bool closeCurrent = false)
{
Logger.Info("loc.browser.switch.to.new.tab");
CloseAndSwitch(TabHandles.Last(), closeCurrent);
}

public void SwitchToTab(string handle, bool closeCurrent = false)
{
Logger.Info("loc.browser.switch.to.tab.handle", handle);
CloseAndSwitch(handle, closeCurrent);
}

public void SwitchToTab(int index, bool closeCurrent = false)
{
Logger.Info("loc.browser.switch.to.tab.index", index);
var names = TabHandles;
if (index < 0 || names.Count <= index)
{
throw new IndexOutOfRangeException(
$"Index of browser tab '{index}' you provided is out of range {0}..{names.Count}");
}

var newTab = names.ElementAt(index);
CloseAndSwitch(newTab, closeCurrent);
}

private void CloseAndSwitch(string name, bool closeCurrent)
{
if (closeCurrent)
{
CloseTab();
}

driver.SwitchTo().Window(name);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using System.Collections.Generic;

namespace Aquality.Selenium.Browsers
{
/// <summary>
/// Provides functionality to work with browser tab navigation.
/// </summary>
public interface IBrowserTabNavigation
{
/// <summary>
/// Gets current tab handle.
/// </summary>
/// <returns>Current tab handle.</returns>
string CurrentTabHandle { get; }

/// <summary>
/// Gets opened tab handles.
/// </summary>
/// <returns>List of tab handles.</returns>
IList<string> TabHandles { get; }

/// <summary>
/// Switches to tab.
/// </summary>
/// <param name="name">Tab handle.</param>
/// <param name="closeCurrent">Close current tab if true and leave it otherwise.</param>
void SwitchToTab(string tabHandle, bool closeCurrent = false);

/// <summary>
/// Switches to tab.
/// </summary>
/// <param name="index">Tab index.</param>
/// <param name="closeCurrent">Close current tab if true and leave it otherwise.</param>
void SwitchToTab(int index, bool closeCurrent = false);

/// <summary>
/// Switches to the last tab.
/// </summary>
/// <param name="closeCurrent">Close current tab if true and leave it otherwise.</param>
void SwitchToLastTab(bool closeCurrent = false);

/// <summary>
/// Closes curent tab.
/// </summary>
void CloseTab();

/// <summary>
/// Opens new tab.
/// </summary>
/// <param name="switchToNew">Switches to new tab if true and stays at current otherwise.</param>
void OpenNewTab(bool switchToNew = true);

/// <summary>
/// Navigates to desired url in new tab.
/// </summary>
/// <param name="url">String representation of URL.</param>
void OpenInNewTab(string url);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ public enum JavaScript
SetFocus,
SetInnerHTML,
SetValue,
GetViewPortCoordinates
GetViewPortCoordinates,
OpenNewTab,
OpenInNewTab
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
window.open(arguments[0]);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
window.open();
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,12 @@
"loc.waitinvisible": "Wait until element is not visible",
"loc.waitnotexists": "Wait until element does not exist in DOM during {0} seconds",
"loc.no.elements.found.in.state": "No elements with locator '{0}' found in {1} state",
"loc.elements.were.found.but.not.in.state": "Elements were found by locator '{0}'. But {1}"
"loc.elements.were.found.but.not.in.state": "Elements were found by locator '{0}'. But {1}",
"loc.browser.switch.to.tab.handle": "Switching to tab by handle '{0}'",
"loc.browser.switch.to.tab.index": "Switching to tab by index '{0}'",
"loc.browser.switch.to.new.tab": "Switching to new tab",
"loc.browser.get.tab.handles": "Getting tab handles",
"loc.browser.get.tab.handle": "Getting current tab handle",
"loc.browser.tab.open.new": "Opening new tab",
"loc.browser.tab.close": "Closing tab"
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,12 @@
"loc.waitinvisible": "Ожидаем пока элемент исчезнет",
"loc.waitnotexists": "Ожидаем исчезновения элемента из DOM в течении {0}",
"loc.no.elements.found.in.state": "Не удалось найти элементов по локатору '{0}' в {1} состоянии",
"loc.elements.were.found.but.not.in.state": "Удалось найти элементы по локатору '{0}'. Но {1}"
"loc.elements.were.found.but.not.in.state": "Удалось найти элементы по локатору '{0}'. Но {1}",
"loc.browser.switch.to.tab.handle": "Переключение на новую вкладку по дескриптору '{0}'",
"loc.browser.switch.to.tab.index": "Переключение на новую вкладку по индексу '{0}'",
"loc.browser.switch.to.new.tab": "Переключение на новую вкладку",
"loc.browser.get.tab.handles": "Получение списка дескрипторов открытых вкладок",
"loc.browser.get.tab.handle": "Получение дескриптора текущей вкладки",
"loc.browser.tab.open.new": "Открытие новой вкладки",
"loc.browser.tab.close": "Закрытие вкладки"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
using System;
using Aquality.Selenium.Browsers;
using Aquality.Selenium.Tests.Integration.TestApp.TheInternet.Forms;
using NUnit.Framework;
using System.Linq;

namespace Aquality.Selenium.Tests.Integration
{
internal class BrowserTabsTests : UITest
{
private readonly WelcomeForm WelcomeForm = new WelcomeForm();

[SetUp]
public void Before()
{
AqualityServices.Browser.GoTo(WelcomeForm.Url);
}

[Test]
public void Should_BePossibleTo_OpenUrlInNewTab()
{
var url = new WelcomeForm().Url;
var browser = AqualityServices.Browser;
browser.Tabs().OpenInNewTab(url);
browser.Tabs().SwitchToLastTab();
Assert.AreEqual(2, browser.Tabs().TabHandles.Count);
Assert.AreEqual(browser.Driver.Url, url);
}

[Test]
public void Should_BePossibleTo_HandleTab()
{
var browser = AqualityServices.Browser;
var tabHandle = browser.Tabs().CurrentTabHandle;
Assert.IsNotEmpty(tabHandle, "Tab name should not be empty");
}

[Test]
public void Should_BePossibleTo_GetTabHandles()
{
var browser = AqualityServices.Browser;
var tabHandles = browser.Tabs().TabHandles;
Assert.AreEqual(1, tabHandles.Count, "Tab number should be correct");
Assert.IsNotEmpty(tabHandles.First(), "Tab handle should not be empty");
}

[Test]
public void Should_BePossibleTo_OpenNewTab()
{
var browser = AqualityServices.Browser;
var tabHandle = browser.Tabs().CurrentTabHandle;

browser.Tabs().OpenNewTab();
var newTabHandle = browser.Tabs().CurrentTabHandle;
Assert.AreEqual(2, browser.Tabs().TabHandles.Count, "New tab should be opened");
Assert.AreNotEqual(tabHandle, newTabHandle, "Browser should be switched to new tab");

browser.Tabs().OpenNewTab(false);
Assert.AreEqual(3, browser.Tabs().TabHandles.Count, "New tab should be opened");
Assert.AreEqual(newTabHandle, browser.Tabs().CurrentTabHandle, "Browser should not be switched to new tab");
}

[Test]
public void Should_BePossibleTo_CloseTab()
{
var browser = AqualityServices.Browser;
WelcomeForm.ClickElementalSelenium();
Assert.AreEqual(2, browser.Tabs().TabHandles.Count, "New tab should be opened");
browser.Tabs().CloseTab();
Assert.AreEqual(1, browser.Tabs().TabHandles.Count, "New tab should be closed");
}

[Test]
public void Should_BePossibleTo_SwitchToNewTab()
{
CheckSwitchingBy(2, () =>
{
AqualityServices.Browser.Tabs().SwitchToLastTab();
});
}

[Test]
public void Should_BePossibleTo_SwitchToNewTab_AndClose()
{
CheckSwitchingBy(1, () =>
{
AqualityServices.Browser.Tabs().SwitchToLastTab(true);
});
}

[Test]
public void Should_BePossibleTo_SwitchToNewTabByHandle()
{
CheckSwitchingBy(3, () =>
{
var browser = AqualityServices.Browser;
var tabHandle = browser.Tabs().TabHandles.Last();
browser.Tabs().OpenNewTab(false);
browser.Tabs().SwitchToTab(tabHandle);
});
}

[Test]
public void Should_BePossibleTo_SwitchToNewTabByHandle_AndClose()
{
CheckSwitchingBy(2, () =>
{
var browser = AqualityServices.Browser;
var tabHandle = browser.Tabs().TabHandles.Last();
browser.Tabs().OpenNewTab(false);
browser.Tabs().SwitchToTab(tabHandle, true);
});
}

[Test]
public void Should_BePossibleTo_SwitchToNewTabByIndex()
{
CheckSwitchingBy(3, () =>
{
AqualityServices.Browser.Tabs().OpenNewTab(false);
AqualityServices.Browser.Tabs().SwitchToTab(1);
});
}

[Test]
public void Should_BePossibleTo_SwitchToNewTabByIndex_AndClose()
{
CheckSwitchingBy(2, () =>
{
AqualityServices.Browser.Tabs().OpenNewTab(false);
AqualityServices.Browser.Tabs().SwitchToTab(1, true);
});
}

[Test]
public void Should_BeThrow_IfSwitchToNewTab_ByIncorrectIndex()
{
Assert.Throws(typeof(IndexOutOfRangeException), () => { AqualityServices.Browser.Tabs().SwitchToTab(10, true); });
}

private void CheckSwitchingBy(int expectedTabCount, Action switchMethod)
{
var browser = AqualityServices.Browser;
var tabHandle = browser.Tabs().CurrentTabHandle;
WelcomeForm.ClickElementalSelenium();
var newTabHandle = browser.Tabs().TabHandles.Last();
switchMethod.Invoke();
Assert.AreEqual(newTabHandle, browser.Tabs().CurrentTabHandle, "Browser should be switched to correct tab");
Assert.AreEqual(expectedTabCount, browser.Tabs().TabHandles.Count, "Number of tabs should be correct");
}

private void CheckSwitching(int expectedTabCount, Action switchMethod)
{
var browser = AqualityServices.Browser;
var tabHandle = browser.Tabs().CurrentTabHandle;
WelcomeForm.ClickElementalSelenium();
switchMethod.Invoke();
var newTabHandle = browser.Tabs().CurrentTabHandle;
Assert.AreNotEqual(tabHandle, newTabHandle, "Browser should be switched to new tab");
Assert.AreEqual(expectedTabCount, browser.Tabs().TabHandles.Count, "Number of tabs should be correct");
}
}
}
Loading

0 comments on commit 075c2da

Please sign in to comment.