Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

selenium tests, only works in VB I think, but the tests work at least #47

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"jsonld": "^0.4.5",
"material-ui": "^0.20.0",
"n3": "^0.11.2",
"nuget": "^2.0.1",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this actually useful or is this just dead code?

Installing NuGet as a separate global dependency shouldn't be a problem at all for people who already installed a C# compiler and an MSBuild-like build system. But maybe you've got a different perspective on that and this line is warranted anyway.

Regardless, please don't put NuGet in the package.json's "dependencies"—if you really do need it, put it in the "devDependencies".

"rdflib": "^0.15",
"react": "^16.2.0",
"react-dom": "^16.2.0",
Expand Down
Binary file added selenium/.vs/selenium/DesignTimeBuild/.dtbcache
Binary file not shown.
Binary file added selenium/.vs/selenium/v15/.suo
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
7 changes: 4 additions & 3 deletions selenium/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ public static class Program
/// <summary>
/// A sequence of all test cases to run.
/// </summary>
private static readonly IEnumerable<TestCase> TestCases = SanityChecks.All;
private static ICollection<TestCase> TestCases = UploadFileTests.All;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why'd you use ICollection<TestCase> here? Shared mutable collections are kind of bad. Consider using IReadOnlyCollection<TestCase> or even IReadOnlyList<TestCase>. Or better yet: IEnumerable<TestCase>, as before.

Also, why exclude the sanity check tests? You can include them like so:

using System.Linq;

// ...

private static readonly IEnumerable<TestCase> TestCases =
    SanityChecks.All
    .Concat(UploadFileTests.All);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might also want to include all the other tests here.


public static int Main(string[] args)
{
// Acquire a log for printing output.
var rawLog = new RecordingLog(TerminalLog.Acquire());
var rawLog = new RecordingLog();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why'd you change this? This'll secretly eat up all error messages, making it impossible to tell what happened when something went wrong. The tests will still fail by exiting with a nonzero exit code, but that will be obscured now.


// Create a derived log for printing diagnostics.
var log = CreateDiagnosticLog(rawLog);
Expand Down Expand Up @@ -78,7 +78,8 @@ public static int Main(string[] args)
return 0;
}

string testUrl = parsedOptions.GetValue<string>(Options.Url);
//string testUrl = parsedOptions.GetValue<string>(Options.Url);
string testUrl = "http://192.168.1.12:5000";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this back. You can specify http://192.168.1.12:5000 as a command-line argument in the project configuration. Here's a relevant StackOverflow question.

bool noUrl = string.IsNullOrWhiteSpace(testUrl);

