Skip to main content

_csharp

TL;DR - Show Me The Code

3-work-with-frames/code/csharp/FramesTest.cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

namespace csharp
{
[TestClass]
public class FileUploadTest
{
IWebDriver _driver;

[TestInitialize]
public void SetUp()
{
_driver = new FirefoxDriver();
}

[TestCleanup]
public void TearDown()
{
_driver?.Quit();
}

[TestMethod]
public void Example1()
{
_driver.Navigate().GoToUrl("https://the-internet.herokuapp.com/nested_frames");
_driver.SwitchTo().Frame(_driver.FindElement(By.Name("frame-top")));
_driver.SwitchTo().Frame(_driver.FindElement(By.Name("frame-middle")));
Assert.AreEqual("MIDDLE", _driver.FindElement(By.Id("content")).Text);
}

[TestMethod]
public void Example2()
{
_driver.Navigate().GoToUrl("https://the-internet.herokuapp.com/tinymce");
_driver.SwitchTo().Frame(_driver.FindElement(By.Id("mce_0_ifr")));
IWebElement Editor = _driver.FindElement(By.Id("tinymce"));
string StartText = Editor.Text;
Editor.Clear();
Editor.SendKeys("Hello World!");
string EndText = Editor.Text;
Assert.AreNotEqual(EndText, StartText);

_driver.SwitchTo().DefaultContent();
string HeaderText = _driver.FindElement(By.CssSelector("h3")).Text;
Assert.AreEqual("An iFrame containing the TinyMCE WYSIWYG Editor", HeaderText);
}
}
}

Code Walkthrough

Importing Libraries, Setup and Teardown

Lines 1 to 4 are pulling in our requisite classes for our testing framework (e.g., using Microsoft.VisualStudio.TestTools.UnitTesting;), driving the browser with Selenium (e.g., using OpenQA.Selenium;), and launching an instance of Firefox (e.g., using OpenQA.Selenium.Firefox;).

Next, we'll start our class off with some setup and teardown methods, covered in lines 13 to 23.

Example 1

Line 23 shows our first test. In it, we'll step through an example of nested frames from the-internet.

With Selenium's .SwitchTo() method we can easily switch to the frame we want. When using it for frames (e.g., Driver.SwitchTo().Frame();) it accepts either an ID or name attribute. But in order to get the text of the middle frame (e.g., a frame nested within another frame), we need to switch to the parent frame (e.g., the top frame) first and then switch to the child frame (e.g., the middle frame).

Once we've done that we're able to find the element we need, grab its text, and assert that it's what we expect.

While this example helps illustrate the point of frame switching, it's not very practical.

Example 2

Here is a more likely example you'll run into -- working with a WYSIWYG Editor like TinyMCE. You can see the page we're testing here.

Once the page loads we switch into the frame that contains TinyMCE and...

  • grab the original text and store it
  • clear and input new text
  • grab the new text value
  • assert that the original and new texts are not the same

Keep in mind that if we need to access a part of the page outside the frame we're currently in we'll need to switch to it. Thankfully Selenium has a method that enables us to quickly jump back to the top level of the page -- .DefaultContent();..

Executing the Test

Before executing the test, we need to make sure the required dependencies are declared on the project file (e.g., csharp.csproj in this case).

Toggle to see the csharp.csproj file.
3-work-with-frames/code/csharp/csharp.csproj
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
<PackageReference Include="MSTest.TestAdapter" Version="3.5.2" />
<PackageReference Include="MSTest.TestFramework" Version="3.5.2" />
<PackageReference Include="Selenium.Support" Version="4.24.0" />
<PackageReference Include="Selenium.WebDriver" Version="4.24.0" />
</ItemGroup>

</Project>

Finally, we can run the test by executing dotnet test from the command-line.