if ((noUrl && !parsedOptions.ContainsOption(Options.BuildApplication))
Expand Down
7 changes: 6 additions & 1 deletion selenium/SeleniumTests.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
Expand Down Expand Up @@ -31,6 +31,7 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Windows.Forms" />
<Reference Include="WebDriver">
<HintPath>packages\Selenium.WebDriver.3.11.2\lib\net45\WebDriver.dll</HintPath>
</Reference>
Expand All @@ -48,7 +49,11 @@
<Compile Include="Options.cs" />
<Compile Include="TestCase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tests\EditGraphTests.cs" />
<Compile Include="Tests\GraphTests.cs" />
<Compile Include="Tests\Help.cs" />
<Compile Include="Tests\SanityChecks.cs" />
<Compile Include="Tests\UploadFileTests.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="packages\Selenium.WebDriver.GeckoDriver.0.20.1\build\Selenium.WebDriver.GeckoDriver.targets" Condition="Exists('packages\Selenium.WebDriver.GeckoDriver.0.20.1\build\Selenium.WebDriver.GeckoDriver.targets')" />
Expand Down
66 changes: 66 additions & 0 deletions selenium/Tests/EditGraphTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System.Collections.Generic;
using OpenQA.Selenium;
using System;
using System.Windows.Forms;

namespace SeleniumTests.Tests
{
class EditGraphTests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These test classes contain public static members only. Consider making the classes themselves public static as well.

{
public static readonly TestCase DeleteSHACLShape =
new TestCase(
"SHACL shapes can be deleted",
(driver, log) =>
{
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
//Log in
driver.Login();
String currentPath = System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.FullName;
String path = currentPath + @"\testfiles\demo_shacl.ttl";
//Open a SHACL file
driver.OpenFile(path);
IWebElement shaclElement = driver.FindElement(By.XPath("//*[contains(text(),'PersonShape')]"), 10);
shaclElement.Click();
SendKeys.SendWait("{DEL}");
System.Threading.Thread.Sleep(500);
try
{
IReadOnlyCollection<IWebElement> elements = driver.FindElements(By.Id(shaclElement.GetAttribute("Id")));
Assert.IsTrue(elements.Count == 0);
}
catch (StaleElementReferenceException) {
Assert.IsTrue(true);
}
});

public static readonly TestCase DeleteDataShape =
new TestCase(
"Data shapes can be deleted",
(driver, log) =>
{
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
//Log in
driver.Login();
String currentPath = System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.FullName;
String path = currentPath + @"\testfiles\demo_data_conforming.ttl";
//Open a SHACL file
driver.OpenFile(path);
var dataElement = driver.FindElement(By.XPath("//*[contains(text(),'ex:Alice')]"), 10);
dataElement.Click();
SendKeys.SendWait("{DEL}");
System.Threading.Thread.Sleep(500);
try
{
bool b = dataElement.Displayed;
Assert.IsTrue(false);
}
catch (OpenQA.Selenium.StaleElementReferenceException) { }
});

public static readonly ICollection<TestCase> All =
new[]
{
DeleteSHACLShape
};
}
}
27 changes: 27 additions & 0 deletions selenium/Tests/GraphTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Collections.Generic;
using OpenQA.Selenium;
using System;

namespace SeleniumTests.Tests
{
class GraphTests
{

public static readonly TestCase DeleteSHACLProperty =
new TestCase(
"SHACL properties can be deleted",
(driver, log) =>
{
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
//Log in
driver.Login();
String currentPath = System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.FullName;
String path = currentPath + @"\testfiles\demo_shacl.ttl";
//Open a SHACL file
driver.OpenFile(path);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the following getting duplicated over and over again.

String currentPath = System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.FullName;
String path = currentPath + @"\testfiles\demo_shacl.ttl";
// Open a SHACL file
driver.OpenFile(path);

You might want to refactor that pattern into a specialized (extension?) method, so you can just call driver.OpenTestFile("demo_shacl.ttl"); Also see my comment below w.r.t. the Windows-style paths: you should use Path.Combine instead.

var shaclElement = driver.FindElement(By.XPath("//*[contains(text(),'sh:targetClass')]"), 10);
Assert.IsTrue(shaclElement.Text == "sh:targetClass : ex:Person");
});

}
}
65 changes: 65 additions & 0 deletions selenium/Tests/Help.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.Collections.Generic;
using OpenQA.Selenium;
using System.Windows.Forms;
using OpenQA.Selenium.Interactions;
using System;
using OpenQA.Selenium.Support.UI;

namespace SeleniumTests.Tests
{
static class Help
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe rename this class to WebDriverHelpers to better express what's going on here.

{

public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds)
{
if (timeoutInSeconds > 0)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
return wait.Until(drv => drv.FindElement(by));
}
return driver.FindElement(by);
}

public static IReadOnlyCollection<IWebElement> FindElements(this IWebDriver driver, By by, int timeoutInSeconds)
{
if (timeoutInSeconds > 0)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
return wait.Until(drv => drv.FindElements(by));
}
return driver.FindElements(by);
}

public static void DoubleClick(this IWebDriver driver, IWebElement element)
{
Actions action = new Actions(driver);
action.DoubleClick(element);
action.Perform();
}

public static void Login(this IWebDriver driver)
{
var elem = driver.FindElement(By.Id("homeLoginButton"));
elem.Click();
Assert.IsTrue(driver.Url.EndsWith("#/login"));
driver.FindElement(By.Id("formUsernameField")).SendKeys("username");
driver.FindElement(By.Id("formPasswordField")).SendKeys("password");
var login = driver.FindElement(By.Id("formLoginButton"));
login.Click();
}

public static void OpenFile(this IWebDriver driver, String path)
{
var fileMenu = driver.FindElement(By.Id("openFileMenu"), 10);
fileMenu.Click();
var localGraph = driver.FindElement(By.Id("openLocalGraphButton"), 10);
localGraph.Click();
var shaclGraph = driver.FindElement(By.Id("openSHACLGraphButton"), 10);
shaclGraph.Click();
SendKeys.SendWait(path);
System.Threading.Thread.Sleep(500);
SendKeys.SendWait(@"{Enter}");
System.Threading.Thread.Sleep(1000);
}
}
}
17 changes: 15 additions & 2 deletions selenium/Tests/SanityChecks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,27 @@ public static class SanityChecks
Assert.IsTrue(driver.Url.EndsWith("#/about"));
});

public static readonly TestCase LoginWorks =
new TestCase(
"Login page can be accessed",
(driver, log) =>
{
//Log in
driver.Login();
// Check that we're at '#/user' after logging in.
Assert.IsTrue(driver.Url.EndsWith("#/user"));

});

/// <summary>
/// A list of all sanity check tests.
/// </summary>
public static readonly IEnumerable<TestCase> All =
public static readonly ICollection<TestCase> All =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why'd you change this to ICollection<TestCase>? Shared mutable collections are kind of bad. Consider using IReadOnlyCollection<TestCase> or even IReadOnlyList<TestCase>.

new[]
{
CheckTitle,
AboutWorks
AboutWorks,
LoginWorks
};
}
}
Empty file added selenium/Tests/UploadFile.cs
Empty file.
50 changes: 50 additions & 0 deletions selenium/Tests/UploadFileTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System.Collections.Generic;
using OpenQA.Selenium;
using System;

namespace SeleniumTests.Tests
{
class UploadFileTests
{
public static readonly TestCase UploadSHACLFile =
new TestCase(
"SHACL files can be uploaded",
(driver, log) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation seems kind of off here. Can you reformat this lambda?

{
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
//Log in
driver.Login();
String currentPath = System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.FullName;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not insert a using System.IO; directive at the top of the file and drop the qualifiers here? Directory.GetParent is just as clear as System.IO.Directory.GetParent and a lot shorter.

String path = currentPath + @"\testfiles\demo_shacl.ttl";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use string path = Path.Combine(currentPath, "testfiles", "demo_shacl.ttl"); instead of string concatenation. Windows' zany backslashes are not recognized as directory separators anywhere else. So the CI build won't succeed until you fix this.

//Open a SHACL file
driver.OpenFile(path);
var shaclElement = driver.FindElement(By.XPath("//*[contains(text(),'sh:targetClass')]"), 10);
Assert.IsTrue(shaclElement.Text == "sh:targetClass : ex:Person");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using Assert.AreEqual(shaclElement.Text, "sh:targetClass : ex:Person"); to better express your intent (and get a prettier error message).

});

public static readonly TestCase UploadDataFile =
new TestCase(
"Data files can be uploaded",
(driver, log) =>
{
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
//Log in
driver.Login();
String currentPath = System.IO.Directory.GetParent(System.IO.Directory.GetCurrentDirectory()).Parent.FullName;
String path = currentPath + @"\testfiles\demo_data_conforming.ttl";
//Open a SHACL file
driver.OpenFile(path);
var dataElement = driver.FindElement(By.XPath("//*[contains(text(),'ex:Alice')]"), 10);
Assert.IsTrue(dataElement.Text == "ex:Alice");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use Assert.AreEqual here instead. Same reasoning as above.

});

public static readonly ICollection<TestCase> All =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why'd you use ICollection<TestCase> here? Shared mutable collections are kind of bad. Consider using IReadOnlyCollection<TestCase> or even IReadOnlyList<TestCase>.

new[]
{
UploadSHACLFile,
UploadDataFile
};
}
}


8 changes: 8 additions & 0 deletions selenium/testfiles/demo_data_conforming.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix sh: <http://www.w3.org/ns/shacl#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix ex: <http://example.com/ns#>.

ex:Alice a ex:Person ;
ex:ssn "987-65-432" .
9 changes: 9 additions & 0 deletions selenium/testfiles/demo_data_non-conforming.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix sh: <http://www.w3.org/ns/shacl#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix ex: <http://example.com/ns#>.
ex:Bob
a ex:Person ;
ex:ssn "123-45-6789" ;
ex:ssn "124-35-6789" .
22 changes: 22 additions & 0 deletions selenium/testfiles/demo_shacl.ttl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix sh: <http://www.w3.org/ns/shacl#>.
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.
@prefix ex: <http://example.com/ns#>.

ex:PersonShape
a sh:NodeShape ;
sh:targetClass ex:Person ;
sh:property [
sh:path ex:ssn ;
sh:maxCount 1 ;
sh:datatype xsd:string ;
sh:pattern "^\\d{3}-\\d{2}-\\d{4}$" ;
] ;
sh:property [
sh:path ex:worksFor ;
sh:class ex:Company ;
sh:nodeKind sh:IRI ;
] ;
sh:closed true ;
sh:ignoredProperties ( rdf:type ) .
2 changes: 2 additions & 0 deletions src/components/containerHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class HomeContainer extends React.Component {
style={{color: 'white'}}
>
<Button
id="homeLoginButton"
inverted={true}
color="teal"
size="huge"
Expand All @@ -65,6 +66,7 @@ class HomeContainer extends React.Component {
style={{color: 'white'}}
>
<Button
id="homeSignUpButton"
animated="fade"
inverted={true}
size="huge"
Expand Down
12 changes: 9 additions & 3 deletions src/dropdowns/DropdownFile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,22 @@ class DropdownFile extends React.Component<DropdownFileProps, any> {

render() {
return (
<Dropdown text='File' pointing="top left">
<Dropdown id='openFileMenu' text='File' pointing="top left">
<Dropdown.Menu>
<Dropdown.Item text='New'/>
<Dropdown
id='openLocalGraphButton'
text='Open local graph'
pointing='left'
className='link item'
className="link item"
>
<Dropdown.Menu>
<Dropdown.Item onClick={() => this.props.import_cb("shacl")}> SHACL Graph </Dropdown.Item>
<Dropdown.Item
id='openSHACLGraphButton'
onClick={() => this.props.import_cb("shacl")}
>
SHACL Graph
</Dropdown.Item>
<Dropdown.Item onClick={() => this.props.import_cb("data")}> Data Graph</Dropdown.Item>
</Dropdown.Menu>
</Dropdown>
Expand Down
Loading