diff --git a/.gitignore b/.gitignore index 5db06f5..35ddf55 100644 --- a/.gitignore +++ b/.gitignore @@ -3,12 +3,15 @@ # .net packages/ -extentreports-dotnet-core/Program.cs -extentreports-dotnet-core/bin/ +ExtentReports/Program.cs +ExtentReports/bin/ +ExtentReports/obj/ +ExtentReports.Tests/Program.cs +ExtentReports.Tests/bin/ +ExtentReports.Tests/obj/ +KlovReporter/Program.cs +KlovReporter/bin/ +KlovReporter/obj/ +extentreports-dotnet-core/ extentreports-dotnet-core/obj/ -extentreports-dotnet-core/bin/debug/ -extentreports-dotnet-core.Tests/bin/ -extentreports-dotnet-core.Tests/obj/ -extentreports-dotnet-core.Tests/Program.cs - -app/ +pkg/ diff --git a/ExtentReports.Tests/Config/ConfigStoreTest.cs b/ExtentReports.Tests/Config/ConfigStoreTest.cs new file mode 100644 index 0000000..c7f014f --- /dev/null +++ b/ExtentReports.Tests/Config/ConfigStoreTest.cs @@ -0,0 +1,83 @@ +using AventStack.ExtentReports.Config; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Config +{ + public class ConfigStoreTest + { + private ConfigStore _store = new ConfigStore(); + + [Test] + public void DuplicateConfig() + { + _store.AddConfig("config", "value1"); + Assert.AreEqual(_store.GetConfig("config"), "value1"); + + _store.AddConfig("config", "value2"); + Assert.AreEqual(_store.GetConfig("config"), "value2"); + } + + [Test] + public void Contains() + { + _store.AddConfig("config", "value1"); + Assert.True(_store.Contains("config")); + Assert.False(_store.Contains("config2")); + } + + [Test] + public void RemoveConfig() + { + _store.AddConfig("config", "value1"); + Assert.True(_store.Contains("config")); + _store.RemoveConfig("config"); + Assert.False(_store.Contains("config")); + } + + [Test] + public void ConfigValueTest() + { + _store.AddConfig("c", "v"); + _store.AddConfig("k", "z"); + Assert.True(_store.GetConfig("c").Equals("v")); + Assert.True(_store.GetConfig("k").Equals("z")); + } + + [Test] + public void ExtendConfigWithStore() + { + var store1 = new ConfigStore(); + store1.AddConfig("config1", "value1"); + var store2 = new ConfigStore(); + store2.AddConfig("config2", "value2"); + store1.Extend(store2.Store); + Assert.True(store1.Contains("config1")); + Assert.True(store1.Contains("config2")); + Assert.True(store2.Contains("config2")); + Assert.False(store2.Contains("config1")); + } + + [Test] + public void ExtendConfigWithMap() + { + var store1 = new ConfigStore(); + store1.AddConfig("config1", "value1"); + var store2 = new ConfigStore(); + store2.AddConfig("config2", "value2"); + store1.Extend(store2.Store); + Assert.True(store1.Contains("config1")); + Assert.True(store1.Contains("config2")); + Assert.True(store2.Contains("config2")); + Assert.False(store2.Contains("config1")); + } + + [Test] + public void ConfigEmpty() + { + Assert.True(_store.IsEmpty); + + _store.AddConfig("config1", "value1"); + Assert.False(_store.IsEmpty); + } + } +} diff --git a/ExtentReports.Tests/Core/AppenderTest.cs b/ExtentReports.Tests/Core/AppenderTest.cs new file mode 100644 index 0000000..9c1ebca --- /dev/null +++ b/ExtentReports.Tests/Core/AppenderTest.cs @@ -0,0 +1,167 @@ +using System.Linq; +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Reporter; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Core +{ + public class AppenderTest + { + private const string JsonArchive = "extent.json"; + + private ExtentReports _extent; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + var json = new ExtentJsonFormatter(JsonArchive); + _extent.AttachReporter(json); + } + + [Test] + public void TestWithLogs() + { + // initial, create archive: + var test1 = _extent.CreateTest("Testname1", "description1") + .Pass("Pass") + .Skip("Skip") + .Fail("Fail"); + var test2 = _extent.CreateTest("Testname2", "description2") + .Warning("Warn") + .Info("Info"); + _extent.Flush(); + + // post, check archive + var list = _extent.Report.Tests.ToList(); + Assert.AreEqual(list.Count, 2); + Assert.AreEqual(list[0].Status, test1.Status); + Assert.AreEqual(list[1].Status, test2.Status); + Assert.AreEqual(list[0].Name, test1.Test.Name); + Assert.AreEqual(list[1].Name, test2.Test.Name); + Assert.AreEqual(list[0].Description, test1.Test.Description); + Assert.AreEqual(list[1].Description, test2.Test.Description); + Assert.AreEqual(list[0].Logs.Count, test1.Test.Logs.Count); + Assert.AreEqual(list[1].Logs.Count, test2.Test.Logs.Count); + } + + [Test] + public void TestWithChildren() + { + // initial, create archive: + var test1 = _extent.CreateTest("Testname1", "description1"); + test1.CreateNode("Child1") + .Pass("Pass") + .Skip("Skip") + .Fail("Fail"); + var test2 = _extent.CreateTest("Testname2", "description2"); + test2.CreateNode("Child2") + .Warning("Warn") + .Info("Info"); + test2.CreateNode("Child3") + .Pass("Pass"); + _extent.Flush(); + + // post, check archive + _extent = new ExtentReports(); + Assert.AreEqual(0, _extent.Report.Tests.Count); + _extent.CreateDomainFromJsonArchive(JsonArchive); + var list = _extent.Report.Tests.ToList(); + + // parent checks + Assert.AreEqual(list.Count, 2); + Assert.AreEqual(list[0].Children.Count, 1); + Assert.AreEqual(list[1].Children.Count, 2); + Assert.AreEqual(list[0].Status, test1.Status); + Assert.AreEqual(list[1].Status, test2.Status); + Assert.AreEqual(list[0].Name, test1.Test.Name); + Assert.AreEqual(list[1].Name, test2.Test.Name); + Assert.AreEqual(list[0].Description, test1.Test.Description); + Assert.AreEqual(list[1].Description, test2.Test.Description); + Assert.AreEqual(list[0].Logs.Count, test1.Test.Logs.Count); + Assert.AreEqual(list[1].Logs.Count, test2.Test.Logs.Count); + } + + [Test] + public void Children() + { + // initial, create archive: + ExtentTest test1 = _extent.CreateTest("Testname1", "description1"); + ExtentTest child1 = test1.CreateNode("Child1") + .Pass("Pass") + .Skip("Skip") + .Fail("Fail"); + ExtentTest test2 = _extent.CreateTest("Testname2", "description2"); + ExtentTest child2 = test2.CreateNode("Child2") + .Warning("Warn") + .Info("Info"); + ExtentTest child3 = test2.CreateNode("Child3") + .Pass("Pass"); + _extent.Flush(); + + // post, check archive + _extent = new ExtentReports(); + _extent.CreateDomainFromJsonArchive(JsonArchive); + var list = _extent.Report.Tests.ToList(); + + Assert.IsNotEmpty(list); + Assert.IsNotEmpty(list[0].Children); + + // children checks + Assert.AreEqual(list[0].Children.First().Name, child1.Test.Name); + Assert.AreEqual(list[1].Children.First().Name, child2.Test.Name); + Assert.AreEqual(list[0].Children.First().Logs.Count, child1.Test.Logs.Count); + Assert.AreEqual(list[1].Children.First().Logs.Count, child2.Test.Logs.Count); + list[1].Children.RemoveAt(0); + Assert.AreEqual(list[1].Children.First().Name, child3.Test.Name); + Assert.AreEqual(list[1].Children.First().Logs.Count, child3.Test.Logs.Count); + } + + [Test] + public void TestWithMedia() + { + // initial, create archive: + var test1 = _extent.CreateTest("Testname1") + .AddScreenCaptureFromPath("img.png") + .Fail("Fail", MediaEntityBuilder.CreateScreenCaptureFromPath("img.png").Build()); + _extent.Flush(); + + // post, check archive + _extent = new ExtentReports(); + _extent.CreateDomainFromJsonArchive(JsonArchive); + var list = _extent.Report.Tests.ToList(); + + // parent checks + Assert.AreEqual(list.Count, 1); + Assert.AreEqual(list[0].Media.Count, 1); + Assert.NotNull(list[0].Logs.First().Media); + Assert.AreEqual(list[0].Media[0].Path, test1.Test.Media[0].Path); + Assert.AreEqual(list[0].Logs.First().Media.Path, + test1.Test.Logs.First().Media.Path); + } + + [Test] + public void TestWithMediaBase64() + { + // initial, create archive: + var test1 = _extent.CreateTest("Testname1") + .AddScreenCaptureFromBase64String("base64string") + .Fail("Fail", MediaEntityBuilder.CreateScreenCaptureFromBase64String("base64string").Build()); + _extent.Flush(); + + // post, check archive + _extent = new ExtentReports(); + _extent.CreateDomainFromJsonArchive(JsonArchive); + var list = _extent.Report.Tests.ToList(); + + // parent checks + Assert.AreEqual(list.Count, 1); + Assert.AreEqual(list[0].Media.Count, 1); + Assert.NotNull(list[0].Logs.First().Media); + Assert.AreEqual(((ScreenCapture)list[0].Media[0]).Base64, + ((ScreenCapture)test1.Test.Media[0]).Base64); + Assert.AreEqual(((ScreenCapture)list[0].Logs.First().Media).Base64, + ((ScreenCapture)test1.Test.Logs.First().Media).Base64); + } + } +} diff --git a/ExtentReports.Tests/Core/BddTypeTest.cs b/ExtentReports.Tests/Core/BddTypeTest.cs new file mode 100644 index 0000000..4fb380d --- /dev/null +++ b/ExtentReports.Tests/Core/BddTypeTest.cs @@ -0,0 +1,113 @@ +using AventStack.ExtentReports.Gherkin.Model; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Core +{ + public class BddTypeTest + { + private ExtentReports _extent; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + } + + [Test] + public void FeatureIsOfBddType() + { + var feature = _extent.CreateTest(TestContext.CurrentContext.Test.Name); + Assert.True(feature.Test.IsBdd); + Assert.AreEqual(feature.Test.BddType.Name, "Feature"); + } + + [Test] + public void ScenarioIsOfBddTypeWithBddChild() + { + var feature = _extent.CreateTest(TestContext.CurrentContext.Test.Name); + var scenario = feature.CreateNode("Scenario"); + Assert.True(scenario.Test.IsBdd); + Assert.AreEqual(scenario.Test.BddType.Name, "Scenario"); + } + + [Test] + public void ScenarioOutlineIsOfBddTypeWithBddChild() + { + var feature = _extent.CreateTest(TestContext.CurrentContext.Test.Name); + var scenarioOutline = feature.CreateNode("ScenarioOutline"); + Assert.True(scenarioOutline.Test.IsBdd); + Assert.AreEqual(scenarioOutline.Test.BddType.Name, "ScenarioOutline"); + } + + [Test] + public void AndIsOfBddTypeWithBddChild() + { + var feature = _extent.CreateTest(TestContext.CurrentContext.Test.Name); + var scenario = feature.CreateNode("Scenario"); + var and = scenario.CreateNode("And"); + Assert.True(and.Test.IsBdd); + Assert.AreEqual(and.Test.BddType.Name, "And"); + } + + [Test] + public void AsteriskIsOfBddTypeWithBddChild() + { + var feature = _extent.CreateTest(TestContext.CurrentContext.Test.Name); + var scenario = feature.CreateNode("Scenario"); + var asterisk = scenario.CreateNode("Asterisk"); + Assert.True(asterisk.Test.IsBdd); + Assert.AreEqual(asterisk.Test.BddType.Name, "*"); + } + + [Test] + public void BackgroundIsOfBddTypeWithBddChild() + { + var feature = _extent.CreateTest(TestContext.CurrentContext.Test.Name); + var scenario = feature.CreateNode("Scenario"); + var background = scenario.CreateNode("Background"); + Assert.True(background.Test.IsBdd); + Assert.AreEqual(background.Test.BddType.Name, "Background"); + } + + [Test] + public void ButIsOfBddTypeWithBddChild() + { + var feature = _extent.CreateTest(TestContext.CurrentContext.Test.Name); + var scenario = feature.CreateNode("Scenario"); + var but = scenario.CreateNode("But"); + Assert.True(but.Test.IsBdd); + Assert.AreEqual(but.Test.BddType.Name, "But"); + } + + [Test] + public void GivenIsOfBddTypeWithBddChild() + { + var feature = _extent.CreateTest(TestContext.CurrentContext.Test.Name); + var scenario = feature.CreateNode("Scenario"); + var given = scenario.CreateNode("Given"); + Assert.True(given.Test.IsBdd); + Assert.AreEqual(given.Test.BddType.Name, "Given"); + } + + [Test] + public void ThenIsOfBddTypeWithBddChild() + { + var feature = _extent.CreateTest(TestContext.CurrentContext.Test.Name); + var scenario = feature.CreateNode("Scenario"); + var then = scenario.CreateNode("Then"); + Assert.True(then.Test.IsBdd); + Assert.AreEqual(then.Test.BddType.Name, "Then"); + } + + [Test] + public void WhenIsOfBddTypeWithBddChild() + { + var feature = _extent.CreateTest(TestContext.CurrentContext.Test.Name); + var scenario = feature.CreateNode("Scenario"); + var when = scenario.CreateNode("When"); + Assert.True(when.Test.IsBdd); + Assert.AreEqual(when.Test.BddType.Name, "When"); + } + } +} diff --git a/ExtentReports.Tests/Core/ConcurrentExtentTestTest.cs b/ExtentReports.Tests/Core/ConcurrentExtentTestTest.cs new file mode 100644 index 0000000..c9782b9 --- /dev/null +++ b/ExtentReports.Tests/Core/ConcurrentExtentTestTest.cs @@ -0,0 +1,53 @@ +using System.Linq; +using System.Threading.Tasks; +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Reporter; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Core +{ + public class ConcurrentExtentTestTest + { + private ExtentReports _extent; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + } + + [Test] + public void ParallelCreateTests() + { + var rng = Enumerable.Range(0, 1000); + Parallel.ForEach(rng, x => _extent.CreateTest("Test").Info("")); + } + + [Test] + public void ParallelCreateTestsWithTags() + { + var rng = Enumerable.Range(0, 1000); + Parallel.ForEach(rng, x => { + _extent.CreateTest("Test") + .AssignCategory(new string[] { "t1", "t2" }) + .Pass(""); + }); + } + + [Test] + public void ParallelCreateTestsWithReporter() + { + _extent.AttachReporter(new ExtentSparkReporter("")); + var rng = Enumerable.Range(0, 10000); + Parallel.ForEach(rng, x => _extent.CreateTest("Test").Info("")); + } + + [Test] + public void ParallelLogs() + { + var test = _extent.CreateTest("Test"); + var rng = Enumerable.Range(0, 1000); + Parallel.ForEach(rng, x => test.Info("")); + } + } +} diff --git a/ExtentReports.Tests/Core/ExtentReportsRemoveTestTest.cs b/ExtentReports.Tests/Core/ExtentReportsRemoveTestTest.cs new file mode 100644 index 0000000..c69cc86 --- /dev/null +++ b/ExtentReports.Tests/Core/ExtentReportsRemoveTestTest.cs @@ -0,0 +1,76 @@ +using System.Linq; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Core +{ + public class ExtentReportsRemoveTestTest + { + private ExtentReports _extent; + private ExtentTest _test; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + _test = _extent.CreateTest("Test"); + } + + [Test] + public void RemoveTest() + { + Assert.AreEqual(1, _extent.Report.Tests.Count); + _extent.RemoveTest(_test); + Assert.AreEqual(0, _extent.Report.Tests.Count); + } + + [Test] + public void RemoveTestByName() + { + Assert.AreEqual(1, _extent.Report.Tests.Count); + _extent.RemoveTest("Test"); + Assert.AreEqual(0, _extent.Report.Tests.Count); + } + + [Test] + public void RemoveTestByID() + { + Assert.AreEqual(1, _extent.Report.Tests.Count); + _extent.RemoveTest(_test.Test.Id); + Assert.AreEqual(0, _extent.Report.Tests.Count); + } + + [Test] + public void RemoveNode() + { + var node = _test.CreateNode("Node"); + Assert.AreEqual(1, _extent.Report.Tests.Count); + Assert.AreEqual(1, _extent.Report.Tests.ToList()[0].Children.Count); + _extent.RemoveTest(node); + Assert.AreEqual(1, _extent.Report.Tests.Count); + Assert.AreEqual(0, _extent.Report.Tests.ToList()[0].Children.Count); + } + + [Test] + public void RemoveNodeByName() + { + _test.CreateNode("Node"); + Assert.AreEqual(1, _extent.Report.Tests.Count); + Assert.AreEqual(1, _extent.Report.Tests.ToList()[0].Children.Count); + _extent.RemoveTest("Node"); + Assert.AreEqual(1, _extent.Report.Tests.Count); + Assert.AreEqual(0, _extent.Report.Tests.ToList()[0].Children.Count); + } + + [Test] + public void RemoveNodeById() + { + var node = _test.CreateNode("Node"); + Assert.AreEqual(1, _extent.Report.Tests.Count); + Assert.AreEqual(1, _extent.Report.Tests.ToList()[0].Children.Count); + _extent.RemoveTest(node.Test.Id); + Assert.AreEqual(1, _extent.Report.Tests.Count); + Assert.AreEqual(0, _extent.Report.Tests.ToList()[0].Children.Count); + } + } +} diff --git a/ExtentReports.Tests/Core/ExtentReportsSystemEnvTest.cs b/ExtentReports.Tests/Core/ExtentReportsSystemEnvTest.cs new file mode 100644 index 0000000..9c398df --- /dev/null +++ b/ExtentReports.Tests/Core/ExtentReportsSystemEnvTest.cs @@ -0,0 +1,43 @@ +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Core +{ + public class ExtentReportsSystemEnvTest + { + private ExtentReports _extent; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + } + + [Test] + public void SystemInfo() + { + _extent.AddSystemInfo("a", "b"); + Assert.AreEqual(_extent.Report.SystemEnvInfo.Count, 1); + Assert.AreEqual(_extent.Report.SystemEnvInfo[0].Name, "a"); + Assert.AreEqual(_extent.Report.SystemEnvInfo[0].Value, "b"); + } + + [Test] + public void NullSystemInfo() + { + _extent.AddSystemInfo(null, null); + Assert.AreEqual(_extent.Report.SystemEnvInfo.Count, 1); + Assert.AreEqual(_extent.Report.SystemEnvInfo[0].Name, null); + Assert.AreEqual(_extent.Report.SystemEnvInfo[0].Value, null); + } + + [Test] + public void EmptySystemInfo() + { + _extent.AddSystemInfo("", ""); + Assert.AreEqual(_extent.Report.SystemEnvInfo.Count, 1); + Assert.AreEqual(_extent.Report.SystemEnvInfo[0].Name, ""); + Assert.AreEqual(_extent.Report.SystemEnvInfo[0].Value, ""); + } + } +} diff --git a/ExtentReports.Tests/Core/ExtentReportsTest.cs b/ExtentReports.Tests/Core/ExtentReportsTest.cs new file mode 100644 index 0000000..5883f87 --- /dev/null +++ b/ExtentReports.Tests/Core/ExtentReportsTest.cs @@ -0,0 +1,135 @@ +using System.Linq; +using AventStack.ExtentReports.Gherkin; +using AventStack.ExtentReports.Gherkin.Model; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Core +{ + class ExtentReportsTest + { + private const string TestName = "Test"; + + private ExtentReports _extent; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + } + + [TearDown] + public void TearDown() + { + _extent.GherkinDialect = "en"; + } + + [Test] + public void CreateTestOverloadTypeNameDesc() + { + var test = _extent.CreateTest(TestName, "Description"); + var model = test.Test; + Assert.True(model.IsBdd); + Assert.AreEqual(model.Name, TestName); + Assert.AreEqual(model.Description, "Description"); + Assert.AreEqual(model.BddType.Name, "Feature"); + Assert.True(model.Leaf); + } + + [Test] + public void CreateTestOverloadTypeName() + { + var test = _extent.CreateTest(TestName); + var model = test.Test; + Assert.True(model.IsBdd); + Assert.AreEqual(model.Name, TestName); + Assert.IsEmpty(model.Description); + Assert.AreEqual(model.BddType.Name, "Feature"); + Assert.True(model.Leaf); + } + + [Test] + public void CreateTestOverloadKeywordNameDesc() + { + var test = _extent.CreateTest(new GherkinKeyword("Feature"), TestName, "Description"); + var model = test.Test; + Assert.True(model.IsBdd); + Assert.AreEqual(model.Name, TestName); + Assert.AreEqual(model.Description, "Description"); + Assert.AreEqual(model.BddType.Name, "Feature"); + Assert.True(model.Leaf); + } + + [Test] + public void CreateTestOverloadKeywordName() + { + var test = _extent.CreateTest(new GherkinKeyword("Feature"), TestName); + var model = test.Test; + Assert.True(model.IsBdd); + Assert.AreEqual(model.Name, TestName); + Assert.IsEmpty(model.Description); + Assert.AreEqual(model.BddType.Name, "Feature"); + Assert.True(model.Leaf); + } + + [Test] + public void CreateTestOverloadNameDesc() + { + var test = _extent.CreateTest(TestName, "Description"); + var model = test.Test; + Assert.False(model.IsBdd); + Assert.AreEqual(model.Name, TestName); + Assert.AreEqual(model.Description, "Description"); + Assert.Null(model.BddType); + Assert.True(model.Leaf); + } + + [Test] + public void CreateTestOverloadName() + { + var test = _extent.CreateTest(TestName); + var model = test.Test; + Assert.False(model.IsBdd); + Assert.AreEqual(model.Name, TestName); + Assert.IsEmpty(model.Description); + Assert.Null(model.BddType); + Assert.True(model.Leaf); + } + + [Test] + public void GherkinDialect() + { + _extent.GherkinDialect = "de"; + Assert.AreEqual(GherkinDialectProvider.Lang, "de"); + } + + [Test] + public void AddTestRunnerOutputSingle() + { + var logs = new string[] { "Log1", "Log2" }; + var list = logs.ToList(); + list.ForEach(x => _extent.AddTestRunnerLogs(x)); + Assert.AreEqual(2, _extent.Report.Logs.Count); + list.ForEach(x => Assert.True(_extent.Report.Logs.Contains(x))); + } + + [Test] + public void AddTestRunnerOutputArr() + { + var logs = new string[] { "Log1", "Log2" }; + _extent.AddTestRunnerLogs(logs); + Assert.AreEqual(2, _extent.Report.Logs.Count); + logs.ToList().ForEach(x => Assert.True(_extent.Report.Logs.Contains(x))); + } + + [Test] + public void AddTestRunnerOutputList() + { + var logs = new string[] { "Log1", "Log2" }; + var list = logs.ToList(); + _extent.AddTestRunnerLogs(list); + Assert.AreEqual(2, _extent.Report.Logs.Count); + list.ForEach(x => Assert.True(_extent.Report.Logs.Contains(x))); + } + } +} diff --git a/ExtentReports.Tests/Core/ExtentTestAttributesTest.cs b/ExtentReports.Tests/Core/ExtentTestAttributesTest.cs new file mode 100644 index 0000000..f161488 --- /dev/null +++ b/ExtentReports.Tests/Core/ExtentTestAttributesTest.cs @@ -0,0 +1,68 @@ +using AventStack.ExtentReports.Model; +using NUnit.Framework; +using System.Linq; + +namespace AventStack.ExtentReports.Tests.Core +{ + public class ExtentTestAttributesTest + { + private ExtentReports _extent; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + } + + [Test] + public void ExtentTestWithNoAuthor() + { + Assert.AreEqual(0, _extent.CreateTest("Test").AssignAuthor().Test.Author.Count); + } + + [Test] + public void ExtentTestWithAuthor() + { + Assert.True( + _extent.CreateTest("Test") + .AssignAuthor("Author") + .Test + .Author + .Any(x => x.Name.Equals("Author"))); + } + + [Test] + public void ExtentTestWithNoDevice() + { + Assert.AreEqual(0, _extent.CreateTest("Test").AssignDevice().Test.Device.Count); + } + + [Test] + public void ExtentTestWithDevice() + { + Assert.True( + _extent.CreateTest("Test") + .AssignDevice("Device") + .Test + .Device + .Any(x => x.Name.Equals("Device"))); + } + + [Test] + public void ExtentTestWithNoCategory() + { + Assert.AreEqual(0, _extent.CreateTest("Test").AssignCategory().Test.Category.Count); + } + + [Test] + public void ExtentTestWithCategory() + { + Assert.True( + _extent.CreateTest("Test") + .AssignCategory("Tag") + .Test + .Category + .Any(x => x.Name.Equals("Tag"))); + } + } +} diff --git a/ExtentReports.Tests/Core/ExtentTestBDDGherkinKeywordNodeTest.cs b/ExtentReports.Tests/Core/ExtentTestBDDGherkinKeywordNodeTest.cs new file mode 100644 index 0000000..8ad723d --- /dev/null +++ b/ExtentReports.Tests/Core/ExtentTestBDDGherkinKeywordNodeTest.cs @@ -0,0 +1,72 @@ +using AventStack.ExtentReports.Gherkin; +using AventStack.ExtentReports.Gherkin.Model; +using NUnit.Framework; +using NUnit.Framework.Internal; +using System; +using System.Threading; + +namespace AventStack.ExtentReports.Tests.Core +{ + class ExtentTestBDDGherkinKeywordNodeTest + { + private const string TestName = "Test"; + private const string NodeName = "Node"; + private const string Description = "Description"; + + private ExtentReports _extent; + private ExtentTest _test; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + _test = _extent.CreateTest(new GherkinKeyword("Feature"), TestName); + } + + [Test] + public void CreateNodeNullName() + { + Assert.Throws(typeof(ArgumentException), () => _test.CreateNode(new GherkinKeyword("Scenario"), null)); + } + + [Test] + public void CreateNodeName() + { + var node = _test.CreateNode(new GherkinKeyword("Scenario"), NodeName); + var model = node.Test; + Assert.NotNull(model.BddType); + Assert.AreEqual(model.BddType.Name, "Scenario"); + Assert.AreEqual(NodeName, model.Name); + Assert.IsEmpty(model.Description); + } + + [Test] + public void CreateNodeNameDesc() + { + var node = _test.CreateNode(new GherkinKeyword("Scenario"), NodeName, Description); + var model = node.Test; + Assert.NotNull(model.BddType); + Assert.AreEqual(model.BddType.Name, "Scenario"); + Assert.AreEqual(NodeName, model.Name); + Assert.AreEqual(Description, model.Description); + } + + [Test] + public void NodeTimeInit() + { + var node = _test.CreateNode(new GherkinKeyword("Scenario"), NodeName); + var model = node.Test; + Assert.True(model.TimeTaken <= 1); + } + + [Test] + public void NodeTimeElapsed() + { + var node = _test.CreateNode(new GherkinKeyword("Scenario"), NodeName); + var model = node.Test; + Thread.Sleep(100); + node.Pass(""); + Assert.True(model.TimeTaken >= 100); + } + } +} diff --git a/ExtentReports.Tests/Core/ExtentTestBDDNodeTest.cs b/ExtentReports.Tests/Core/ExtentTestBDDNodeTest.cs new file mode 100644 index 0000000..3b661b9 --- /dev/null +++ b/ExtentReports.Tests/Core/ExtentTestBDDNodeTest.cs @@ -0,0 +1,71 @@ +using AventStack.ExtentReports.Gherkin.Model; +using NUnit.Framework; +using NUnit.Framework.Internal; +using System; +using System.Threading; + +namespace AventStack.ExtentReports.Tests.Core +{ + class ExtentTestBDDNodeTest + { + private const string TestName = "Test"; + private const string NodeName = "Node"; + private const string Description = "Description"; + + private ExtentReports _extent; + private ExtentTest _test; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + _test = _extent.CreateTest(TestName); + } + + [Test] + public void CreateNodeNullName() + { + Assert.Throws(typeof(ArgumentException), () => _test.CreateNode(null)); + } + + [Test] + public void CreateNodeName() + { + var node = _test.CreateNode(NodeName); + var model = node.Test; + Assert.NotNull(model.BddType); + Assert.AreEqual(model.BddType.Name, "Scenario"); + Assert.AreEqual(NodeName, model.Name); + Assert.IsEmpty(model.Description); + } + + [Test] + public void CreateNodeNameDesc() + { + var node = _test.CreateNode(NodeName, Description); + var model = node.Test; + Assert.NotNull(model.BddType); + Assert.AreEqual(model.BddType.Name, "Scenario"); + Assert.AreEqual(NodeName, model.Name); + Assert.AreEqual(Description, model.Description); + } + + [Test] + public void NodeTimeInit() + { + var node = _test.CreateNode(NodeName); + var model = node.Test; + Assert.True(model.TimeTaken <= 1); + } + + [Test] + public void NodeTimeElapsed() + { + var node = _test.CreateNode(NodeName); + var model = node.Test; + Thread.Sleep(100); + node.Pass(""); + Assert.True(model.TimeTaken >= 100); + } + } +} diff --git a/ExtentReports.Tests/Core/ExtentTestGeneratedLogTest.cs b/ExtentReports.Tests/Core/ExtentTestGeneratedLogTest.cs new file mode 100644 index 0000000..4dc6b05 --- /dev/null +++ b/ExtentReports.Tests/Core/ExtentTestGeneratedLogTest.cs @@ -0,0 +1,57 @@ +using AventStack.ExtentReports.MarkupUtils; +using AventStack.ExtentReports.Model; +using NUnit.Framework; +using NUnit.Framework.Internal; + +using System.Linq; + +namespace AventStack.ExtentReports.Tests.Core +{ + public class ExtentTestGeneratedLogTest + { + private const string TestName = "Test"; + + private ExtentReports _extent; + private ExtentTest _test; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + _test = _extent.CreateTest(TestName); + } + + [Test] + public void GeneratedLogEmpty() + { + var t = _test.GenerateLog(Status.Pass, ""); + Assert.True(t.Test.HasAnyLog); + Assert.True(t.Test.HasGeneratedLog); + Assert.True(!t.Test.GeneratedLog.IsEmpty); + Assert.AreEqual(t.Test.GeneratedLog.First().Details, ""); + } + + [Test] + public void GeneratedLogDetails() + { + var t = _test.GenerateLog(Status.Pass, "Details"); + Assert.True(t.Test.HasAnyLog); + Assert.True(!t.Test.GeneratedLog.IsEmpty); + Assert.AreEqual(t.Test.GeneratedLog.First().Details, "Details"); + } + + [Test] + public void GeneratedLogMarkup() + { + var json = "{ 'key': 'value' }"; + var m = MarkupHelper.CreateCodeBlock(json, CodeLanguage.Json); + var t = _test.GenerateLog(Status.Pass, m); + Assert.True(t.Test.HasAnyLog); + Assert.True(!t.Test.GeneratedLog.IsEmpty); + Assert.True(t.Test.GeneratedLog.First().Details.Contains("jsonTree")); + Assert.True(t.Test.GeneratedLog.First().Details.Contains("")); + Assert.True(t.Test.GeneratedLog.First().Details.Contains("{ 'key': 'value' }")); + } + } +} diff --git a/ExtentReports.Tests/Core/ExtentTestLogsTest.cs b/ExtentReports.Tests/Core/ExtentTestLogsTest.cs new file mode 100644 index 0000000..ae7f7ef --- /dev/null +++ b/ExtentReports.Tests/Core/ExtentTestLogsTest.cs @@ -0,0 +1,384 @@ +using AventStack.ExtentReports.MarkupUtils; +using AventStack.ExtentReports.Model; +using NUnit.Framework; +using NUnit.Framework.Internal; +using System; +using System.Collections.Generic; + +namespace AventStack.ExtentReports.Tests.Core +{ + class ExtentTestLogsTest + { + private const string Details = "details"; + private const string Attachment = "img.png"; + + private const string TestName = "Test"; + + private ExtentReports _extent; + private ExtentTest _test; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + _test = _extent.CreateTest(TestName); + } + + [Test] + public void LogDetails() + { + _test.Log(Status.Skip, Details + "1"); + Assert.AreEqual(_test.Test.Status, Status.Skip); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Details, Details + "1"); + Assert.AreEqual(logs[0].Status, Status.Skip); + _test.Log(Status.Fail, Details); + logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[1].Details, Details); + Assert.AreEqual(logs[1].Status, Status.Fail); + } + + [Test] + public void LogDetailsMedia() + { + _test.Log(Status.Skip, Details, + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(_test.Test.Status, Status.Skip); + Assert.AreEqual(logs[0].Details, Details); + Assert.AreEqual(logs[0].Status, Status.Skip); + Assert.AreEqual(logs[0].Media.Path, Attachment); + _test.Log(Status.Fail, Details, MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[1].Details, Details); + Assert.AreEqual(logs[1].Status, Status.Fail); + Assert.AreEqual(logs[1].Media.Path, Attachment); + } + + [Test] + public void LogMedia() + { + var test = _test.Log(Status.Skip, + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + Assert.AreEqual(_test.Test.Status, Status.Skip); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Details, ""); + Assert.AreEqual(logs[0].Status, Status.Skip); + Assert.AreEqual(logs[0].Media.Path, Attachment); + _test.Log(Status.Fail, MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[1].Details, ""); + Assert.AreEqual(logs[1].Status, Status.Fail); + Assert.AreEqual(logs[1].Media.Path, Attachment); + } + + [Test] + public void LogMarkup() + { + var m = MarkupHelper.CreateCodeBlock("code"); + _test.Log(Status.Skip, m); + Assert.AreEqual(_test.Test.Status, Status.Skip); + var logs = new List(_test.Test.Logs); + Assert.True(logs[0].Details.Contains("code")); + Assert.AreEqual(logs[0].Status, Status.Skip); + } + + [Test] + public void LogThrowable() + { + var ex = new Exception("Exception"); + _test.Log(Status.Skip, ex); + Assert.AreEqual(_test.Test.Status, Status.Skip); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Skip); + _test.Log(Status.Fail, ex); + logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[1].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[1].Status, Status.Fail); + } + + [Test] + public void LogThrowableMedia() + { + var ex = new Exception("Exception"); + var test = _test.Log(Status.Skip, ex, + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + Assert.AreEqual(_test.Test.Status, Status.Skip); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Skip); + Assert.AreEqual(logs[0].Media.Path, Attachment); + _test.Log(Status.Fail, ex, MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[1].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[1].Status, Status.Fail); + Assert.AreEqual(logs[1].Media.Path, Attachment); + } + + [Test] + public void FailDetails() + { + _test.Fail(Details); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Details, Details); + Assert.AreEqual(logs[0].Status, Status.Fail); + } + + [Test] + public void FailMedia() + { + _test.Fail( + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + _test.Log(Status.Fail, Details, MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Status, Status.Fail); + Assert.AreEqual(logs[0].Media.Path, Attachment); + } + + [Test] + public void FailThrowable() + { + var ex = new Exception("Exception"); + _test.Fail(ex); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Fail); + } + + [Test] + public void FailThrowableMedia() + { + var ex = new Exception("Exception"); + _test.Fail(ex, + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Fail); + Assert.AreEqual(logs[0].Media.Path, Attachment); + } + + [Test] + public void FailMarkup() + { + var m = MarkupHelper.CreateCodeBlock("code"); + _test.Fail(m); + Assert.AreEqual(_test.Test.Status, Status.Fail); + var logs = new List(_test.Test.Logs); + Assert.True(logs[0].Details.Contains("code")); + Assert.AreEqual(logs[0].Status, Status.Fail); + } + + [Test] + public void SkipDetails() + { + _test.Skip(Details); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Details, Details); + Assert.AreEqual(logs[0].Status, Status.Skip); + } + + [Test] + public void SkipMedia() + { + _test.Skip( + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + _test.Log(Status.Fail, Details, MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Status, Status.Skip); + Assert.AreEqual(logs[0].Media.Path, Attachment); + } + + [Test] + public void SkipThrowable() + { + var ex = new Exception("Exception"); + _test.Skip(ex); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Skip); + } + + [Test] + public void SkipThrowableMedia() + { + var ex = new Exception("Exception"); + _test.Skip(ex, + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Skip); + Assert.AreEqual(logs[0].Media.Path, Attachment); + } + + [Test] + public void SkipMarkup() + { + var m = MarkupHelper.CreateCodeBlock("code"); + _test.Log(Status.Skip, m); + Assert.AreEqual(_test.Test.Status, Status.Skip); + var logs = new List(_test.Test.Logs); + Assert.True(logs[0].Details.Contains("code")); + Assert.AreEqual(logs[0].Status, Status.Skip); + } + + [Test] + public void WarnDetails() + { + _test.Warning(Details); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Details, Details); + Assert.AreEqual(logs[0].Status, Status.Warning); + } + + [Test] + public void WarnMedia() + { + _test.Warning( + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + _test.Log(Status.Warning, Details, MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Status, Status.Warning); + Assert.AreEqual(logs[0].Media.Path, Attachment); + } + + [Test] + public void WarnThrowable() + { + var ex = new Exception("Exception"); + _test.Warning(ex); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Warning); + } + + [Test] + public void WarnThrowableMedia() + { + var ex = new Exception("Exception"); + _test.Log(Status.Warning, ex, + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Warning); + Assert.AreEqual(logs[0].Media.Path, Attachment); + } + + [Test] + public void WarnMarkup() + { + var m = MarkupHelper.CreateCodeBlock("code"); + _test.Log(Status.Warning, m); + Assert.AreEqual(_test.Test.Status, Status.Warning); + var logs = new List(_test.Test.Logs); + Assert.True(logs[0].Details.Contains("code")); + Assert.AreEqual(logs[0].Status, Status.Warning); + } + + [Test] + public void PassDetails() + { + _test.Pass(Details); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Details, Details); + Assert.AreEqual(logs[0].Status, Status.Pass); + } + + [Test] + public void PassMedia() + { + _test.Pass( + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + _test.Log(Status.Pass, Details, MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Status, Status.Pass); + Assert.AreEqual(logs[0].Media.Path, Attachment); + } + + [Test] + public void PassThrowable() + { + var ex = new Exception("Exception"); + _test.Pass(ex); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Pass); + } + + [Test] + public void PassThrowableMedia() + { + var ex = new Exception("Exception"); + _test.Pass(ex, + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Pass); + Assert.AreEqual(logs[0].Media.Path, Attachment); + } + + [Test] + public void PassMarkup() + { + var m = MarkupHelper.CreateCodeBlock("code"); + _test.Log(Status.Pass, m); + Assert.AreEqual(_test.Test.Status, Status.Pass); + var logs = new List(_test.Test.Logs); + Assert.True(logs[0].Details.Contains("code")); + Assert.AreEqual(logs[0].Status, Status.Pass); + } + + [Test] + public void InfoDetails() + { + _test.Info(Details); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Details, Details); + Assert.AreEqual(logs[0].Status, Status.Info); + } + + [Test] + public void InfoMedia() + { + _test.Info( + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + _test.Log(Status.Info, Details, MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].Status, Status.Info); + Assert.AreEqual(logs[0].Media.Path, Attachment); + } + + [Test] + public void InfoThrowable() + { + var ex = new Exception("Exception"); + _test.Info(ex); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Info); + } + + [Test] + public void InfoThrowableMedia() + { + var ex = new Exception("Exception"); + _test.Info(ex, + MediaEntityBuilder.CreateScreenCaptureFromPath(Attachment).Build()); + var logs = new List(_test.Test.Logs); + Assert.AreEqual(logs[0].ExceptionInfo.Exception, ex); + Assert.AreEqual(logs[0].Status, Status.Info); + Assert.AreEqual(logs[0].Media.Path, Attachment); + } + + [Test] + public void InfoMarkup() + { + var m = MarkupHelper.CreateCodeBlock("code"); + _test.Log(Status.Info, m); + Assert.AreEqual(_test.Test.Status, Status.Pass); + var logs = new List(_test.Test.Logs); + Assert.True(logs[0].Details.Contains("code")); + Assert.AreEqual(logs[0].Status, Status.Info); + } + } +} diff --git a/ExtentReports.Tests/Core/ExtentTestMediaTest.cs b/ExtentReports.Tests/Core/ExtentTestMediaTest.cs new file mode 100644 index 0000000..2971d57 --- /dev/null +++ b/ExtentReports.Tests/Core/ExtentTestMediaTest.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Core +{ + public class ExtentTestMediaTest + { + private const string Base64Encoded = "data:image/png;base64,"; + private const string Base64 = "iVBORw0KGgoAAAANSUhEUgAAAY4AAABbCAYAAABkgGJUAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAABIMSURBVHhe7Z3" + + "daxRXH8effyZ3gVwIXgiFemXwookXkUIINFQQGrx4clV9LpILadCLEOzjWm0U00ZMQ7SQUEuKbSw1BoKkEdnqI1tss3lZ1rh1a9JsTMLvOWfmnJmzu/NyzuyLO/H7gUObcWfmzMzu7zPn/V8EAAAA" + + "GABxAAAAMALiAAAAYATEAQAAwAiIAwAAgBEQBwAAACMgDgAAAEZAHAAAAIyAOAAAABgBcQAAADAC4gAAAGAExAEAAMAIiAMAAIAREAcAAAAjIA4AAABGQBwAAACMgDgAAAAYAXEAAAAwAuIAAABgB"; + private const string Path = "src/test/resources/img.png"; + private const string Title = "MediaTitle"; + + private ExtentReports _extent; + private ExtentTest _test; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + _test = _extent.CreateTest("Test"); + } + + [Test] + public void AddScreenCaptureFromEmptyPathTest() + { + Assert.Throws(typeof(ArgumentException), () => _test.AddScreenCaptureFromPath("")); + } + + [Test] + public void AddScreenCaptureFromNullPathTest() + { + Assert.Throws(typeof(ArgumentException), () => _test.AddScreenCaptureFromPath(null)); + } + + [Test] + public void AddScreenCaptureFromPathTest() + { + _test.AddScreenCaptureFromPath(Path, Title).Pass("Pass"); + Assert.AreEqual(_test.Test.Media.Count, 1); + Assert.AreEqual(_test.Test.Media[0].Path, Path); + Assert.AreEqual(_test.Test.Media[0].Title, Title); + } + + [Test] + public void AddScreenCaptureFromPathTestOverloads() + { + _test + .AddScreenCaptureFromPath(Path) + .Pass("Pass"); + Assert.AreEqual(_test.Test.Media.Count, 1); + Assert.AreEqual(_test.Test.Media[0].Path, Path); + } + + [Test] + public void AddScreenCaptureFromPathNode() + { + ExtentTest node = _test + .CreateNode("Node") + .AddScreenCaptureFromPath(Path, Title) + .Pass("Pass"); + Assert.AreEqual(_test.Test.Media.Count, 0); + Assert.AreEqual(node.Test.Media.Count, 1); + Assert.AreEqual(node.Test.Media[0].Path, Path); + Assert.AreEqual(node.Test.Media[0].Title, Title); + } + + [Test] + public void AddScreenCaptureEmptyPathTestLog() + { + Assert.Throws(typeof(ArgumentException), () => _test.Pass("Pass", MediaEntityBuilder.CreateScreenCaptureFromPath("").Build())); + } + + [Test] + public void AddScreenCaptureNullPathTestLog() + { + Assert.Throws(typeof(ArgumentException), () => _test.Pass("Pass", MediaEntityBuilder.CreateScreenCaptureFromPath(null).Build())); + } + + [Test] + public void AddScreenCaptureFromPathTestLog() + { + _test.Pass("Pass", MediaEntityBuilder.CreateScreenCaptureFromPath(Path, Title).Build()); + Assert.AreEqual(_test.Test.Media.Count, 0); + var logs = new List(_test.Test.Logs); + Assert.NotNull(logs[0].Media); + Assert.AreEqual(logs[0].Media.Path, Path); + Assert.AreEqual(logs[0].Media.Title, Title); + } + + [Test] + public void AddScreenCaptureFromPathTestLogOverloads() + { + _test.Pass("Pass", MediaEntityBuilder.CreateScreenCaptureFromPath(Path).Build()); + Assert.AreEqual(_test.Test.Media.Count, 0); + var logs = new List(_test.Test.Logs); + Assert.NotNull(logs[0].Media); + Assert.AreEqual(logs[0].Media.Path, Path); + } + + [Test] + public void AddScreenCaptureFromPathNodeLog() + { + ExtentTest node = _test + .CreateNode("Node") + .Pass("Pass", MediaEntityBuilder.CreateScreenCaptureFromPath(Path, Title).Build()); + Assert.AreEqual(node.Test.Media.Count, 0); + var logs = new List(node.Test.Logs); + Assert.NotNull(logs[0].Media); + Assert.AreEqual(logs[0].Media.Path, Path); + Assert.AreEqual(logs[0].Media.Title, Title); + } + + [Test] + public void AddScreenCaptureFromEmptyBase64Test() + { + Assert.Throws(typeof(ArgumentException), () => _test.AddScreenCaptureFromBase64String("")); + } + + [Test] + public void AddScreenCaptureFromNullBase64Test() + { + Assert.Throws(typeof(ArgumentException), () => _test.AddScreenCaptureFromBase64String(null)); + } + + [Test] + public void AddScreenCaptureFromBase64Test() + { + _test.AddScreenCaptureFromBase64String(Base64, Title) + .Pass("Pass"); + Assert.AreEqual(_test.Test.Media.Count, 1); + Assert.AreEqual(((ScreenCapture)_test.Test.Media[0]).Base64, Base64Encoded + Base64); + Assert.AreEqual(_test.Test.Media[0].Title, Title); + } + + [Test] + public void AddScreenCaptureFromBase64Node() + { + var node = _test.CreateNode("Node") + .AddScreenCaptureFromBase64String(Base64, Title) + .Pass("Pass"); + Assert.AreEqual(_test.Test.Media.Count, 0); + Assert.AreEqual(node.Test.Media.Count, 1); + Assert.AreEqual(((ScreenCapture)node.Test.Media[0]).Base64, Base64Encoded + Base64); + Assert.AreEqual(node.Test.Media[0].Title, Title); + } + + [Test] + public void AddScreenCaptureFromBase64NodeOverloads() + { + var node = _test.CreateNode("Node") + .AddScreenCaptureFromBase64String(Base64) + .Pass("Pass"); + Assert.AreEqual(_test.Test.Media.Count, 0); + Assert.AreEqual(node.Test.Media.Count, 1); + Assert.AreEqual(((ScreenCapture)node.Test.Media[0]).Base64, Base64Encoded + Base64); + } + + [Test] + public void AddScreenCaptureFromBase64TestLog() + { + _test.Pass("Pass", MediaEntityBuilder.CreateScreenCaptureFromBase64String(Base64, Title).Build()); + Assert.AreEqual(_test.Test.Media.Count, 0); + var logs = new List(_test.Test.Logs); + Assert.NotNull(logs[0].Media); + Assert.AreEqual(((ScreenCapture)logs[0].Media).Base64, + Base64Encoded + Base64); + Assert.AreEqual(logs[0].Media.Title, Title); + } + + [Test] + public void AddScreenCaptureFromBase64NodeLog() + { + var node = _test.CreateNode("Node") + .Pass("Pass", MediaEntityBuilder.CreateScreenCaptureFromBase64String(Base64, Title).Build()); + Assert.AreEqual(node.Test.Media.Count, 0); + var logs = new List(node.Test.Logs); + Assert.NotNull(logs[0].Media); + Assert.AreEqual(((ScreenCapture)logs[0].Media).Base64, + Base64Encoded + Base64); + Assert.AreEqual(logs[0].Media.Title, Title); + } + + [Test] + public void AddScreenCaptureFromBase64NodeLogOverloads() + { + var node = _test.CreateNode("Node") + .Pass("Pass", MediaEntityBuilder.CreateScreenCaptureFromBase64String(Base64).Build()); + Assert.AreEqual(node.Test.Media.Count, 0); + var logs = new List(node.Test.Logs); + Assert.NotNull(logs[0].Media); + Assert.AreEqual(((ScreenCapture)logs[0].Media).Base64, + Base64Encoded + Base64); + } + } +} diff --git a/ExtentReports.Tests/Core/ExtentTestNodeTest.cs b/ExtentReports.Tests/Core/ExtentTestNodeTest.cs new file mode 100644 index 0000000..3f0094c --- /dev/null +++ b/ExtentReports.Tests/Core/ExtentTestNodeTest.cs @@ -0,0 +1,66 @@ +using NUnit.Framework; +using NUnit.Framework.Internal; +using System; +using System.Threading; + +namespace AventStack.ExtentReports.Tests.Core +{ + class ExtentTestNodeTest + { + private const string TestName = "Test"; + private const string NodeName = "Node"; + private const string Description = "Description"; + + private ExtentReports _extent; + private ExtentTest _test; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + _test = _extent.CreateTest(TestName); + } + + [Test] + public void CreateNodeNullName() + { + Assert.Throws(typeof(ArgumentException), () => _test.CreateNode(null)); + } + + [Test] + public void CreateNodeName() + { + var node = _test.CreateNode(NodeName); + var model = node.Test; + Assert.AreEqual(NodeName, model.Name); + Assert.IsEmpty(model.Description); + } + + [Test] + public void CreateNodeNameDesc() + { + var node = _test.CreateNode(NodeName, Description); + var model = node.Test; + Assert.AreEqual(NodeName, model.Name); + Assert.AreEqual(Description, model.Description); + } + + [Test] + public void NodeTimeInit() + { + var node = _test.CreateNode(NodeName, Description); + var model = node.Test; + Assert.True(model.TimeTaken <= 1); + } + + [Test] + public void NodeTimeElapsed() + { + var node = _test.CreateNode(NodeName, Description); + var model = node.Test; + Thread.Sleep(100); + node.Pass(""); + Assert.True(model.TimeTaken >= 100); + } + } +} diff --git a/ExtentReports.Tests/Core/NaturalConfTest.cs b/ExtentReports.Tests/Core/NaturalConfTest.cs new file mode 100644 index 0000000..0260cda --- /dev/null +++ b/ExtentReports.Tests/Core/NaturalConfTest.cs @@ -0,0 +1,73 @@ +using AventStack.ExtentReports.Model; +using NUnit.Framework; +using System; +using System.Threading; + +namespace AventStack.ExtentReports.Tests.Core +{ + public class NaturalConfTest + { + private ExtentReports _extent; + private ExtentTest _test; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports + { + UseNaturalTime = false + }; + _test = _extent.CreateTest("Test"); + } + + [Test] + public void UseNaturalConfReport() + { + _test.Pass("init"); + Thread.Sleep(500); + _test.Pass("complete"); + // must flush to determine time for report + _extent.Flush(); + Assert.True(_extent.Report.TimeTaken.TotalMilliseconds < 5); + } + + [Test] + public void UseNaturalConfReportWithTimeChanged() + { + _test.Pass("init"); + _test.Test.EndTime = DateTime.Now.AddMilliseconds(5000); + _test.Pass("complete"); + // must flush to determine time for report + _extent.Flush(); + Assert.True(_extent.Report.TimeTaken.TotalMilliseconds >= 5000); + } + + [Test] + public void UseNaturalConfTest() + { + _test.Pass("init"); + Thread.Sleep(500); + _test.Pass("complete"); + Assert.True(_test.Test.TimeTaken < 5); + } + + [Test] + public void UseNaturalConfTestWithTimeChanged() + { + _test.Pass("init"); + _test.Test.EndTime = DateTime.Now.AddMilliseconds(5000); + _test.Pass("complete"); + Assert.True(_test.Test.TimeTaken >= 5000); + } + + [Test] + public void UseNaturalConfTestWithNodes() + { + ExtentTest child = _test.CreateNode("Node").Pass("init"); + Thread.Sleep(500); + child.Pass("complete"); + Assert.True(_test.Test.TimeTaken < 5); + Assert.True(child.Test.TimeTaken < 5); + } + } +} diff --git a/ExtentReports.Tests/Core/TestIdTest.cs b/ExtentReports.Tests/Core/TestIdTest.cs new file mode 100644 index 0000000..1c32237 --- /dev/null +++ b/ExtentReports.Tests/Core/TestIdTest.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.Linq; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Core +{ + class TestIdTest + { + private static readonly int Attempts = 10000; + + [Test] + public void AllTestsHaveUniqueId() + { + var extent = new ExtentReports(); + var set = new HashSet(); + Enumerable.Range(0, Attempts).ToList().ForEach(x => set.Add(extent.CreateTest("test").Test.Id)); + Assert.AreEqual(Attempts, set.Count); + } + } +} diff --git a/ExtentReports.Tests/ExtentReports.Tests.csproj b/ExtentReports.Tests/ExtentReports.Tests.csproj new file mode 100644 index 0000000..9dd9b8b --- /dev/null +++ b/ExtentReports.Tests/ExtentReports.Tests.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + + false + + + + + + + + + + + + diff --git a/ExtentReports.Tests/Markup/CodeBlockTest.cs b/ExtentReports.Tests/Markup/CodeBlockTest.cs new file mode 100644 index 0000000..bf951cd --- /dev/null +++ b/ExtentReports.Tests/Markup/CodeBlockTest.cs @@ -0,0 +1,103 @@ +using System; +using AventStack.ExtentReports.MarkupUtils; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Markup +{ + public class CodeBlockTest + { + [Test] + public void NullCodeBlockContent() + { + var m = MarkupHelper.CreateCodeBlock((string)null); + Assert.AreEqual(m.GetMarkup(), ""); + } + + [Test] + public void XmlCodeBlock() + { + var xml = "value"; + var m = MarkupHelper.CreateCodeBlock(xml); + Assert.True(m.GetMarkup().Contains(xml)); + } + + [Test] + public void XmlCodeBlockWithLang() + { + var xml = "value"; + var m = MarkupHelper.CreateCodeBlock(xml, CodeLanguage.Xml); + Assert.True(m.GetMarkup().Contains(xml)); + } + + [Test] + public void JsonCodeBlock() + { + var json = "{ 'key': 'value' }"; + var m = MarkupHelper.CreateCodeBlock(json); + Assert.True(m.GetMarkup().Contains(json)); + } + + [Test] + public void JsonCodeBlockWithLang() + { + var json = "{ 'key': 'value' }"; + var m = MarkupHelper.CreateCodeBlock(json, CodeLanguage.Json); + Assert.True(m.GetMarkup().Contains(json)); + Assert.True(m.GetMarkup().Contains("jsonTreeCreate")); + Assert.True(m.GetMarkup().Contains("")); + } + + [Test] + public void JsonCodeBlockWithLangMultiple() + { + var json = "{ 'key': 'value' }"; + var m = MarkupHelper.CreateCodeBlock(json, CodeLanguage.Json); + Assert.True(m.GetMarkup().Contains(json)); + Assert.True(m.GetMarkup().Contains("jsonTreeCreate")); + Assert.True(m.GetMarkup().Contains("")); + m = MarkupHelper.CreateCodeBlock(json, CodeLanguage.Json); + Assert.True(m.GetMarkup().Contains(json)); + Assert.True(m.GetMarkup().Contains("jsonTreeCreate")); + Assert.True(m.GetMarkup().Contains("")); + } + + [Test] + public void MultipleCodeBlocks1() + { + var xml = "value"; + var m = MarkupHelper.CreateCodeBlock(new String[] { xml }); + String s = m.GetMarkup(); + Assert.True(s.Contains("col-md-12")); + } + + [Test] + public void MultipleCodeBlocks2() + { + var xml = "value"; + var m = MarkupHelper.CreateCodeBlock(new String[] { xml, xml }); + String s = m.GetMarkup(); + Assert.True(s.Contains("col-md-6")); + } + + [Test] + public void MultipleCodeBlocks3() + { + var xml = "value"; + var m = MarkupHelper.CreateCodeBlock(new String[] { xml, xml, xml }); + String s = m.GetMarkup(); + Assert.True(s.Contains("col-md-4")); + } + + [Test] + public void MultipleCodeBlocks4() + { + var xml = "value"; + var m = MarkupHelper.CreateCodeBlock(new String[] { xml, xml, xml, xml }); + String s = m.GetMarkup(); + Assert.True(s.Contains("col-md-3")); + } + } +} diff --git a/ExtentReports.Tests/Markup/Foo.cs b/ExtentReports.Tests/Markup/Foo.cs new file mode 100644 index 0000000..0e8e575 --- /dev/null +++ b/ExtentReports.Tests/Markup/Foo.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace AventStack.ExtentReports.Tests.Markup +{ + class Foo + { + public List Names { get; set; } = new string[] { "Anshoo", "Extent", "Klov" }.ToList(); + public object[] Stack { get; set; } = new object[] { "Java", "C#", "Angular" }; + } +} diff --git a/ExtentReports.Tests/Markup/LabelTest.cs b/ExtentReports.Tests/Markup/LabelTest.cs new file mode 100644 index 0000000..d1deeb7 --- /dev/null +++ b/ExtentReports.Tests/Markup/LabelTest.cs @@ -0,0 +1,31 @@ +using System; +using AventStack.ExtentReports.MarkupUtils; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Markup +{ + public class LabelTest + { + [Test] + public void LabelWithNullText() + { + var m = MarkupHelper.CreateLabel(null, ExtentColor.Transparent); + Assert.AreEqual(m.GetMarkup(), ""); + } + + [Test] + public void LabelWithEmptyText() + { + var m = MarkupHelper.CreateLabel("", ExtentColor.Transparent); + Assert.AreEqual(m.GetMarkup(), ""); + } + + [Test] + public void LabelWithText() + { + String text = "Extent"; + var m = MarkupHelper.CreateLabel(text, ExtentColor.Transparent); + Assert.True(m.GetMarkup().Contains(text)); + } + } +} diff --git a/ExtentReports.Tests/Markup/TableTest.cs b/ExtentReports.Tests/Markup/TableTest.cs new file mode 100644 index 0000000..c21ff81 --- /dev/null +++ b/ExtentReports.Tests/Markup/TableTest.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using AventStack.ExtentReports.MarkupUtils; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Markup +{ + public class TableTest + { + [Test] + public void TableWithNullText() + { + var m = MarkupHelper.CreateTable(null); + Assert.AreEqual(m.GetMarkup(), ""); + } + + [Test] + public void TableWithData() + { + string[,] data = new string[,] { { "h1", "h2" }, { "c1", "c2" } }; + var m = MarkupHelper.CreateTable(data); + string s = m.GetMarkup(); + Assert.True(s.Contains("h1")); + Assert.True(s.Contains("h2")); + Assert.True(s.Contains("c1")); + Assert.True(s.Contains("c2")); + Assert.True(s.Contains("")); + } + + [Test] + public void TableWithBeginningEndingTags() + { + var m = MarkupHelper.ToTable(new Foo()); + string s = m.GetMarkup(); + Assert.True(s.Contains("")); + } + + [Test] + public void TableWithHeaders() + { + var m = MarkupHelper.ToTable(new Foo()); + string s = m.GetMarkup(); + Assert.True(s.Contains("Names")); + Assert.True(s.Contains("Stack")); + } + + [Test] + public void TableWithCells() + { + var m = MarkupHelper.ToTable(new Foo()); + string s = m.GetMarkup(); + Assert.True(s.Contains("Anshoo")); + Assert.True(s.Contains("Extent")); + Assert.True(s.Contains("Klov")); + Assert.True(s.Contains("Java")); + Assert.True(s.Contains("C#")); + Assert.True(s.Contains("Angular")); + } + } +} diff --git a/ExtentReports.Tests/Model/AuthorEntityTest.cs b/ExtentReports.Tests/Model/AuthorEntityTest.cs new file mode 100644 index 0000000..21100e5 --- /dev/null +++ b/ExtentReports.Tests/Model/AuthorEntityTest.cs @@ -0,0 +1,16 @@ +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Model +{ + class AuthorEntityTest + { + [Test] + public void AuthorName() + { + var name = "Anshoo"; + var author = new Author(name); + Assert.AreEqual(name, author.Name); + } + } +} diff --git a/ExtentReports.Tests/Model/CategoryEntityTest.cs b/ExtentReports.Tests/Model/CategoryEntityTest.cs new file mode 100644 index 0000000..5f02b48 --- /dev/null +++ b/ExtentReports.Tests/Model/CategoryEntityTest.cs @@ -0,0 +1,16 @@ +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Model +{ + class CategoryEntityTest + { + [Test] + public void CategoryName() + { + var name = "TagName"; + var category = new Category(name); + Assert.AreEqual(name, category.Name); + } + } +} diff --git a/ExtentReports.Tests/Model/Context/Manager/NamedAttributeContextManagerTest.cs b/ExtentReports.Tests/Model/Context/Manager/NamedAttributeContextManagerTest.cs new file mode 100644 index 0000000..df9f005 --- /dev/null +++ b/ExtentReports.Tests/Model/Context/Manager/NamedAttributeContextManagerTest.cs @@ -0,0 +1,50 @@ +using System.Linq; +using System.Threading.Tasks; +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Model.Context.Manager; +using NUnit.Framework; + +namespace ExtentReports.Tests.Model.Context.Manager +{ + public class NamedAttributeContextManagerTest + { + [Test] + public void ConcurrentAddContextTest() + { + var mgr = new NamedAttributeContextManager(); + int rangeFor = 100; + + var rng = Enumerable.Range(0, rangeFor); + Parallel.ForEach(rng, x => + { + var category = new Category(x.ToString()); + var test = new Test(x.ToString()); + mgr.AddContext(category, test); + }); + + for (int i = 0; i < rangeFor; i++) + { + Assert.AreEqual(1, mgr.Context[i.ToString()].Count()); + } + } + + [Test] + public void ConcurrentAddContextTests() + { + var mgr = new NamedAttributeContextManager(); + var category = new Category("Category"); + var test = new Test("Test"); + mgr.AddContext(category, test); + int rangeFor = 100; + + var rng = Enumerable.Range(0, rangeFor); + Parallel.ForEach(rng, x => + { + var test = new Test(x.ToString()); + mgr.AddContext(category, test); + }); + + Assert.AreEqual(1 + rangeFor, mgr.Context[category.Name].Count()); + } + } +} diff --git a/ExtentReports.Tests/Model/Context/NamedAttributeContextTest.cs b/ExtentReports.Tests/Model/Context/NamedAttributeContextTest.cs new file mode 100644 index 0000000..b1f21f9 --- /dev/null +++ b/ExtentReports.Tests/Model/Context/NamedAttributeContextTest.cs @@ -0,0 +1,48 @@ +using System.Linq; +using System.Threading.Tasks; +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Model.Context; +using NUnit.Framework; + +namespace ExtentReports.Tests.Model.Context +{ + public class NamedAttributeContextTest + { + [Test] + public void ConcurrentAddTest() + { + // initialize with a tag name and test + var category = new Category("Category"); + var test = new Test("Test"); + var ctx = new NamedAttributeContext(category, test); + int rangeFor = 1000; + + var rng = Enumerable.Range(0, rangeFor); + Parallel.ForEach(rng, x => + { + var test = new Test(x.ToString()); + ctx.AddTest(test); + }); + Assert.AreEqual(1 + rangeFor, ctx.Count()); + } + + [Test] + public void ConcurrentAddRemoveTest() + { + // initialize with a tag name and test + var category = new Category("Category"); + var test = new Test("Test"); + var ctx = new NamedAttributeContext(category, test); + int rangeFor = 1000; + + var rng = Enumerable.Range(0, rangeFor); + Parallel.ForEach(rng, x => + { + var test = new Test(x.ToString()); + ctx.AddTest(test); + ctx.RemoveTest(test); + }); + Assert.AreEqual(1, ctx.Count()); + } + } +} diff --git a/ExtentReports.Tests/Model/DeviceEntityTest.cs b/ExtentReports.Tests/Model/DeviceEntityTest.cs new file mode 100644 index 0000000..b726306 --- /dev/null +++ b/ExtentReports.Tests/Model/DeviceEntityTest.cs @@ -0,0 +1,16 @@ +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Model +{ + class DeviceEntityTest + { + [Test] + public void DeviceName() + { + var name = "DeviceName"; + var device = new Device(name); + Assert.AreEqual(name, device.Name); + } + } +} diff --git a/ExtentReports.Tests/Model/LogEntityTest.cs b/ExtentReports.Tests/Model/LogEntityTest.cs new file mode 100644 index 0000000..a8721e6 --- /dev/null +++ b/ExtentReports.Tests/Model/LogEntityTest.cs @@ -0,0 +1,87 @@ +using AventStack.ExtentReports; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Model +{ + public class LogEntityTest + { + private Log _log; + + [SetUp] + public void Setup() + { + _log = new Log(Status.Pass); + } + + [Test] + public void DefaultStatusBuilder() + { + Assert.AreEqual(Status.Pass, _log.Status); + } + + [Test] + public void ChangedStatus() + { + _log.Status = Status.Fail; + Assert.AreEqual(Status.Fail, _log.Status); + _log.Status = Status.Pass; + Assert.AreEqual(Status.Pass, _log.Status); + } + + [Test] + public void TimestampNonNullOnInit() + { + Assert.NotNull(_log.Timestamp); + } + + [Test] + public void DetailsNullOnInit() + { + Assert.Null(_log.Details); + } + + [Test] + public void SeqNegOnInit() + { + Assert.AreEqual(_log.Seq, -1); + } + + [Test] + public void MediaEmptyOnInit() + { + Assert.AreEqual(_log.Media, null); + } + + [Test] + public void ExceptionsEmptyOnInit() + { + Assert.AreEqual(_log.ExceptionInfo, null); + } + + [Test] + public void AddMediaDefault() + { + Assert.False(_log.HasMedia); + } + + [Test] + public void AddMediaWithPathToLog() + { + Media m = new ScreenCapture("img.png"); + _log.AddMedia(m); + Assert.True(_log.HasMedia); + } + + [Test] + public void AddMediaWithResolvedPathToLog() + { + Media m = new ScreenCapture + { + ResolvedPath = "img.png" + }; + _log.AddMedia(m); + Assert.True(_log.HasMedia); + } + } +} diff --git a/ExtentReports.Tests/Model/ReportEntityTest.cs b/ExtentReports.Tests/Model/ReportEntityTest.cs new file mode 100644 index 0000000..d506f74 --- /dev/null +++ b/ExtentReports.Tests/Model/ReportEntityTest.cs @@ -0,0 +1,164 @@ +using System; +using System.Linq; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Model +{ + public class ReportEntityTest + { + private ExtentReports _extent; + private Report _report; + private Test _test; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + _report = new Report(); + _test = new Test("Test"); + } + + [Test] + public void StartAndEndTimesNonNullAtInit() + { + Assert.NotNull(_report.StartTime); + Assert.NotNull(_report.EndTime); + } + + [Test] + public void StartIsPassOnInit() + { + Assert.AreEqual(Status.Pass, _report.Status); + } + + [Test] + public void TestsEmptyOnInit() + { + Assert.True(_report.Tests.Count == 0); + } + + [Test] + public void StatsNonNullAtInit() + { + Assert.NotNull(_report.Stats); + } + + [Test] + public void ReportTestListSize() + { + Assert.AreEqual(0, _report.Tests.Count); + _report.Tests.Add(_test); + Assert.AreEqual(1, _report.Tests.Count); + } + + [Test] + public void ReportIsBDD() + { + Assert.False(_report.IsBDD); + _report.AddTest(_test); + Assert.False(_report.IsBDD); + _test.BddType = new Gherkin.GherkinKeyword("given"); + Assert.True(_report.IsBDD); + } + + [Test] + public void ReportTestHasStatus() + { + var skip = new Log(Status.Skip); + var pass = new Log(); + + _report.AddTest(_test); + Assert.True(_report.AnyTestHasStatus(Status.Pass)); + Assert.False(_report.AnyTestHasStatus(Status.Skip)); + + _test.AddLog(skip); + Assert.False(_report.AnyTestHasStatus(Status.Pass)); + Assert.True(_report.AnyTestHasStatus(Status.Skip)); + + _test.AddLog(pass); + Assert.False(_report.AnyTestHasStatus(Status.Pass)); + Assert.True(_report.AnyTestHasStatus(Status.Skip)); + } + + [Test] + public void AuthorCtx() + { + var context = _report.AuthorCtx; + Assert.AreEqual(0, context.Context.Count); + var author = new Author("x"); + _test.Author.Add(author); + _report.AuthorCtx.AddContext(author, _test); + Assert.AreEqual(1, context.Context.Count); + Assert.True(context.Context.Where(x => x.Key.Equals("x")).Any()); + Assert.AreEqual(1, context.Context.Select(x => x.Key.Equals("x")).ToList().Count); + Assert.AreEqual("Test", context.Context.Where(x => x.Key.Equals("x")).First().Value.Tests.First().Name); + } + + [Test] + public void CategoryCtx() + { + var context = _report.CategoryCtx; + Assert.AreEqual(0, context.Context.Count); + var cat = new Category("x"); + _test.Category.Add(cat); + _report.CategoryCtx.AddContext(cat, _test); + Assert.AreEqual(1, context.Context.Count); + Assert.True(context.Context.Where(x => x.Key.Equals("x")).Any()); + Assert.AreEqual(1, context.Context.Select(x => x.Key.Equals("x")).ToList().Count); + Assert.AreEqual("Test", context.Context.Where(x => x.Key.Equals("x")).First().Value.Tests.First().Name); + } + + [Test] + public void DeviceCtx() + { + var context = _report.DeviceCtx; + Assert.AreEqual(0, context.Context.Count); + var device = new Device("x"); + _test.Device.Add(device); + _report.DeviceCtx.AddContext(device, _test); + Assert.AreEqual(1, context.Context.Count); + Assert.True(context.Context.Where(x => x.Key.Equals("x")).Any()); + Assert.AreEqual(1, context.Context.Select(x => x.Key.Equals("x")).ToList().Count); + Assert.AreEqual("Test", context.Context.Where(x => x.Key.Equals("x")).First().Value.Tests.First().Name); + } + + [Test] + public void ExceptionContext() + { + var msg = "An exception has occurred."; + var ex = new Exception(msg); + Assert.AreEqual(0, _report.ExceptionInfoCtx.Context.Count); + var info = new ExceptionInfo(ex); + var log = new Log(Status.Fail) + { + ExceptionInfo = info + }; + _test.AddLog(log); + var device = new Device("x"); + _test.Device.Add(device); + _report.ExceptionInfoCtx.AddContext(info, _test); + Assert.AreEqual(1, _report.ExceptionInfoCtx.Context.Count); + Assert.True(_report.ExceptionInfoCtx.Context.Where(x => x.Key.Equals("System.Exception")).Any()); + Assert.AreEqual(1, _report.ExceptionInfoCtx.Context.Select(x => x.Key.Equals("System.Exception")).ToList().Count); + Assert.AreEqual("Test", _report.ExceptionInfoCtx.Context.Where(x => x.Key.Equals("System.Exception")).First().Value.Tests.First().Name); + } + + [Test] + public void TestRunnerLogs() + { + var s = new string[] { "Log 1", "Log 2", "Log 3" }; + Assert.AreEqual(0, _report.Logs.Count); + s.ToList().ForEach(x => _report.Logs.Enqueue(x)); + Assert.AreEqual(3, _report.Logs.Count); + s.ToList().ForEach(x => Assert.True(_report.Logs.Contains(x))); + } + + [Test] + public void TimeTaken() + { + var duration = _report.TimeTaken; + Assert.True(duration.TotalMilliseconds < 5); + } + } +} diff --git a/ExtentReports.Tests/Model/ReportStatsConcurrentTest.cs b/ExtentReports.Tests/Model/ReportStatsConcurrentTest.cs new file mode 100644 index 0000000..9e7f138 --- /dev/null +++ b/ExtentReports.Tests/Model/ReportStatsConcurrentTest.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Model +{ + public class ReportStatsConcurrentTest + { + [Test] + public void ConcurrentUpdateFlush() + { + var extent = new ExtentReports(); + IEnumerable rng = Enumerable.Range(0, 1000); + Parallel.ForEach(rng, x => { + extent.CreateTest("Test").Pass(""); + extent.Flush(); + }); + Assert.AreEqual(1000, extent.Report.Tests.Count); + } + } +} diff --git a/ExtentReports.Tests/Model/ReportStatsTest.cs b/ExtentReports.Tests/Model/ReportStatsTest.cs new file mode 100644 index 0000000..1215be7 --- /dev/null +++ b/ExtentReports.Tests/Model/ReportStatsTest.cs @@ -0,0 +1,215 @@ +using AventStack.ExtentReports.Model; +using NUnit.Framework; +using System; +using System.Linq; + +namespace AventStack.ExtentReports.Tests.Model +{ + class ReportStatsTest + { + [Test] + public void AnalysisStrategyDefault() + { + var stats = new ReportStats(); + Assert.AreEqual(AnalysisStrategy.Test, stats.AnalysisStrategy); + } + + [Test] + public void AllLevelMapsNonNull() + { + var stats = new ReportStats(); + Assert.NotNull(stats.Child); + Assert.NotNull(stats.ChildPercentage); + Assert.NotNull(stats.Grandchild); + Assert.NotNull(stats.GrandchildPercentage); + Assert.NotNull(stats.Log); + Assert.NotNull(stats.LogPercentage); + Assert.NotNull(stats.Parent); + Assert.NotNull(stats.ParentPercentage); + } + + [Test] + public void StatsCount() + { + var report = new Report(); + + Assert.AreEqual(0, report.Stats.Parent.Count); + + report.Stats.Update(report.Tests); + Assert.AreEqual(Enum.GetValues(typeof(Status)).Length, report.Stats.Parent.Count); + } + + [Test] + public void AllStatsPresent() + { + var report = new Report(); + report.Stats.Update(report.Tests); + + // check if all Status fields are present + var list = Enum.GetValues(typeof(Status)).Cast().ToList(); + list.ForEach(x => Assert.True(report.Stats.Parent.ContainsKey(x))); + list.ForEach(x => Assert.True(report.Stats.Child.ContainsKey(x))); + list.ForEach(x => Assert.True(report.Stats.Grandchild.ContainsKey(x))); + list.ForEach(x => Assert.True(report.Stats.Log.ContainsKey(x))); + } + + [Test] + public void ParentStatsCounts() + { + var report = new Report(); + report.Stats.Update(report.Tests); + Assert.AreEqual(0, report.Stats.Parent[Status.Pass]); + Assert.AreEqual(0, report.Stats.Parent[Status.Fail]); + Assert.AreEqual(0, report.Stats.Parent[Status.Skip]); + Assert.AreEqual(0, report.Stats.Parent[Status.Warning]); + Assert.AreEqual(0, report.Stats.Parent[Status.Info]); + } + + [Test] + public void ChildStatsCounts() + { + var report = new Report(); + report.Stats.Update(report.Tests); + Assert.AreEqual(0, report.Stats.Child[Status.Pass]); + Assert.AreEqual(0, report.Stats.Child[Status.Fail]); + Assert.AreEqual(0, report.Stats.Child[Status.Skip]); + Assert.AreEqual(0, report.Stats.Child[Status.Warning]); + Assert.AreEqual(0, report.Stats.Child[Status.Info]); + } + + [Test] + public void GrandchildStatsCounts() + { + var report = new Report(); + report.Stats.Update(report.Tests); + Assert.AreEqual(0, report.Stats.Grandchild[Status.Pass]); + Assert.AreEqual(0, report.Stats.Grandchild[Status.Fail]); + Assert.AreEqual(0, report.Stats.Grandchild[Status.Skip]); + Assert.AreEqual(0, report.Stats.Grandchild[Status.Warning]); + Assert.AreEqual(0, report.Stats.Grandchild[Status.Info]); + } + + [Test] + public void StatsTestStatus() + { + var test = new Test("Test"); + var report = new Report(); + report.AddTest(test); + report.Stats.Update(report.Tests); + + // check if all Status fields are present + var list = Enum.GetValues(typeof(Status)).Cast().ToList(); + list.ForEach(x => Assert.True(report.Stats.Parent.ContainsKey(x))); + list.ForEach(x => Assert.True(report.Stats.Child.ContainsKey(x))); + list.ForEach(x => Assert.True(report.Stats.Grandchild.ContainsKey(x))); + list.ForEach(x => Assert.True(report.Stats.Log.ContainsKey(x))); + + test.Status = Status.Fail; + report.Stats.Update(report.Tests); + Assert.AreEqual(0, report.Stats.Parent[Status.Pass]); + Assert.AreEqual(1, report.Stats.Parent[Status.Fail]); + } + + [Test] + public void StatsChildStatus() + { + var test = new Test("Test"); + var node = new Test("Node") + { + Status = Status.Skip + }; + test.AddChild(node); + + var report = new Report(); + report.AddTest(test); + + report.Stats.Update(report.Tests); + + Assert.AreEqual(0, report.Stats.Parent[Status.Pass]); + Assert.AreEqual(1, report.Stats.Parent[Status.Skip]); + Assert.AreEqual(0, report.Stats.Child[Status.Pass]); + Assert.AreEqual(1, report.Stats.Child[Status.Skip]); + } + + [Test] + public void StatsMultipleChildStatus() + { + var test = new Test("Test"); + var node1 = new Test("Node1"); + var node2 = new Test("Node2"); + node1.Status = Status.Skip; + node2.Status = Status.Fail; + test.AddChild(node1); + test.AddChild(node2); + + var report = new Report(); + report.AddTest(test); + + report.Stats.Update(report.Tests); + + Assert.AreEqual(0, report.Stats.Parent[Status.Pass]); + Assert.AreEqual(0, report.Stats.Parent[Status.Skip]); + Assert.AreEqual(1, report.Stats.Parent[Status.Fail]); + Assert.AreEqual(0, report.Stats.Child[Status.Pass]); + Assert.AreEqual(1, report.Stats.Child[Status.Skip]); + Assert.AreEqual(1, report.Stats.Child[Status.Fail]); + } + + [Test] + public void StatsGrandchildStatus() + { + var test = new Test("Test"); + var node = new Test("Node"); + var grandchild = new Test("Grandchild") + { + Status = Status.Fail + }; + node.AddChild(grandchild); + test.AddChild(node); + + var report = new Report(); + report.AddTest(test); + + report.Stats.Update(report.Tests); + + Assert.AreEqual(0, report.Stats.Parent[Status.Pass]); + Assert.AreEqual(1, report.Stats.Parent[Status.Fail]); + Assert.AreEqual(0, report.Stats.Child[Status.Pass]); + Assert.AreEqual(1, report.Stats.Child[Status.Fail]); + Assert.AreEqual(0, report.Stats.Grandchild[Status.Pass]); + Assert.AreEqual(1, report.Stats.Grandchild[Status.Fail]); + } + + [Test] + public void StatsLogStatus() + { + var test = new Test("Test"); + var node = new Test("Node"); + test.AddChild(node); + + test.AddLog(new Log(Status.Skip)); + test.AddLog(new Log(Status.Skip)); + test.AddLog(new Log(Status.Info)); + test.AddLog(new Log(Status.Pass)); + + node.AddLog(new Log(Status.Fail)); + node.AddLog(new Log(Status.Fail)); + node.AddLog(new Log(Status.Info)); + node.AddLog(new Log(Status.Pass)); + + test.UpdateResult(); + + var report = new Report(); + report.AddTest(test); + + report.Stats.Update(report.Tests); + + Assert.AreEqual(1, report.Stats.Parent[Status.Fail]); + Assert.AreEqual(1, report.Stats.Child[Status.Fail]); + Assert.AreEqual(2, report.Stats.Log[Status.Skip]); + Assert.AreEqual(2, report.Stats.Log[Status.Fail]); + Assert.AreEqual(2, report.Stats.Log[Status.Pass]); + Assert.AreEqual(2, report.Stats.Log[Status.Info]); + } + } +} diff --git a/ExtentReports.Tests/Model/ScreenCaptureTest.cs b/ExtentReports.Tests/Model/ScreenCaptureTest.cs new file mode 100644 index 0000000..5de367f --- /dev/null +++ b/ExtentReports.Tests/Model/ScreenCaptureTest.cs @@ -0,0 +1,18 @@ +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Model +{ + public class ScreenCaptureTest + { + [Test] + public void InitWithAllEntitiesNull() + { + var capture = new ScreenCapture(); + Assert.Null(capture.Base64); + Assert.Null(capture.Path); + Assert.Null(capture.ResolvedPath); + Assert.Null(capture.Title); + } + } +} diff --git a/ExtentReports.Tests/Model/StatusTest.cs b/ExtentReports.Tests/Model/StatusTest.cs new file mode 100644 index 0000000..650f04a --- /dev/null +++ b/ExtentReports.Tests/Model/StatusTest.cs @@ -0,0 +1,27 @@ +using AventStack.ExtentReports.Extensions; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Model +{ + public class StatusTest + { + private Status[] RandomHierarchy() + { + var arr = (Status[]) Status.GetValues(typeof(Status)); + return arr; + } + + [Test] + public void StatusMax() + { + Assert.AreEqual(Status.Fail, StatusExtensions.Max(RandomHierarchy())); + } + + [Test] + public void StatusMin() + { + Assert.AreEqual(Status.Info, StatusExtensions.Min(RandomHierarchy())); + } + } +} diff --git a/ExtentReports.Tests/Model/TestEntityTest.cs b/ExtentReports.Tests/Model/TestEntityTest.cs new file mode 100644 index 0000000..4e4da80 --- /dev/null +++ b/ExtentReports.Tests/Model/TestEntityTest.cs @@ -0,0 +1,346 @@ +using System; +using System.Linq; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Model +{ + public class TestEntityTest + { + private const string Name = "Test"; + private Test _test; + + [SetUp] + public void Setup() + { + _test = new Test(Name); + } + + [Test] + public void LogSeqIncrements() + { + var log = new Log(); + Enumerable.Range(0, 99).ToList().ForEach(x => + { + _test.AddLog(log); + Assert.AreEqual(x+1, log.Seq); + }); + } + + [Test] + public void TestEntities() + { + Assert.AreEqual(_test.Author.Count, 0); + Assert.AreEqual(_test.Device.Count, 0); + Assert.AreEqual(_test.Category.Count, 0); + Assert.AreEqual(_test.Children.Count, 0); + Assert.True(_test.Leaf); + Assert.AreEqual(_test.Level, 0); + Assert.AreEqual(_test.Status, Status.Pass); + Assert.Null(_test.Description); + } + + [Test] + public void AddNullChildToTest() + { + Assert.Throws(typeof(ArgumentNullException), () => _test.AddChild(null)); + } + + [Test] + public void AddChildToTest() + { + var node = new Test("Node"); + _test.AddChild(node); + Assert.AreEqual(_test.Children.Count, 1); + _test.AddChild(node); + Assert.AreEqual(_test.Children.Count, 2); + } + + [Test] + public void AddChildToTestLevel() + { + var node = new Test("Node"); + _test.AddChild(node); + Assert.AreEqual(_test.Level, 0); + Assert.AreEqual(node.Level, 1); + } + + [Test] + public void AddChildToTestLeaf() + { + var node = new Test("Node"); + _test.AddChild(node); + Assert.False(_test.Leaf); + Assert.True(node.Leaf); + } + + [Test] + public void AddNullLogToTest() + { + var logs = _test.Logs.Count; + _test.AddLog(null); + Assert.AreEqual(logs, _test.Logs.Count); + } + + [Test] + public void AddLogToTest() + { + var log = new Log(); + var test = new Test(Name); + test.AddLog(log); + Assert.AreEqual(1, log.Seq); + Assert.AreEqual(1, test.Logs.Count); + Assert.AreEqual(Status.Pass, test.Status); + Assert.AreEqual(Status.Pass, log.Status); + } + + [Test] + public void AddSkipLogToTest() + { + var log = new Log(Status.Skip); + _test.AddLog(log); + Assert.AreEqual(_test.Status, Status.Skip); + Assert.AreEqual(log.Status, Status.Skip); + } + + [Test] + public void AddFailLogToTest() + { + var log = new Log(Status.Fail); + _test.AddLog(log); + Assert.AreEqual(_test.Status, Status.Fail); + Assert.AreEqual(log.Status, Status.Fail); + } + + [Test] + public void TestHasLog() + { + Assert.False(_test.HasLog); + var log = new Log(); + _test.AddLog(log); + Assert.True(_test.HasLog); + } + + [Test] + public void IsTestBDD() + { + Assert.False(_test.IsBdd); + _test.BddType = new Gherkin.GherkinKeyword("given"); + Assert.True(_test.IsBdd); + } + + [Test] + public void TestHasChildren() + { + Assert.False(_test.HasChildren); + var node = new Test(Name); + _test.AddChild(node); + Assert.True(_test.HasChildren); + } + + [Test] + public void TestStatusWithoutLog() + { + Assert.AreEqual(_test.Status, Status.Pass); + } + + [Test] + public void TestStatusWithLog() + { + Assert.AreEqual(_test.Status, Status.Pass); + var log = new Log(Status.Fail); + _test.AddLog(log); + Assert.AreEqual(_test.Status, Status.Fail); + } + + [Test] + public void TestStatusWithLogStatusChanged() + { + Assert.AreEqual(_test.Status, Status.Pass); + var log = new Log(Status.Skip); + _test.AddLog(log); + Assert.AreEqual(_test.Status, Status.Skip); + log.Status = (Status.Fail); + //_test.UpdateResult(); + //Assert.AreEqual(_test.Status, Status.Fail); + } + + [Test] + public void HasAuthor() + { + Assert.False(_test.HasAuthor); + _test.Author.Add(new Author("x")); + Assert.True(_test.HasAuthor); + } + + [Test] + public void HasCategory() + { + Assert.False(_test.HasCategory); + _test.Category.Add(new Category("x")); + Assert.True(_test.HasCategory); + } + + [Test] + public void HasDevice() + { + Assert.False(_test.HasDevice); + _test.Device.Add(new Device("x")); + Assert.True(_test.HasDevice); + } + + [Test] + public void HasAttributes() + { + Assert.False(_test.HasAttributes); + + _test.Author.Add(new Author("x")); + Assert.True(_test.HasAttributes); + + _test = new Test(Name); + _test.Device.Add(new Device("x")); + Assert.True(_test.HasAttributes); + + _test = new Test(Name); + _test.Category.Add(new Category("x")); + Assert.True(_test.HasAttributes); + } + + [Test] + public void TestFullName() + { + var name = new String[] { "Test", "Child", "Grandchild" }; + var test = new Test(name[0]); + var child = new Test(name[1]); + var grandchild = new Test(name[2]); + test.AddChild(child); + child.AddChild(grandchild); + Assert.AreEqual(name[0], test.FullName); + Assert.AreEqual(name[0] + "." + name[1], child.FullName); + Assert.AreEqual(grandchild.FullName, + name[0] + "." + name[1] + "." + name[2]); + } + + [Test] + public void HasScreenCapture() + { + Assert.False(_test.HasScreenCapture); + _test.AddMedia(new ScreenCapture()); + Assert.False(_test.HasScreenCapture); + _test.AddMedia(new ScreenCapture("/img")); + Assert.True(_test.HasScreenCapture); + } + + [Test] + public void ComputeTestStatusNoLog() + { + _test.UpdateResult(); + Assert.AreEqual(Status.Pass, _test.Status); + } + + [Test] + public void ComputeTestStatusSkipLog() + { + _test.AddLog(new Log(Status.Skip)); + _test.UpdateResult(); + Assert.AreEqual(Status.Skip, _test.Status); + } + + [Test] + public void ComputeTestStatusSkipAndFailLog() + { + _test.AddLog(new Log(Status.Skip)); + _test.AddLog(new Log(Status.Fail)); + _test.UpdateResult(); + Assert.AreEqual(Status.Fail, _test.Status); + } + + [Test] + public void ComputeTestStatusNode() + { + var parent = new Test(""); + var node = new Test(""); + parent.AddChild(node); + node.AddLog(new Log(Status.Skip)); + parent.UpdateResult(); + Assert.AreEqual(Status.Skip, parent.Status); + Assert.AreEqual(Status.Skip, node.Status); + node.AddLog(new Log(Status.Fail)); + parent.UpdateResult(); + Assert.AreEqual(Status.Fail, parent.Status); + Assert.AreEqual(Status.Fail, node.Status); + } + + [Test] + public void ComputeTestStatusAndNodeStatus() + { + var parent = new Test(""); + var node = new Test(""); + parent.AddChild(node); + node.AddLog(new Log(Status.Skip)); + parent.UpdateResult(); + Assert.AreEqual(Status.Skip, parent.Status); + Assert.AreEqual(Status.Skip, node.Status); + parent.AddLog(new Log(Status.Fail)); + parent.UpdateResult(); + Assert.AreEqual(Status.Fail, parent.Status); + Assert.AreEqual(Status.Skip, node.Status); + } + + [Test] + public void Ancestor() + { + var parent = new Test(""); + var node = new Test(""); + var child = new Test(""); + parent.AddChild(node); + node.AddChild(child); + Assert.AreEqual(parent.Ancestor, parent); + Assert.AreEqual(node.Ancestor, parent); + Assert.AreEqual(child.Ancestor, parent); + } + /* + [Test] + public void generatedLog() + { + Test test = getTest(); + Logs log = Logs.builder().status(Status.Skip).details("details").build(); + _test.addGeneratedLog(log); + Assert.AreEqual(_test.getGeneratedLog.Count, 1); + Assert.AreEqual(_test.Logs.Count, 0); + Assert.AreEqual(_test.Status, Status.Skip); + } + + [Test] + public void testHasAngLogWithNoLogs() + { + Test test = getTest(); + Assert.False(_test.hasAnyLog()); + } + + [Test] + public void testHasAngLogWithLog() + { + Test test = getTest(); + Logs log = Logs.builder().status(Status.Skip).details("details").build(); + _test.AddLog(log); + Assert.True(_test.hasAnyLog()); + } + + [Test] + public void testHasAngLogWithGeneratedLog() + { + Test test = getTest(); + Logs log = Logs.builder().status(Status.Skip).details("details").build(); + _test.addGeneratedLog(log); + Assert.True(_test.hasAnyLog()); + } + */ + [Test] + public void TimeTaken() + { + double duration = _test.TimeTaken; + Assert.True(duration < 5); + } + } +} diff --git a/ExtentReports.Tests/Model/TestIdsTests.cs b/ExtentReports.Tests/Model/TestIdsTests.cs new file mode 100644 index 0000000..dffeb44 --- /dev/null +++ b/ExtentReports.Tests/Model/TestIdsTests.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.Linq; +using AventStack.ExtentReports.Model; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Model +{ + public class TestIdsTests + { + [Test] + public void TestIdTest() + { + var incr = 100; + var set = new HashSet(); + Enumerable.Range(0, incr).ToList().ForEach(x => set.Add(new Test(Name).Id)); + Assert.AreEqual(incr, set.Count); + } + + private const string Name = "Test"; + } +} diff --git a/ExtentReports.Tests/Model/TestInitTests.cs b/ExtentReports.Tests/Model/TestInitTests.cs new file mode 100644 index 0000000..cec12ba --- /dev/null +++ b/ExtentReports.Tests/Model/TestInitTests.cs @@ -0,0 +1 @@ +using AventStack.ExtentReports.Model; using NUnit.Framework; namespace AventStack.ExtentReports.Tests { public class TestInitTests { [SetUp] public void Setup() { _test = new Test(Name); } [Test] public void StartAndEndTimesNonNullAtInit() { Assert.NotNull(_test.StartTime); Assert.NotNull(_test.EndTime); } [Test] public void StartIsPassOnInit() { Assert.AreEqual(Status.Pass, _test.Status); } [Test] public void LevelIs0OnInit() { Assert.AreEqual(0, _test.Level); } [Test] public void TestIsLeafOnInit() { Assert.True(_test.Leaf); } [Test] public void ChildrenEmptyOnInit() { Assert.True(_test.Children.Count == 0); } [Test] public void LogsEmptyOnInit() { Assert.True(_test.Children.Count == 0); } [Test] public void AuthorsEmptyOnInit() { Assert.True(_test.Author.Count == 0); } [Test] public void DevicesEmptyOnInit() { Assert.True(_test.Device.Count == 0); } [Test] public void TagEmptyOnInit() { Assert.True(_test.Category.Count == 0); } [Test] public void DescriptionNullOnInit() { Assert.Null(_test.Description); } [Test] public void ParentNullOnInit() { Assert.Null(_test.Parent); } private const string Name = "Test"; private Test _test; } } \ No newline at end of file diff --git a/ExtentReports.Tests/Reporter/SparkOutputTagTest.cs b/ExtentReports.Tests/Reporter/SparkOutputTagTest.cs new file mode 100644 index 0000000..490531e --- /dev/null +++ b/ExtentReports.Tests/Reporter/SparkOutputTagTest.cs @@ -0,0 +1,40 @@ +using System.IO; +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Reporter; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Reporter +{ + public class SparkOutputTagTest + { + private const string Path = "spark.html"; + private const string Tag = "TAG#1234"; + + private ExtentReports _extent; + + [SetUp] + public void Setup() + { + _extent = new ExtentReports(); + _extent.AttachReporter(new ExtentSparkReporter(Path)); + } + + [Test] + public void TestTag() + { + _extent.CreateTest("Test").AssignCategory(Tag); + _extent.Flush(); + var text = File.ReadAllText(Path); + Assert.True(text.Contains(Tag)); + } + + [Test] + public void NodeTag() + { + _extent.CreateTest("Test").CreateNode("Node").AssignCategory(Tag); + _extent.Flush(); + var text = File.ReadAllText(Path); + Assert.True(text.Contains(Tag)); + } + } +} diff --git a/ExtentReports.Tests/Reporter/SparkReporterTest.cs b/ExtentReports.Tests/Reporter/SparkReporterTest.cs new file mode 100644 index 0000000..8cb180b --- /dev/null +++ b/ExtentReports.Tests/Reporter/SparkReporterTest.cs @@ -0,0 +1,139 @@ +using AventStack.ExtentReports.Reporter; +using NUnit.Framework; +using System; +using System.IO; +using System.Linq; + +namespace AventStack.ExtentReports.Tests.Reporter +{ + public class SparkReporterTest + { + private const string FileName = "spark.html"; + private const string Parent = "Parent"; + private const string Child = "Child"; + private const string Grandchild = "Grandchild"; + private const string Scripts = "spark-script.js"; + private const string Stylesheet = "spark-style.css"; + + private ExtentReports _extent; + private ExtentSparkReporter _spark; + private string _path; + + [SetUp] + public void Setup() + { + _path = DateTime.Now.Millisecond + FileName; + _extent = new ExtentReports(); + _spark = new ExtentSparkReporter(_path); + _extent.AttachReporter(_spark); + } + + private void AssertFileExists(bool delete = true) + { + Assert.True(File.Exists(_path)); + + if (delete) + { + File.Delete(_path); + } + } + + [Test] + public void CreatesReportWithNoTestsInitPath() + { + _extent.Flush(); + Assert.False(File.Exists(_path)); + } + + [Test] + public void ReportContainsTestsAndNodes() + { + _extent.CreateTest(Parent) + .CreateNode(Child) + .CreateNode(Grandchild) + .Pass("Pass"); + _extent.Flush(); + AssertFileExists(); + Assert.AreEqual(_spark.Report.Tests.Count, 1); + + var list = _spark.Report.Tests.ToList(); + var children = list[0].Children.ToList(); + var grandchildren = children[0].Children.ToList(); + + Assert.AreEqual(list[0].Name, Parent); + Assert.AreEqual(list[0].Children.Count, 1); + Assert.AreEqual(children[0].Name, Child); + Assert.AreEqual(grandchildren.Count, 1); + Assert.AreEqual(grandchildren[0].Name, Grandchild); + } + + [Test] + public void ReportContainsTestsAndNodesTags() + { + _extent.CreateTest(Parent).AssignCategory("Tag1") + .CreateNode(Child).AssignCategory("Tag2") + .CreateNode(Grandchild).AssignCategory("Tag3") + .Pass("Pass"); + _extent.Flush(); + AssertFileExists(); + + var list = _spark.Report.Tests.ToList(); + var children = list[0].Children.ToList(); + var grandchildren = children[0].Children.ToList(); + + Assert.True(list[0].Category.Any(x => x.Name.Equals("Tag1"))); + Assert.True(children[0].Category.Any(x => x.Name.Equals("Tag2"))); + Assert.True(grandchildren[0].Category.Any(x => x.Name.Equals("Tag2"))); + } + + [Test] + public void ReportContainsTestsAndNodesUsers() + { + _extent.CreateTest(Parent).AssignAuthor("Tag1") + .CreateNode(Child).AssignAuthor("Tag2") + .CreateNode(Grandchild).AssignAuthor("Tag3") + .Pass("Pass"); + _extent.Flush(); + AssertFileExists(); + + var list = _spark.Report.Tests.ToList(); + var children = list[0].Children.ToList(); + var grandchildren = children[0].Children.ToList(); + + Assert.True(list[0].Author.Any(x => x.Name.Equals("Tag1"))); + Assert.True(children[0].Author.Any(x => x.Name.Equals("Tag2"))); + Assert.True(grandchildren[0].Author.Any(x => x.Name.Equals("Tag2"))); + } + + [Test] + public void ReportContainsTestsAndNodesDevices() + { + _extent.CreateTest(Parent).AssignDevice("Tag1") + .CreateNode(Child).AssignDevice("Tag2") + .CreateNode(Grandchild).AssignDevice("Tag3") + .Pass("Pass"); + _extent.Flush(); + AssertFileExists(); + + var list = _spark.Report.Tests.ToList(); + var children = list[0].Children.ToList(); + var grandchildren = children[0].Children.ToList(); + + Assert.True(list[0].Device.Any(x => x.Name.Equals("Tag1"))); + Assert.True(children[0].Device.Any(x => x.Name.Equals("Tag2"))); + Assert.True(grandchildren[0].Device.Any(x => x.Name.Equals("Tag2"))); + } + + [Test] + public void SparkOffline() + { + _spark.Config.OfflineMode = true; + + _extent.CreateTest(Parent).Pass("Pass"); + _extent.Flush(); + AssertFileExists(false); + Assert.True(File.Exists("extent/" + Scripts)); + Assert.True(File.Exists("extent/" + Stylesheet)); + } + } +} diff --git a/ExtentReports.Tests/Usage/Base.cs b/ExtentReports.Tests/Usage/Base.cs new file mode 100644 index 0000000..78e77e9 --- /dev/null +++ b/ExtentReports.Tests/Usage/Base.cs @@ -0,0 +1,38 @@ +using AventStack.ExtentReports.MarkupUtils; +using AventStack.ExtentReports.Tests.Usage.Core; +using NUnit.Framework; +using NUnit.Framework.Interfaces; + +namespace AventStack.ExtentReports.Tests.Usage +{ + public class Base + { + [SetUp] + protected void Setup() + { + ExtentTestManager.CreateTest(); + } + + [TearDown] + protected void Teardown() + { + if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed) + { + ExtentTestManager.Test.Value.Fail(MarkupHelper.CreateCodeBlock(TestContext.CurrentContext.Result.Message)); + } + else if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Inconclusive || TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Warning) + { + ExtentTestManager.Test.Value.Warning("Warning"); + } + else if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Skipped) + { + ExtentTestManager.Test.Value.Skip("Skip"); + } + else + { + ExtentTestManager.Test.Value.Pass("Pass"); + } + + } + } +} diff --git a/ExtentReports.Tests/Usage/Core/ExtentManager.cs b/ExtentReports.Tests/Usage/Core/ExtentManager.cs new file mode 100644 index 0000000..788f70c --- /dev/null +++ b/ExtentReports.Tests/Usage/Core/ExtentManager.cs @@ -0,0 +1,31 @@ +using AventStack.ExtentReports.Reporter; + +namespace AventStack.ExtentReports.Tests.Usage.Core +{ + internal sealed class ExtentManager + { + private ExtentManager() { } + + public static ExtentReports Instance + { + get + { + if (_extent == null) + { + Init(); + } + + return _extent; + } + } + + private static ExtentReports _extent; + + public static void Init() + { + var extent = new ExtentReports(); + extent.AttachReporter(new ExtentSparkReporter("spark.html")); + _extent = extent; + } + } +} diff --git a/ExtentReports.Tests/Usage/Core/ExtentTestManager.cs b/ExtentReports.Tests/Usage/Core/ExtentTestManager.cs new file mode 100644 index 0000000..a84c05b --- /dev/null +++ b/ExtentReports.Tests/Usage/Core/ExtentTestManager.cs @@ -0,0 +1,32 @@ +using NUnit.Framework; +using System.Collections.Generic; +using System.Threading; + +namespace AventStack.ExtentReports.Tests.Usage.Core +{ + internal class ExtentTestManager + { + private static Dictionary Parent = new Dictionary(); + public static ThreadLocal Test = new ThreadLocal(); + + private static readonly object _synclock = new object(); + + public static ExtentTest CreateTest() + { + var className = TestContext.CurrentContext.Test.ClassName; + var testName = TestContext.CurrentContext.Test.Name; + + lock (_synclock) + { + if (!Parent.ContainsKey(className)) + { + Parent[className] = ExtentManager.Instance.CreateTest(className); + } + + Test.Value = Parent[className].CreateNode(testName); + } + + return Test.Value; + } + } +} diff --git a/ExtentReports.Tests/Usage/Login.cs b/ExtentReports.Tests/Usage/Login.cs new file mode 100644 index 0000000..47f5097 --- /dev/null +++ b/ExtentReports.Tests/Usage/Login.cs @@ -0,0 +1,19 @@ +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Usage +{ + public class Login : Base + { + [Test] + public void AssertTrue() + { + Assert.True(true); + } + + [Test] + public void AssertFalse() + { + //Assert.False(true); + } + } +} diff --git a/ExtentReports.Tests/Usage/Logout.cs b/ExtentReports.Tests/Usage/Logout.cs new file mode 100644 index 0000000..7355469 --- /dev/null +++ b/ExtentReports.Tests/Usage/Logout.cs @@ -0,0 +1,31 @@ +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Usage +{ + public class Logout : Base + { + [Test] + public void AssertTrue1() + { + Assert.True(true); + } + + [Test] + public void AssertFalse2() + { + //Assert.False(true); + } + + [Test] + public void AssertTrue3() + { + Assert.True(true); + } + + [Test] + public void AssertFalse4() + { + //Assert.False(true); + } + } +} diff --git a/ExtentReports.Tests/Usage/TestOneTimeSetup.cs b/ExtentReports.Tests/Usage/TestOneTimeSetup.cs new file mode 100644 index 0000000..478066d --- /dev/null +++ b/ExtentReports.Tests/Usage/TestOneTimeSetup.cs @@ -0,0 +1,15 @@ +using AventStack.ExtentReports.Tests.Usage.Core; +using NUnit.Framework; + +namespace AventStack.ExtentReports.Tests.Usage +{ + [SetUpFixture] + public class TestOneTimeSetup + { + [OneTimeTearDown] + protected void Teardown() + { + ExtentManager.Instance.Flush(); + } + } +} diff --git a/ExtentReports.sln b/ExtentReports.sln new file mode 100644 index 0000000..47ff0f3 --- /dev/null +++ b/ExtentReports.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34024.191 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExtentReports", "ExtentReports\ExtentReports.csproj", "{B80E46C7-1107-44EF-BAD2-683167699270}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExtentReports.Tests", "ExtentReports.Tests\ExtentReports.Tests.csproj", "{27C87D4D-6D19-4538-8407-9CC0F9865149}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KlovReporter", "KlovReporter\KlovReporter.csproj", "{203A84FB-DF8E-4BF4-8425-314B4F910D48}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B80E46C7-1107-44EF-BAD2-683167699270}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B80E46C7-1107-44EF-BAD2-683167699270}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B80E46C7-1107-44EF-BAD2-683167699270}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B80E46C7-1107-44EF-BAD2-683167699270}.Release|Any CPU.Build.0 = Release|Any CPU + {27C87D4D-6D19-4538-8407-9CC0F9865149}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27C87D4D-6D19-4538-8407-9CC0F9865149}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27C87D4D-6D19-4538-8407-9CC0F9865149}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27C87D4D-6D19-4538-8407-9CC0F9865149}.Release|Any CPU.Build.0 = Release|Any CPU + {203A84FB-DF8E-4BF4-8425-314B4F910D48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {203A84FB-DF8E-4BF4-8425-314B4F910D48}.Debug|Any CPU.Build.0 = Debug|Any CPU + {203A84FB-DF8E-4BF4-8425-314B4F910D48}.Release|Any CPU.ActiveCfg = Release|Any CPU + {203A84FB-DF8E-4BF4-8425-314B4F910D48}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EA8B10A5-93EC-4130-A8F1-186F79242D02} + EndGlobalSection +EndGlobal diff --git a/ExtentReports/Collections/SynchronizedList.cs b/ExtentReports/Collections/SynchronizedList.cs new file mode 100644 index 0000000..fc21272 --- /dev/null +++ b/ExtentReports/Collections/SynchronizedList.cs @@ -0,0 +1,128 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace AventStack.ExtentReports.Collections +{ + public sealed class SynchronizedList : IList, IReadOnlyList + { + private readonly List _list = new List(); + + public T this[int index] + { + get + { + lock (_list) + { + return _list[index]; + } + } + set + { + lock (_list) + { + _list[index] = value; + } + } + } + + public int Count + { + get + { + lock (_list) + { + return _list.Count; + } + } + } + + public bool IsReadOnly + { + get + { + lock (_list) + { + return ((ICollection)_list).IsReadOnly; + } + } + } + + public void Add(T item) + { + lock (_list) + { + _list.Add(item); + } + } + + public void Clear() + { + lock (_list) + { + _list.Clear(); + } + } + + public bool Contains(T item) + { + lock (_list) + { + return _list.Contains(item); + } + } + + public void CopyTo(T[] array, int arrayIndex) + { + lock (_list) + { + _list.CopyTo(array, arrayIndex); + } + } + + public IEnumerator GetEnumerator() + { + lock (_list) + { + return _list.ToList().GetEnumerator(); + } + } + + public int IndexOf(T item) + { + lock (_list) + { + return _list.IndexOf(item); + } + } + + public void Insert(int index, T item) + { + lock (_list) + { + _list.Insert(index, item); + } + } + + public bool Remove(T item) + { + lock (_list) + { + return _list.Remove(item); + } + } + + public void RemoveAt(int index) + { + lock (_list) + { + _list.RemoveAt(index); + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + } +} diff --git a/ExtentReports/Config/ConfigStore.cs b/ExtentReports/Config/ConfigStore.cs new file mode 100644 index 0000000..1b0c963 --- /dev/null +++ b/ExtentReports/Config/ConfigStore.cs @@ -0,0 +1,37 @@ +using AventStack.ExtentReports.Extensions; +using System.Collections.Generic; + +namespace AventStack.ExtentReports.Config +{ + public class ConfigStore + { + public Dictionary Store { get; } = new Dictionary(); + + public bool IsEmpty => Store.Count == 0; + + public void AddConfig(string k, string v) + { + Store[k] = v; + } + + public void RemoveConfig(string k) + { + Store.Remove(k); + } + + public bool Contains(string k) + { + return Store.ContainsKey(k); + } + + public object GetConfig(string k) + { + return Store[k]; + } + + public void Extend(IDictionary dict) + { + Store.AddRange(dict); + } + } +} \ No newline at end of file diff --git a/ExtentReports/Config/JsonConfigLoader.cs b/ExtentReports/Config/JsonConfigLoader.cs new file mode 100644 index 0000000..1a48a83 --- /dev/null +++ b/ExtentReports/Config/JsonConfigLoader.cs @@ -0,0 +1,16 @@ +using Newtonsoft.Json; +using System.IO; + +namespace AventStack.ExtentReports.Config +{ + public class JsonConfigLoader + { + public void LoadJSONConfig(ref T config, string filePath) + { + var json = File.ReadAllText(filePath); + var serializer = new JsonSerializer(); + var jsonTextReader = new JsonTextReader(new StringReader(json)); + config = serializer.Deserialize(jsonTextReader); + } + } +} diff --git a/ExtentReports/Config/XmlConfigLoader.cs b/ExtentReports/Config/XmlConfigLoader.cs new file mode 100644 index 0000000..e2efded --- /dev/null +++ b/ExtentReports/Config/XmlConfigLoader.cs @@ -0,0 +1,16 @@ +using System.IO; +using System.Xml.Serialization; + +namespace AventStack.ExtentReports.Config +{ + internal class XmlConfigLoader + { + public void LoadXMLConfig(ref T config, string filePath) + { + var serializer = new XmlSerializer(typeof(T)); + var textReader = new StreamReader(filePath); + config = (T)serializer.Deserialize(textReader); + textReader.Close(); + } + } +} diff --git a/ExtentReports/Core/AbstractProcessor.cs b/ExtentReports/Core/AbstractProcessor.cs new file mode 100644 index 0000000..fc3bf12 --- /dev/null +++ b/ExtentReports/Core/AbstractProcessor.cs @@ -0,0 +1,125 @@ +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Model.Convert; +using System.IO; + +namespace AventStack.ExtentReports.Core +{ + public abstract class AbstractProcessor : ReactiveSubject + { + protected internal bool UsingNaturalConf = true; + + private string[] _mediaResolverPath; + + protected internal void OnTestCreated(Test test) + { + Report.AddTest(test); + } + + protected internal void OnTestRemoved(Test test) + { + Report.RemoveTest(test); + } + + protected internal void OnNodeCreated(Test node) + { + + } + + protected internal void OnLogCreated(Log log, Test test) + { + if (log.HasException) + { + Report.ExceptionInfoCtx.AddContext(log.ExceptionInfo, test); + } + } + + protected internal void OnMediaAdded(Media m, Test test) + { + TryResolveMediaPath(m); + } + + protected internal void OnMediaAdded(Media m, Log log, Test test) + { + TryResolveMediaPath(m); + } + + private void TryResolveMediaPath(Media media) + { + if (_mediaResolverPath == null || (media is ScreenCapture && ((ScreenCapture)media).Base64 != null)) + { + return; + } + + if (!File.Exists(media.Path)) + { + foreach (var p in _mediaResolverPath) + { + var path = Path.Combine(p, media.Path); + + if (File.Exists(path)) + { + media.ResolvedPath = path; + break; + } + + var name = Path.GetFileName(media.Path); + path = Path.Combine(p, name); + + if (File.Exists(path)) + { + media.ResolvedPath = path; + break; + } + } + } + } + + protected internal void TryResolveMediaPath(string[] path) + { + _mediaResolverPath = path; + } + + protected internal void OnAuthorAdded(Author x, Test test) + { + Report.AuthorCtx.AddContext(x, test); + } + + protected internal void OnCategoryAdded(Category x, Test test) + { + Report.CategoryCtx.AddContext(x, test); + } + + protected internal void OnDeviceAdded(Device x, Test test) + { + Report.DeviceCtx.AddContext(x, test); + } + + protected internal void OnFlush() + { + Report.Refresh(); + + if (!UsingNaturalConf) + { + Report.ApplyOverrideConf(); + } + + Flush(); + } + + protected internal void OnReportLogAdded(string log) + { + Report.Logs.Enqueue(log); + } + + protected internal void OnSystemInfoAdded(SystemEnvInfo env) + { + Report.SystemEnvInfo.Add(env); + } + + protected internal void ConvertRawEntities(ExtentReports extent, string filePath) + { + var parser = new TestEntityParser(extent); + parser.CreateEntities(filePath); + } + } +} diff --git a/extentreports-dotnet-core/AnalysisStrategy.cs b/ExtentReports/Core/AnalysisStrategy.cs similarity index 100% rename from extentreports-dotnet-core/AnalysisStrategy.cs rename to ExtentReports/Core/AnalysisStrategy.cs diff --git a/ExtentReports/Core/ExtentReports.cs b/ExtentReports/Core/ExtentReports.cs new file mode 100644 index 0000000..45c3f95 --- /dev/null +++ b/ExtentReports/Core/ExtentReports.cs @@ -0,0 +1,149 @@ +using AventStack.ExtentReports.Core; +using AventStack.ExtentReports.Gherkin; +using AventStack.ExtentReports.Gherkin.Model; +using AventStack.ExtentReports.Listener.Entity; +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Reporter; +using System; +using System.Collections.Generic; + +namespace AventStack.ExtentReports +{ + public class ExtentReports : AbstractProcessor + { + public string GherkinDialect + { + get => GherkinDialectProvider.Lang; + set => GherkinDialectProvider.Lang = value; + } + + public bool UseNaturalTime + { + get => UsingNaturalConf; + set => UsingNaturalConf = value; + } + + public Status Status => Report.Status; + + public new Report Report => base.Report; + + public void AttachReporter(params IObserver[] observer) + { + foreach (IObserver x in observer) + { + Subscribe(x); + } + } + + public ExtentTest CreateTest(GherkinKeyword keyword, string name, string description = "") + { + var test = new ExtentTest(this, keyword, name, description); + OnTestCreated(test.Test); + return test; + } + + public ExtentTest CreateTest(string name, string description = "") where T : IGherkinFormatterModel + { + var type = typeof(T).Name; + var keyword = new GherkinKeyword(type); + return CreateTest(keyword, name, description); + } + + public ExtentTest CreateTest(string name, string description = "") + { + var test = new ExtentTest(this, name, description); + OnTestCreated(test.Test); + return test; + } + + public void RemoveTest(int id) + { + Report.RemoveTest(id); + } + + public void RemoveTest(string name) + { + var test = Report.FindTest(name); + Report.RemoveTest(test); + } + + public void RemoveTest(ExtentTest test) + { + Report.RemoveTest(test.Test); + } + + public new void Flush() + { + OnFlush(); + } + + public void AddSystemInfo(string name, string value) + { + OnSystemInfoAdded(new SystemEnvInfo(name, value)); + } + + /// + /// Adds logs from test framework tools to the test-runner logs view (if available in the reporter) + /// + /// + public void AddTestRunnerLogs(string log) + { + OnReportLogAdded(log); + } + + /// + /// Adds logs from test framework tools to the test-runner logs view (if available in the reporter) + /// + /// + public void AddTestRunnerLogs(string[] log) + { + foreach (string l in log) + { + AddTestRunnerLogs(l); + } + } + + /// + /// Adds logs from test framework tools to the test-runner logs view (if available in the reporter) + /// + /// + public void AddTestRunnerLogs(List log) + { + log.ForEach(x => AddTestRunnerLogs(x)); + } + + /// + /// Tries to resolve a location if the absolute path is not + /// found using the supplied locations. This can resolve cases where the default + /// path was supplied to be relative for a FileReporter. If the absolute path is not + /// determined, the supplied path will be used. + /// + /// An array of paths to be used if the provided media path is not + /// resolved + /// + public new void TryResolveMediaPath(string[] path) + { + base.TryResolveMediaPath(path); + } + + /// + /// + /// + /// + public void TryResolveMediaPath(string path) + { + TryResolveMediaPath(new string[] { path }); + } + + /// + /// Creates the internal model by consuming a JSON archive using ExtentJsonFormatter + /// from a previous run session. This provides the same functionality available in earlier + /// versions with AppendExisting. + /// + /// The JSON archive file created by + public void CreateDomainFromJsonArchive(string filePath) + { + ConvertRawEntities(this, filePath); + } + } +} diff --git a/extentreports-dotnet-core/ExtentTest.cs b/ExtentReports/Core/ExtentTest.cs similarity index 53% rename from extentreports-dotnet-core/ExtentTest.cs rename to ExtentReports/Core/ExtentTest.cs index 77645b9..84a7070 100644 --- a/extentreports-dotnet-core/ExtentTest.cs +++ b/ExtentReports/Core/ExtentTest.cs @@ -1,88 +1,118 @@ -using AventStack.ExtentReports.Core; +using AventStack.ExtentReports.Gherkin; using AventStack.ExtentReports.Gherkin.Model; using AventStack.ExtentReports.MarkupUtils; using AventStack.ExtentReports.Model; - +using AventStack.ExtentReports.Util; using System; using System.Linq; namespace AventStack.ExtentReports { - public class ExtentTest : IMediaContainer + public class ExtentTest { - public Status Status => Model.Status; - - public Test Model { get; private set; } + public Status Status => Test.Status; + public Test Test { get; private set; } + public Test Model => Test; public ExtentReports Extent { get; private set; } - internal ExtentTest(ExtentReports extent, IGherkinFormatterModel bddType, string name, string description) + internal ExtentTest(ExtentReports extent, GherkinKeyword bddType, string name, string description) { - if (string.IsNullOrEmpty(name)) - throw new ArgumentException("Test name cannot be null or empty"); + Assert.NotEmpty(name, "Test name must not be null or empty"); Extent = extent; - Model = new Test + + Test = new Test { Name = name, + BddType = bddType, Description = description, - BehaviorDrivenType = bddType + UseNaturalConf = extent.UsingNaturalConf }; + + Extent = extent; } internal ExtentTest(ExtentReports extent, string name, string description = "") : this(extent, null, name, description) { } - public ExtentTest CreateNode(string name, string description = "") where T : IGherkinFormatterModel + public ExtentTest CreateNode(GherkinKeyword keyword, string name, string description = "") { - if (string.IsNullOrEmpty(name)) - throw new ArgumentException("Test name cannot be null or empty"); + Assert.NotEmpty(name, "Node name must not be null or empty"); - Type type = typeof(T); - var obj = (IGherkinFormatterModel)Activator.CreateInstance(type); - - var node = new ExtentTest(Extent, obj, name, description); - ApplyCommonNodeSettings(node); - return node; + var t = new ExtentTest(Extent, keyword, name, description); + Notify(t.Test); + return t; } - private void ApplyCommonNodeSettings(ExtentTest node) + private void Notify(Test t) { - node.Model.Parent = Model; - Model.NodeContext.Add(node.Model); - AddNodeToReport(node); + Test.AddChild(t); + Extent.OnNodeCreated(t); } - private void AddNodeToReport(ExtentTest node) + public ExtentTest CreateNode(string name, string description = "") where T : IGherkinFormatterModel { - Extent.AddNode(node.Model); + var type = typeof(T).Name; + var keyword = new GherkinKeyword(type); + return CreateNode(keyword, name, description); } public ExtentTest CreateNode(string name, string description = "") { - var node = new ExtentTest(Extent, name, description); - ApplyCommonNodeSettings(node); - return node; + var t = new ExtentTest(Extent, name, description); + Notify(t.Test); + return t; } - public ExtentTest CreateNode(GherkinKeyword keyword, string name, string description = "") - { - var node = new ExtentTest(Extent, name, description); - node.Model.BehaviorDrivenType = keyword.Model; - ApplyCommonNodeSettings(node); - return node; - } - /// /// Removes a direct child of the current test /// /// The child node to be removed public void RemoveNode(ExtentTest test) { - if (Model.HasChildren) + Extent.RemoveTest(test); + } + + /// + /// Create a non-standard log with details. This is unlike the Log + /// method which creates a fixed table layout with the following columns: + /// Timestamp, Status, Details. + /// + /// GenerateLog with allows for a user-defined + /// log with a supported provided by + /// + /// + /// Test details of the step + /// A object + public ExtentTest GenerateLog(Status status, string details) + { + var evt = new Log { - Model.NodeContext.Remove(test.Model); - } + Status = status, + Details = details ?? "" + }; + + Test.AddGeneratedLog(evt); + Extent.OnLogCreated(evt, Test); + + return this; + } + + /// + /// Create a non-standard log with details. This is unlike the Log + /// method which creates a fixed table layout with the following columns: + /// Timestamp, Status, Details. + /// + /// GenerateLog with allows for a user-defined + /// log with a supported provided by + /// + /// + /// + /// A object + public ExtentTest GenerateLog(Status status, IMarkup markup) + { + return GenerateLog(status, markup.GetMarkup()); } /// @@ -92,112 +122,137 @@ public void RemoveNode(ExtentTest test) /// test.Log(Status.Fail, "details", MediaEntityBuilder.CreateScreenCaptureFromPath("screen.png").Build()); /// /// + /// /// /// Log details - /// A object + /// A object + /// /// A object - public ExtentTest Log(Status status, string details, MediaEntityModelProvider provider = null) + public ExtentTest Log(Status status, string details, Exception ex, Media media) { - var evt = CreateLog(status, details); + Assert.NotNull(status, "Status must not be null"); + + var evt = new Log + { + Status = status, + Details = details ?? "" + }; - if (provider != null) + if (ex != null) { - AddsScreenCapture(evt, provider.Media); + var ei = new ExceptionInfo(ex); + evt.ExceptionInfo = ei; + Test.ExceptionInfo.Add(ei); } - return AddLog(evt); + Test.AddLog(evt); + Extent.OnLogCreated(evt, Test); + + if (media != null) + { + evt.AddMedia(media); + Extent.OnMediaAdded(media, evt, Test); + } + + return this; } - private void AddsScreenCapture(Log evt, Media m) + /// + /// Logs an event with , details and a media object: + /// + /// + /// test.Log(Status.Fail, "details", MediaEntityBuilder.CreateScreenCaptureFromPath("screen.png").Build()); + /// + /// + /// + /// + /// Log details + /// A object + /// A object + public ExtentTest Log(Status status, string details, Media media) { - evt.AddScreenCapture((ScreenCapture)m); + return Log(status, details, null, media); } /// - /// Logs an event with and a media object: + /// Logs an event with , details and a media object: /// /// - /// test.Log(Status.Fail, MediaEntityBuilder.CreateScreenCaptureFromPath("screen.png").Build()); + /// test.Log(Status.Fail, "details", MediaEntityBuilder.CreateScreenCaptureFromPath("screen.png").Build()); /// /// + /// /// - /// A object + /// A object /// A object - public ExtentTest Log(Status status, MediaEntityModelProvider provider = null) + public ExtentTest Log(Status status, Media media) { - var evt = CreateLog(status); - - if (provider != null) - { - AddsScreenCapture(evt, provider.Media); - } - - return AddLog(evt); + return Log(status, null, null, media); } /// - /// Logs an event with , an exception and a media object: + /// Logs an event with , details and a media object: /// /// - /// test.Log(Status.Fail, exception, MediaEntityBuilder.CreateScreenCaptureFromPath("screen.png").Build()); + /// test.Log(Status.Fail, "details", MediaEntityBuilder.CreateScreenCaptureFromPath("screen.png").Build()); /// /// + /// /// /// - /// A object + /// A object /// A object - public ExtentTest Log(Status status, Exception ex, MediaEntityModelProvider provider = null) + public ExtentTest Log(Status status, Exception ex, Media media) { - ExceptionInfo e = new ExceptionInfo(ex); - Model.ExceptionInfoContext.Add(e); - var evt = new Log(Model) - { - ExceptionInfo = e - }; - return AddLog(evt); + return Log(status, "", ex, media); } /// - /// Logs an event with and custom such as: + /// Logs an event with , details and a media object: /// - /// - /// CodeBlock - /// Label - /// Table - /// + /// + /// test.Log(Status.Fail, "details", MediaEntityBuilder.CreateScreenCaptureFromPath("screen.png").Build()); + /// /// - /// - /// + /// + /// + /// /// A object - public ExtentTest Log(Status status, IMarkup markup) + public ExtentTest Log(Status status, Exception ex) { - string details = markup.GetMarkup(); - return Log(status, details); + return Log(status, null, ex, null); } - private ExtentTest AddLog(Log evt) + /// + /// Logs an event with , details and a media object: + /// + /// + /// test.Log(Status.Fail, "details", MediaEntityBuilder.CreateScreenCaptureFromPath("screen.png").Build()); + /// + /// + /// + /// + /// Log details + /// A object + public ExtentTest Log(Status status, string details) { - Model.LogContext.Add(evt); - Extent.AddLog(Model, evt); - - if (evt.HasScreenCapture) - { - Extent.AddScreenCapture(evt, evt.ScreenCaptureContext.FirstOrDefault()); - } - - return this; + return Log(status, details, null, null); } - private Log CreateLog(Status status, string details = null) + /// + /// Logs an event with , details and a media object: + /// + /// + /// test.Log(Status.Fail, "details", MediaEntityBuilder.CreateScreenCaptureFromPath("screen.png").Build()); + /// + /// + /// + /// + /// + /// A object + public ExtentTest Log(Status status, IMarkup m) { - details = details == null ? "" : details.Trim(); - Log evt = new Log(this.Model) - { - Status = status, - Details = details, - Sequence = Model.LogContext.All().Count + 1 - }; - return evt; + return Log(status, m.GetMarkup(), null, null); } /// @@ -206,9 +261,9 @@ private Log CreateLog(Status status, string details = null) /// Details /// A object /// A object - public ExtentTest Info(string details, MediaEntityModelProvider provider = null) + public ExtentTest Info(string details, Media media = null) { - Log(Status.Info, details, provider); + Log(Status.Info, details, null, media); return this; } @@ -218,9 +273,19 @@ public ExtentTest Info(string details, MediaEntityModelProvider provider = null) /// /// A object /// A object - public ExtentTest Info(Exception ex, MediaEntityModelProvider provider = null) + public ExtentTest Info(Exception ex, Media media = null) + { + return Log(Status.Info, ex, media); + } + + /// + /// Logs an event with details and a media object + /// + /// A object + /// A object + public ExtentTest Info(Media media = null) { - return Log(Status.Info, ex, provider); + return Log(Status.Info, media); } /// @@ -230,7 +295,7 @@ public ExtentTest Info(Exception ex, MediaEntityModelProvider provider = null) /// A object public ExtentTest Info(IMarkup m) { - return Log(Status.Info, m); + return Log(Status.Info, m.GetMarkup(), null); } /// @@ -239,9 +304,9 @@ public ExtentTest Info(IMarkup m) /// Details /// A object /// A object - public ExtentTest Pass(string details, MediaEntityModelProvider provider = null) + public ExtentTest Pass(string details, Media media = null) { - return Log(Status.Pass, details, provider); + return Log(Status.Pass, details, null, media); } /// @@ -250,83 +315,70 @@ public ExtentTest Pass(string details, MediaEntityModelProvider provider = null) /// /// A object /// A object - public ExtentTest Pass(Exception ex, MediaEntityModelProvider provider = null) + public ExtentTest Pass(Exception ex, Media media = null) { - return Log(Status.Pass, ex, provider); + return Log(Status.Pass, ex, media); } /// - /// Logs an event with - /// - /// - /// A object - public ExtentTest Pass(IMarkup m) - { - return Log(Status.Pass, m); - } - - /// - /// Logs an event with details and a media object + /// Logs an event with details and a media object /// - /// Details - /// A object + /// A object /// A object - public ExtentTest Fail(string details, MediaEntityModelProvider provider = null) + public ExtentTest Pass(Media media = null) { - return Log(Status.Fail, details, provider); + return Log(Status.Pass, media); } /// - /// Logs an event with an exception and a media object + /// Logs an event with /// - /// - /// A object + /// /// A object - public ExtentTest Fail(Exception ex, MediaEntityModelProvider provider = null) + public ExtentTest Pass(IMarkup m) { - return Log(Status.Fail, ex, provider); + return Log(Status.Pass, m.GetMarkup(), null); } /// - /// Logs an event with + /// Logs an event with details and a media object /// - /// + /// A object /// A object - public ExtentTest Fail(IMarkup m) + public ExtentTest Fail(string details, Media media = null) { - return Log(Status.Fail, m); + return Log(Status.Fail, details, null, media); } /// - /// Logs an event with details and a media object + /// Logs an event with details and a media object /// - /// Details - /// A object + /// A object /// A object - public ExtentTest Fatal(string details, MediaEntityModelProvider provider = null) + public ExtentTest Fail(Media media = null) { - return Log(Status.Fatal, details, provider); + return Log(Status.Fail, media); } /// - /// Logs an event with an exception and a media object + /// Logs an event with an exception and a media object /// /// /// A object /// A object - public ExtentTest Fatal(Exception ex, MediaEntityModelProvider provider = null) + public ExtentTest Fail(Exception ex, Media media = null) { - return Log(Status.Fatal, ex, provider); + return Log(Status.Fail, ex, media); } /// - /// Logs an event with + /// Logs an event with /// /// /// A object - public ExtentTest Fatal(IMarkup m) + public ExtentTest Fail(IMarkup m) { - return Log(Status.Fatal, m); + return Log(Status.Fail, m.GetMarkup(), null); } /// @@ -335,9 +387,9 @@ public ExtentTest Fatal(IMarkup m) /// Details /// A object /// A object - public ExtentTest Warning(string details, MediaEntityModelProvider provider = null) + public ExtentTest Warning(string details, Media media = null) { - return Log(Status.Warning, details, provider); + return Log(Status.Warning, details, null, media); } /// @@ -346,51 +398,29 @@ public ExtentTest Warning(string details, MediaEntityModelProvider provider = nu /// /// A object /// A object - public ExtentTest Warning(Exception ex, MediaEntityModelProvider provider = null) - { - return Log(Status.Warning, ex, provider); - } - - /// - /// Logs an event with - /// - /// - /// A object - public ExtentTest Warning(IMarkup m) + public ExtentTest Warning(Exception ex, Media media = null) { - return Log(Status.Warning, m); + return Log(Status.Warning, ex, media); } /// - /// Logs an event with details and a media object - /// - /// Details - /// A object - /// A object - public ExtentTest Error(string details, MediaEntityModelProvider provider = null) - { - return Log(Status.Error, details, provider); - } - - /// - /// Logs an event with an exception and a media object + /// Logs an event with details and a media object /// - /// - /// A object + /// A object /// A object - public ExtentTest Error(Exception ex, MediaEntityModelProvider provider = null) + public ExtentTest Warning(Media media = null) { - return Log(Status.Error, ex, provider); + return Log(Status.Warning, media); } /// - /// Logs an event with + /// Logs an event with /// /// /// A object - public ExtentTest Error(IMarkup m) + public ExtentTest Warning(IMarkup m) { - return Log(Status.Error, m); + return Log(Status.Warning, m.GetMarkup(), null); } /// @@ -399,9 +429,9 @@ public ExtentTest Error(IMarkup m) /// Details /// A object /// A object - public ExtentTest Skip(string details, MediaEntityModelProvider provider = null) + public ExtentTest Skip(string details, Media media = null) { - return Log(Status.Skip, details, provider); + return Log(Status.Skip, details, null, media); } /// @@ -410,9 +440,9 @@ public ExtentTest Skip(string details, MediaEntityModelProvider provider = null) /// /// A object /// A object - public ExtentTest Skip(Exception ex, MediaEntityModelProvider provider = null) + public ExtentTest Skip(Exception ex, Media media = null) { - return Log(Status.Skip, ex, provider); + return Log(Status.Skip, ex, media); } /// @@ -422,39 +452,17 @@ public ExtentTest Skip(Exception ex, MediaEntityModelProvider provider = null) /// A object public ExtentTest Skip(IMarkup m) { - return Log(Status.Skip, m); - } - - /// - /// Logs an event with details and a media object - /// - /// Details - /// A object - /// A object - public ExtentTest Debug(string details, MediaEntityModelProvider provider = null) - { - return Log(Status.Debug, details, provider); + return Log(Status.Skip, m.GetMarkup(), null); } /// - /// Logs an event with an exception and a media object - /// - /// - /// A object - /// A object - public ExtentTest Debug(Exception ex, MediaEntityModelProvider provider = null) - { - return Log(Status.Debug, ex, provider); - } - - /// - /// Logs an event with + /// Logs an event with details and a media object /// - /// + /// A object /// A object - public ExtentTest Debug(IMarkup m) + public ExtentTest Skip(Media media = null) { - return Log(Status.Debug, m); + return Log(Status.Skip, media); } /// @@ -465,14 +473,18 @@ public ExtentTest Debug(IMarkup m) public ExtentTest AssignAuthor(params string[] author) { if (author == null || author.Length == 0) + { return this; + } + + var authors = author.Where(x => !string.IsNullOrEmpty(x)) + .Select(x => new Author(x)); - author.ToList().Distinct().Where(c => !string.IsNullOrEmpty(c)).ToList().ForEach(a => + foreach (Author x in authors) { - var auth = new Author(a.Replace(" ", "")); - Model.AuthorContext.Add(auth); - Extent.AssignAuthor(Model, auth); - }); + Test.Author.Add(x); + Extent.OnAuthorAdded(x, Test); + } return this; } @@ -485,14 +497,18 @@ public ExtentTest AssignAuthor(params string[] author) public ExtentTest AssignCategory(params string[] category) { if (category == null || category.Length == 0) + { return this; + } + + var categories = category.Where(x => !string.IsNullOrEmpty(x)) + .Select(x => new Category(x)); - category.ToList().Distinct().Where(c => !string.IsNullOrEmpty(c)).ToList().ForEach(c => + foreach (Category x in categories) { - var tag = new Category(c.Replace(" ", "")); - Model.CategoryContext.Add(tag); - Extent.AssignCategory(Model, tag); - }); + Test.Category.Add(x); + Extent.OnCategoryAdded(x, Test); + } return this; } @@ -505,14 +521,18 @@ public ExtentTest AssignCategory(params string[] category) public ExtentTest AssignDevice(params string[] device) { if (device == null || device.Length == 0) + { return this; + } + + var devices = device.Where(x => !string.IsNullOrEmpty(x)) + .Select(x => new Device(x)); - device.ToList().Distinct().Where(c => !string.IsNullOrEmpty(c)).ToList().ForEach(a => + foreach (Device x in devices) { - var d = new Device(a.Replace(" ", "")); - Model.DeviceContext.Add(d); - Extent.AssignDevice(Model, d); - }); + Test.Device.Add(x); + Extent.OnDeviceAdded(x, Test); + } return this; } @@ -525,42 +545,42 @@ public ExtentTest AssignDevice(params string[] device) /// A object public ExtentTest AddScreenCaptureFromPath(string path, string title = null) { + Assert.NotEmpty(path, "ScreenCapture path must not be null or empty"); + ScreenCapture sc = new ScreenCapture { Path = path, Title = title }; - AddScreenCapture(sc); - return this; - } - private void AddScreenCapture(ScreenCapture sc) - { - Model.ScreenCaptureContext.Add(sc); + Test.Media.Add(sc); - if (Model.ObjectId != null) - { - int seq = Model.ScreenCaptureContext.Count; - sc.TestObjectId = Model.ObjectId; - } - - Extent.AddScreenCapture(Model, sc); + return this; } /// - /// Adds a screenshot using a base64 string + /// Adds a screenshot using a file path /// - /// Base64 string + /// Base64 string /// Image title /// A object - public ExtentTest AddScreenCaptureFromBase64String(string s, string title = null) + public ExtentTest AddScreenCaptureFromBase64String(string base64, string title = null) { + Assert.NotEmpty(base64, "ScreenCapture Base64 string must not be null or empty"); + + if (!base64.StartsWith("data:")) + { + base64 = "data:image/png;base64," + base64; + } + ScreenCapture sc = new ScreenCapture { - Base64String = s, + Base64 = base64, Title = title }; - AddScreenCapture(sc); + + Test.Media.Add(sc); + return this; } } diff --git a/ExtentReports/Core/MediaEntityBuilder.cs b/ExtentReports/Core/MediaEntityBuilder.cs new file mode 100644 index 0000000..8546ed3 --- /dev/null +++ b/ExtentReports/Core/MediaEntityBuilder.cs @@ -0,0 +1,59 @@ +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Util; +using System.Threading; + +namespace AventStack.ExtentReports +{ + public class MediaEntityBuilder + { + private static readonly string Base64Encoded = "data:image/png;base64,"; + private static readonly MediaEntityBuilder _instance = new MediaEntityBuilder(); + private static ThreadLocal _media; + + public Media Build() + { + return _media.Value; + } + + public static MediaEntityBuilder CreateScreenCaptureFromPath(string path, string title) + { + Assert.NotEmpty(path, "ScreenCapture path must not be null or empty"); + + _media = new ThreadLocal + { + Value = new ScreenCapture(path, title) + }; + return _instance; + } + + public static MediaEntityBuilder CreateScreenCaptureFromPath(string path) + { + return CreateScreenCaptureFromPath(path, null); + } + + public static MediaEntityBuilder CreateScreenCaptureFromBase64String(string base64, string title) + { + Assert.NotEmpty(base64, "ScreenCapture's base64 string must not be null or empty"); + + if (!base64.StartsWith("data:")) + { + base64 = Base64Encoded + base64; + } + + _media = new ThreadLocal + { + Value = new ScreenCapture(null, title) + { + Base64 = base64 + } + }; + + return _instance; + } + + public static MediaEntityBuilder CreateScreenCaptureFromBase64String(string base64) + { + return CreateScreenCaptureFromBase64String(base64, null); + } + } +} diff --git a/ExtentReports/Core/ReactiveSubject.cs b/ExtentReports/Core/ReactiveSubject.cs new file mode 100644 index 0000000..526c0a0 --- /dev/null +++ b/ExtentReports/Core/ReactiveSubject.cs @@ -0,0 +1,23 @@ +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Listener.Entity; +using System; +using System.Reactive.Subjects; + +namespace AventStack.ExtentReports.Core +{ + public abstract class ReactiveSubject + { + private readonly Subject _reportSubject = new Subject(); + protected Report Report { get; } = new Report(); + + protected internal void Subscribe(IObserver obj) + { + _reportSubject.Subscribe(obj); + } + + protected internal void Flush() + { + _reportSubject.OnNext(new ReportEntity { Report = Report }); + } + } +} diff --git a/ExtentReports/Core/Status.cs b/ExtentReports/Core/Status.cs new file mode 100644 index 0000000..109fac4 --- /dev/null +++ b/ExtentReports/Core/Status.cs @@ -0,0 +1,12 @@ +namespace AventStack.ExtentReports +{ + public enum Status + { + Info = 10, + Pass = 20, + Warning = 30, + Skip = 40, + Error = 50, + Fail = 60 + } +} diff --git a/ExtentReports/Extensions/ConcurrentQueueExtensions.cs b/ExtentReports/Extensions/ConcurrentQueueExtensions.cs new file mode 100644 index 0000000..7310019 --- /dev/null +++ b/ExtentReports/Extensions/ConcurrentQueueExtensions.cs @@ -0,0 +1,15 @@ +using System.Collections.Concurrent; + +namespace AventStack.ExtentReports.Extensions +{ + internal static class ConcurrentQueueExtensions + { + public static void Clear(this ConcurrentQueue queue) + { + while (!queue.IsEmpty) + { + _ = queue.TryDequeue(out _); + } + } + } +} diff --git a/ExtentReports/Extensions/DictionaryExtensions.cs b/ExtentReports/Extensions/DictionaryExtensions.cs new file mode 100644 index 0000000..3d5bf7a --- /dev/null +++ b/ExtentReports/Extensions/DictionaryExtensions.cs @@ -0,0 +1,18 @@ +using AventStack.ExtentReports.Util; +using System.Collections.Generic; + +namespace AventStack.ExtentReports.Extensions +{ + internal static class DictionaryExtensions + { + public static void AddRange(this IDictionary source, IDictionary collection) + { + Assert.NotNull(source, "Collection must not be null"); + + foreach (KeyValuePair item in collection) + { + source[item.Key] = item.Value; + } + } + } +} diff --git a/ExtentReports/Extensions/StatusExtensions.cs b/ExtentReports/Extensions/StatusExtensions.cs new file mode 100644 index 0000000..db04efa --- /dev/null +++ b/ExtentReports/Extensions/StatusExtensions.cs @@ -0,0 +1,27 @@ +using System.Linq; + +namespace AventStack.ExtentReports.Extensions +{ + public static class StatusExtensions + { + public static Status Min(this Status s1, Status s2) + { + return Max(s1, s2) == s1 ? s2 : s1; + } + + public static Status Min(Status[] status) + { + return status.Min(); + } + + public static Status Max(this Status s1, Status s2) + { + return s1 > s2 ? s1 : s2; + } + + public static Status Max(Status[] status) + { + return status.Max(); + } + } +} diff --git a/ExtentReports/ExtentReports.csproj b/ExtentReports/ExtentReports.csproj new file mode 100644 index 0000000..c871d8c --- /dev/null +++ b/ExtentReports/ExtentReports.csproj @@ -0,0 +1,124 @@ + + + + netstandard2.0 + true + AventStack.ExtentReports + 5.0.0 + anshooarora + AventStack + https://github.com/extent-framework/extentreports-csharp/blob/master/LICENSE + true + anshooarora + https://github.com/extent-framework/extentreports-csharp + ExtentReports .Net Standard + .net reporting extent extentreports klov + ExtentReports + ExtentReports .Net Standard + ExtentReports + + https://www.extentreports.com/logo.jpg + True + 5.0.0 + 6576a851-016a-4abc-a1d1-bdd65a6090d5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExtentReports/Gherkin/GherkinDialect.cs b/ExtentReports/Gherkin/GherkinDialect.cs new file mode 100644 index 0000000..0b7a1fa --- /dev/null +++ b/ExtentReports/Gherkin/GherkinDialect.cs @@ -0,0 +1,62 @@ +using AventStack.ExtentReports.Core; + +namespace AventStack.ExtentReports.Gherkin +{ + public class GherkinDialect + { + public GherkinKeywords Keywords { get; private set; } + public string Language { get; private set; } + + public GherkinDialect(string language, GherkinKeywords keywords) + { + Language = language; + Keywords = keywords; + } + + public string Match(string keyword) + { + if (Keywords.And.Contains(keyword)) + { + return "And"; + } + else if (Keywords.Background.Contains(keyword)) + { + return "Background"; + } + else if (Keywords.But.Contains(keyword)) + { + return "But"; + } + else if (Keywords.Examples.Contains(keyword)) + { + return "Examples"; + } + else if (Keywords.Feature.Contains(keyword)) + { + return "Feature"; + } + else if (Keywords.Given.Contains(keyword)) + { + return "Given"; + } + else if (Keywords.Scenario.Contains(keyword)) + { + return "Scenario"; + } + else if (Keywords.ScenarioOutline.Contains(keyword)) + { + return "ScenarioOutline"; + } + else if (Keywords.Then.Contains(keyword)) + { + return "Then"; + } + else if (Keywords.When.Contains(keyword)) + { + return "When"; + } + + throw new GherkinKeywordNotFoundException("The supplied keyword " + keyword + " is invalid for lang=" + Language); + } + } +} diff --git a/ExtentReports/Gherkin/GherkinDialectProvider.cs b/ExtentReports/Gherkin/GherkinDialectProvider.cs new file mode 100644 index 0000000..c18a751 --- /dev/null +++ b/ExtentReports/Gherkin/GherkinDialectProvider.cs @@ -0,0 +1,80 @@ +using AventStack.ExtentReports.Gherkin.Resource; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.IO; + +namespace AventStack.ExtentReports.Gherkin +{ + public static class GherkinDialectProvider + { + private const string LangFileName = "lang.json"; + + private static string _lang = "en"; + private static GherkinKeywords _keywords; + private static GherkinDialect _dialect; + + public static Dictionary Dialects { get; private set; } + + public static GherkinDialect Dialect + { + get + { + if (_dialect == null) + { + LoadDialects(); + } + + return _dialect; + } + set => _dialect = value; + } + + public static string Lang + { + get => _lang; + set + { + _lang = value; + SetDialect(value); + } + } + + private static void LoadDialects() + { + var gherkinResource = typeof(IGherkinResource).Assembly; + var ns = typeof(IGherkinResource).Namespace; + var lang = ns + "." + LangFileName; + string json = null; + + using (Stream resourceStream = gherkinResource.GetManifestResourceStream(lang)) + { + using (StreamReader reader = new StreamReader(resourceStream)) + { + if (null != resourceStream) + { + json = reader.ReadToEnd(); + } + } + } + + Dialects = JsonConvert.DeserializeObject>(json); + SetDialect(_lang); + } + + private static void SetDialect(string lang) + { + if (Dialects == null) + { + LoadDialects(); + } + + if (!Dialects.ContainsKey(lang)) + { + throw new InvalidGherkinLanguageException(lang + " is not a valid Gherkin dialect"); + } + + _keywords = Dialects[lang]; + Dialect = new GherkinDialect(lang, _keywords); + } + } +} diff --git a/ExtentReports/Gherkin/GherkinKeyword.cs b/ExtentReports/Gherkin/GherkinKeyword.cs new file mode 100644 index 0000000..8aa8c1a --- /dev/null +++ b/ExtentReports/Gherkin/GherkinKeyword.cs @@ -0,0 +1,43 @@ +using AventStack.ExtentReports.Core; +using System.Linq; + +namespace AventStack.ExtentReports.Gherkin +{ + public class GherkinKeyword + { + public string Name { get; private set; } + public string OriginalName { get; private set; } + + public GherkinKeyword(string name) + { + OriginalName = name; + + if (name == "ScenarioOutline") + { + name = "Scenario Outline"; + } + if (name == "Asterisk") + { + name = "*"; + } + + Name = name; + CreateDomain(); + } + + private void CreateDomain() + { + if (Name == null) + { + throw new GherkinKeywordNotFoundException("Keyword " + Name + " cannot be null"); + } + + string key = Name.First().ToString().ToUpper() + Name.Substring(1); + + if (key != "*") + { + Name = GherkinDialectProvider.Dialect.Match(key); + } + } + } +} diff --git a/extentreports-dotnet-core/Core/GherkinKeywordNotFoundException.cs b/ExtentReports/Gherkin/GherkinKeywordNotFoundException.cs similarity index 100% rename from extentreports-dotnet-core/Core/GherkinKeywordNotFoundException.cs rename to ExtentReports/Gherkin/GherkinKeywordNotFoundException.cs diff --git a/ExtentReports/Gherkin/GherkinKeywords.cs b/ExtentReports/Gherkin/GherkinKeywords.cs new file mode 100644 index 0000000..3d3876b --- /dev/null +++ b/ExtentReports/Gherkin/GherkinKeywords.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; + +namespace AventStack.ExtentReports.Gherkin +{ + public class GherkinKeywords + { + public ISet And { get; set; } + public ISet Background { get; set; } + public ISet But { get; set; } + public ISet Examples { get; set; } + public ISet Feature { get; set; } + public ISet Given { get; set; } + public string Name { get; set; } + public string Native { get; set; } + public ISet Scenario { get; set; } + public ISet ScenarioOutline { get; set; } + public ISet Then { get; set; } + public ISet When { get; set; } + } +} diff --git a/extentreports-dotnet-core/Gherkin/InvalidGherkinLanguageException.cs b/ExtentReports/Gherkin/InvalidGherkinLanguageException.cs similarity index 66% rename from extentreports-dotnet-core/Gherkin/InvalidGherkinLanguageException.cs rename to ExtentReports/Gherkin/InvalidGherkinLanguageException.cs index b6d6304..9a27bc0 100644 --- a/extentreports-dotnet-core/Gherkin/InvalidGherkinLanguageException.cs +++ b/ExtentReports/Gherkin/InvalidGherkinLanguageException.cs @@ -7,10 +7,7 @@ public class InvalidGherkinLanguageException : ArgumentException { public InvalidGherkinLanguageException() : base() { } public InvalidGherkinLanguageException(string message) : base(message) { } - public InvalidGherkinLanguageException(string message, System.Exception inner) : base(message, inner) { } - // A constructor is needed for serialization when an - // exception propagates from a remoting server to the client. protected InvalidGherkinLanguageException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) { } diff --git a/extentreports-dotnet-core/Gherkin/Model/And.cs b/ExtentReports/Gherkin/Model/And.cs similarity index 69% rename from extentreports-dotnet-core/Gherkin/Model/And.cs rename to ExtentReports/Gherkin/Model/And.cs index 4a24399..cea56fd 100644 --- a/extentreports-dotnet-core/Gherkin/Model/And.cs +++ b/ExtentReports/Gherkin/Model/And.cs @@ -5,11 +5,11 @@ namespace AventStack.ExtentReports.Gherkin.Model [Serializable] public class And : IGherkinFormatterModel { - public static string GherkinName { get; } = "And"; + public const string Name = "And"; public override string ToString() { - return GherkinName; + return Name; } } } diff --git a/extentreports-dotnet-core/Gherkin/Model/Asterisk.cs b/ExtentReports/Gherkin/Model/Asterisk.cs similarity index 70% rename from extentreports-dotnet-core/Gherkin/Model/Asterisk.cs rename to ExtentReports/Gherkin/Model/Asterisk.cs index cf31e14..d52a676 100644 --- a/extentreports-dotnet-core/Gherkin/Model/Asterisk.cs +++ b/ExtentReports/Gherkin/Model/Asterisk.cs @@ -5,11 +5,11 @@ namespace AventStack.ExtentReports.Gherkin.Model [Serializable] public class Asterisk : IGherkinFormatterModel { - public static string GherkinName { get; } = "*"; + public const string Name = "*"; public override string ToString() { - return GherkinName; + return Name; } } } diff --git a/extentreports-dotnet-core/Gherkin/Model/Background.cs b/ExtentReports/Gherkin/Model/Background.cs similarity index 68% rename from extentreports-dotnet-core/Gherkin/Model/Background.cs rename to ExtentReports/Gherkin/Model/Background.cs index 0454274..38d73fd 100644 --- a/extentreports-dotnet-core/Gherkin/Model/Background.cs +++ b/ExtentReports/Gherkin/Model/Background.cs @@ -5,11 +5,11 @@ namespace AventStack.ExtentReports.Gherkin.Model [Serializable] public class Background : IGherkinFormatterModel { - public static string GherkinName { get; } = "Background"; + public static string Name = "Background"; public override string ToString() { - return GherkinName; + return Name; } } } diff --git a/extentreports-dotnet-core/Gherkin/Model/But.cs b/ExtentReports/Gherkin/Model/But.cs similarity index 69% rename from extentreports-dotnet-core/Gherkin/Model/But.cs rename to ExtentReports/Gherkin/Model/But.cs index 4d874ca..bf28553 100644 --- a/extentreports-dotnet-core/Gherkin/Model/But.cs +++ b/ExtentReports/Gherkin/Model/But.cs @@ -5,11 +5,11 @@ namespace AventStack.ExtentReports.Gherkin.Model [Serializable] public class But : IGherkinFormatterModel { - public static string GherkinName { get; } = "But"; + public static string Name = "But"; public override string ToString() { - return GherkinName; + return Name; } } } diff --git a/extentreports-dotnet-core/Gherkin/Model/Feature.cs b/ExtentReports/Gherkin/Model/Feature.cs similarity index 69% rename from extentreports-dotnet-core/Gherkin/Model/Feature.cs rename to ExtentReports/Gherkin/Model/Feature.cs index d6a9f5c..c954329 100644 --- a/extentreports-dotnet-core/Gherkin/Model/Feature.cs +++ b/ExtentReports/Gherkin/Model/Feature.cs @@ -5,11 +5,11 @@ namespace AventStack.ExtentReports.Gherkin.Model [Serializable] public class Feature : IGherkinFormatterModel { - public static string GherkinName { get; } = "Feature"; + public static string Name = "Feature"; public override string ToString() { - return GherkinName; + return Name; } } } diff --git a/extentreports-dotnet-core/Gherkin/Model/Given.cs b/ExtentReports/Gherkin/Model/Given.cs similarity index 69% rename from extentreports-dotnet-core/Gherkin/Model/Given.cs rename to ExtentReports/Gherkin/Model/Given.cs index a2bd2c7..7225f87 100644 --- a/extentreports-dotnet-core/Gherkin/Model/Given.cs +++ b/ExtentReports/Gherkin/Model/Given.cs @@ -5,11 +5,11 @@ namespace AventStack.ExtentReports.Gherkin.Model [Serializable] public class Given : IGherkinFormatterModel { - public static string GherkinName { get; } = "Given"; + public static string Name = "Given"; public override string ToString() { - return GherkinName; + return Name; } } } diff --git a/extentreports-dotnet-core/Gherkin/Model/IGherkinFormatterModel.cs b/ExtentReports/Gherkin/Model/IGherkinFormatterModel.cs similarity index 100% rename from extentreports-dotnet-core/Gherkin/Model/IGherkinFormatterModel.cs rename to ExtentReports/Gherkin/Model/IGherkinFormatterModel.cs diff --git a/extentreports-dotnet-core/Gherkin/Model/Scenario.cs b/ExtentReports/Gherkin/Model/Scenario.cs similarity index 69% rename from extentreports-dotnet-core/Gherkin/Model/Scenario.cs rename to ExtentReports/Gherkin/Model/Scenario.cs index 73ca5e1..5ac64cd 100644 --- a/extentreports-dotnet-core/Gherkin/Model/Scenario.cs +++ b/ExtentReports/Gherkin/Model/Scenario.cs @@ -5,11 +5,11 @@ namespace AventStack.ExtentReports.Gherkin.Model [Serializable] public class Scenario : IGherkinFormatterModel { - public static string GherkinName { get; } = "Scenario"; + public static string Name = "Scenario"; public override string ToString() { - return GherkinName; + return Name; } } } diff --git a/extentreports-dotnet-core/Gherkin/Model/ScenarioOutline.cs b/ExtentReports/Gherkin/Model/ScenarioOutline.cs similarity index 68% rename from extentreports-dotnet-core/Gherkin/Model/ScenarioOutline.cs rename to ExtentReports/Gherkin/Model/ScenarioOutline.cs index eed27c8..5a93542 100644 --- a/extentreports-dotnet-core/Gherkin/Model/ScenarioOutline.cs +++ b/ExtentReports/Gherkin/Model/ScenarioOutline.cs @@ -5,11 +5,11 @@ namespace AventStack.ExtentReports.Gherkin.Model [Serializable] public class ScenarioOutline : IGherkinFormatterModel { - public static string GherkinName { get; } = "Scenario Outline"; + public static string Name = "Scenario Outline"; public override string ToString() { - return GherkinName; + return Name; } } } diff --git a/extentreports-dotnet-core/Gherkin/Model/Then.cs b/ExtentReports/Gherkin/Model/Then.cs similarity index 69% rename from extentreports-dotnet-core/Gherkin/Model/Then.cs rename to ExtentReports/Gherkin/Model/Then.cs index 45e4f27..3970034 100644 --- a/extentreports-dotnet-core/Gherkin/Model/Then.cs +++ b/ExtentReports/Gherkin/Model/Then.cs @@ -5,11 +5,11 @@ namespace AventStack.ExtentReports.Gherkin.Model [Serializable] public class Then : IGherkinFormatterModel { - public static string GherkinName { get; } = "Then"; + public static string Name = "Then"; public override string ToString() { - return GherkinName; + return Name; } } } diff --git a/extentreports-dotnet-core/Gherkin/Model/When.cs b/ExtentReports/Gherkin/Model/When.cs similarity index 69% rename from extentreports-dotnet-core/Gherkin/Model/When.cs rename to ExtentReports/Gherkin/Model/When.cs index 7de5bf8..2f5dd94 100644 --- a/extentreports-dotnet-core/Gherkin/Model/When.cs +++ b/ExtentReports/Gherkin/Model/When.cs @@ -5,11 +5,11 @@ namespace AventStack.ExtentReports.Gherkin.Model [Serializable] public class When : IGherkinFormatterModel { - public static string GherkinName { get; } = "When"; + public static string Name = "When"; public override string ToString() { - return GherkinName; + return Name; } } } diff --git a/ExtentReports/Gherkin/Resource/IGherkinResource.cs b/ExtentReports/Gherkin/Resource/IGherkinResource.cs new file mode 100644 index 0000000..224d6cd --- /dev/null +++ b/ExtentReports/Gherkin/Resource/IGherkinResource.cs @@ -0,0 +1,6 @@ +namespace AventStack.ExtentReports.Gherkin.Resource +{ + internal interface IGherkinResource + { + } +} diff --git a/ExtentReports/Gherkin/Resource/lang.json b/ExtentReports/Gherkin/Resource/lang.json new file mode 100644 index 0000000..3dda5a8 --- /dev/null +++ b/ExtentReports/Gherkin/Resource/lang.json @@ -0,0 +1,3625 @@ +{ + "af": { + "and": [ + "*", + "En" + ], + "background": [ + "Agtergrond" + ], + "but": [ + "*", + "Maar" + ], + "examples": [ + "Voorbeelde" + ], + "feature": [ + "Funksie", + "Besigheid Behoefte", + "Vermoë" + ], + "given": [ + "*", + "Gegewe" + ], + "name":"Afrikaans", + "native":"Afrikaans", + "rule": [ + "Rule" + ], + "scenario": [ + "Voorbeeld", + "Situasie" + ], + "scenarioOutline": [ + "Situasie Uiteensetting" + ], + "then": [ + "*", + "Dan" + ], + "when": [ + "*", + "Wanneer" + ] + }, + "am": { + "and": [ + "*", + "Եվ" + ], + "background": [ + "Կոնտեքստ" + ], + "but": [ + "*", + "Բայց" + ], + "examples": [ + "Օրինակներ" + ], + "feature": [ + "Ֆունկցիոնալություն", + "Հատկություն" + ], + "given": [ + "*", + "Դիցուք" + ], + "name":"Armenian", + "native":"հայերեն", + "rule": [ + "Rule" + ], + "scenario": [ + "Օրինակ", + "Սցենար" + ], + "scenarioOutline": [ + "Սցենարի կառուցվացքը" + ], + "then": [ + "*", + "Ապա" + ], + "when": [ + "*", + "Եթե", + "Երբ" + ] + }, + "an": { + "and": [ + "*", + "Y", + "E" + ], + "background": [ + "Antecedents" + ], + "but": [ + "*", + "Pero" + ], + "examples": [ + "Eixemplos" + ], + "feature": [ + "Caracteristica" + ], + "given": [ + "*", + "Dau", + "Dada", + "Daus", + "Dadas" + ], + "name":"Aragonese", + "native":"Aragonés", + "rule": [ + "Rule" + ], + "scenario": [ + "Eixemplo", + "Caso" + ], + "scenarioOutline": [ + "Esquema del caso" + ], + "then": [ + "*", + "Alavez", + "Allora", + "Antonces" + ], + "when": [ + "*", + "Cuan" + ] + }, + "ar": { + "and": [ + "*", + "و" + ], + "background": [ + "الخلفية" + ], + "but": [ + "*", + "لكن" + ], + "examples": [ + "امثلة" + ], + "feature": [ + "خاصية" + ], + "given": [ + "*", + "بفرض" + ], + "name":"Arabic", + "native":"العربية", + "rule": [ + "Rule" + ], + "scenario": [ + "مثال", + "سيناريو" + ], + "scenarioOutline": [ + "سيناريو مخطط" + ], + "then": [ + "*", + "اذاً", + "ثم" + ], + "when": [ + "*", + "متى", + "عندما" + ] + }, + "ast": { + "and": [ + "*", + "Y", + "Ya" + ], + "background": [ + "Antecedentes" + ], + "but": [ + "*", + "Peru" + ], + "examples": [ + "Exemplos" + ], + "feature": [ + "Carauterística" + ], + "given": [ + "*", + "Dáu", + "Dada", + "Daos", + "Daes" + ], + "name":"Asturian", + "native":"asturianu", + "rule": [ + "Rule" + ], + "scenario": [ + "Exemplo", + "Casu" + ], + "scenarioOutline": [ + "Esbozu del casu" + ], + "then": [ + "*", + "Entós" + ], + "when": [ + "*", + "Cuando" + ] + }, + "az": { + "and": [ + "*", + "Və", + "Həm" + ], + "background": [ + "Keçmiş", + "Kontekst" + ], + "but": [ + "*", + "Amma", + "Ancaq" + ], + "examples": [ + "Nümunələr" + ], + "feature": [ + "Özəllik" + ], + "given": [ + "*", + "Tutaq ki", + "Verilir" + ], + "name":"Azerbaijani", + "native":"Azərbaycanca", + "rule": [ + "Rule" + ], + "scenario": [ + "Nümunə", + "Ssenari" + ], + "scenarioOutline": [ + "Ssenarinin strukturu" + ], + "then": [ + "*", + "O halda" + ], + "when": [ + "*", + "Əgər", + "Nə vaxt ki" + ] + }, + "bg": { + "and": [ + "*", + "И" + ], + "background": [ + "Предистория" + ], + "but": [ + "*", + "Но" + ], + "examples": [ + "Примери" + ], + "feature": [ + "Функционалност" + ], + "given": [ + "*", + "Дадено" + ], + "name":"Bulgarian", + "native":"български", + "rule": [ + "Rule" + ], + "scenario": [ + "Пример", + "Сценарий" + ], + "scenarioOutline": [ + "Рамка на сценарий" + ], + "then": [ + "*", + "То" + ], + "when": [ + "*", + "Когато" + ] + }, + "bm": { + "and": [ + "*", + "Dan" + ], + "background": [ + "Latar Belakang" + ], + "but": [ + "*", + "Tetapi", + "Tapi" + ], + "examples": [ + "Contoh" + ], + "feature": [ + "Fungsi" + ], + "given": [ + "*", + "Diberi", + "Bagi" + ], + "name":"Malay", + "native":"Bahasa Melayu", + "rule": [ + "Rule" + ], + "scenario": [ + "Senario", + "Situasi", + "Keadaan" + ], + "scenarioOutline": [ + "Kerangka Senario", + "Kerangka Situasi", + "Kerangka Keadaan", + "Garis Panduan Senario" + ], + "then": [ + "*", + "Maka", + "Kemudian" + ], + "when": [ + "*", + "Apabila" + ] + }, + "bs": { + "and": [ + "*", + "I", + "A" + ], + "background": [ + "Pozadina" + ], + "but": [ + "*", + "Ali" + ], + "examples": [ + "Primjeri" + ], + "feature": [ + "Karakteristika" + ], + "given": [ + "*", + "Dato" + ], + "name":"Bosnian", + "native":"Bosanski", + "rule": [ + "Rule" + ], + "scenario": [ + "Primjer", + "Scenariju", + "Scenario" + ], + "scenarioOutline": [ + "Scenariju-obris", + "Scenario-outline" + ], + "then": [ + "*", + "Zatim" + ], + "when": [ + "*", + "Kada" + ] + }, + "ca": { + "and": [ + "*", + "I" + ], + "background": [ + "Rerefons", + "Antecedents" + ], + "but": [ + "*", + "Però" + ], + "examples": [ + "Exemples" + ], + "feature": [ + "Característica", + "Funcionalitat" + ], + "given": [ + "*", + "Donat", + "Donada", + "Atès", + "Atesa" + ], + "name":"Catalan", + "native":"català", + "rule": [ + "Rule" + ], + "scenario": [ + "Exemple", + "Escenari" + ], + "scenarioOutline": [ + "Esquema de l'escenari" + ], + "then": [ + "*", + "Aleshores", + "Cal" + ], + "when": [ + "*", + "Quan" + ] + }, + "cs": { + "and": [ + "*", + "A také", + "A" + ], + "background": [ + "Pozadí", + "Kontext" + ], + "but": [ + "*", + "Ale" + ], + "examples": [ + "Příklady" + ], + "feature": [ + "Požadavek" + ], + "given": [ + "*", + "Pokud", + "Za předpokladu" + ], + "name":"Czech", + "native":"Česky", + "rule": [ + "Rule" + ], + "scenario": [ + "Příklad", + "Scénář" + ], + "scenarioOutline": [ + "Náčrt Scénáře", + "Osnova scénáře" + ], + "then": [ + "*", + "Pak" + ], + "when": [ + "*", + "Když" + ] + }, + "cy-GB": { + "and": [ + "*", + "A" + ], + "background": [ + "Cefndir" + ], + "but": [ + "*", + "Ond" + ], + "examples": [ + "Enghreifftiau" + ], + "feature": [ + "Arwedd" + ], + "given": [ + "*", + "Anrhegedig a" + ], + "name":"Welsh", + "native":"Cymraeg", + "rule": [ + "Rule" + ], + "scenario": [ + "Enghraifft", + "Scenario" + ], + "scenarioOutline": [ + "Scenario Amlinellol" + ], + "then": [ + "*", + "Yna" + ], + "when": [ + "*", + "Pryd" + ] + }, + "da": { + "and": [ + "*", + "Og" + ], + "background": [ + "Baggrund" + ], + "but": [ + "*", + "Men" + ], + "examples": [ + "Eksempler" + ], + "feature": [ + "Egenskab" + ], + "given": [ + "*", + "Givet" + ], + "name":"Danish", + "native":"dansk", + "rule": [ + "Rule" + ], + "scenario": [ + "Eksempel", + "Scenarie" + ], + "scenarioOutline": [ + "Abstrakt Scenario" + ], + "then": [ + "*", + "Så" + ], + "when": [ + "*", + "Når" + ] + }, + "de": { + "and": [ + "*", + "Und" + ], + "background": [ + "Grundlage", + "Hintergrund", + "Voraussetzungen", + "Vorbedingungen" + ], + "but": [ + "*", + "Aber" + ], + "examples": [ + "Beispiele" + ], + "feature": [ + "Funktionalität", + "Funktion" + ], + "given": [ + "*", + "Angenommen", + "Gegeben sei", + "Gegeben seien" + ], + "name":"German", + "native":"Deutsch", + "rule": [ + "Rule", + "Regel" + ], + "scenario": [ + "Beispiel", + "Szenario" + ], + "scenarioOutline": [ + "Szenariogrundriss", + "Szenarien" + ], + "then": [ + "*", + "Dann" + ], + "when": [ + "*", + "Wenn" + ] + }, + "el": { + "and": [ + "*", + "Και" + ], + "background": [ + "Υπόβαθρο" + ], + "but": [ + "*", + "Αλλά" + ], + "examples": [ + "Παραδείγματα", + "Σενάρια" + ], + "feature": [ + "Δυνατότητα", + "Λειτουργία" + ], + "given": [ + "*", + "Δεδομένου" + ], + "name":"Greek", + "native":"Ελληνικά", + "rule": [ + "Rule" + ], + "scenario": [ + "Παράδειγμα", + "Σενάριο" + ], + "scenarioOutline": [ + "Περιγραφή Σεναρίου", + "Περίγραμμα Σεναρίου" + ], + "then": [ + "*", + "Τότε" + ], + "when": [ + "*", + "Όταν" + ] + }, + "em": { + "and": [ + "*", + "😂" + ], + "background": [ + "💤" + ], + "but": [ + "*", + "😔" + ], + "examples": [ + "📓" + ], + "feature": [ + "📚" + ], + "given": [ + "*", + "😐" + ], + "name":"Emoji", + "native":"😀", + "rule": [ + "Rule" + ], + "scenario": [ + "🥒", + "📕" + ], + "scenarioOutline": [ + "📖" + ], + "then": [ + "*", + "🙏" + ], + "when": [ + "*", + "🎬" + ] + }, + "en": { + "and": [ + "*", + "And" + ], + "background": [ + "Background" + ], + "but": [ + "*", + "But" + ], + "examples": [ + "Examples", + "Scenarios" + ], + "feature": [ + "Feature", + "Business Need", + "Ability" + ], + "given": [ + "*", + "Given" + ], + "name":"English", + "native":"English", + "rule": [ + "Rule" + ], + "scenario": [ + "Example", + "Scenario" + ], + "scenarioOutline": [ + "Scenario Outline", + "Scenario Template" + ], + "then": [ + "*", + "Then" + ], + "when": [ + "*", + "When" + ] + }, + "en-Scouse": { + "and": [ + "*", + "An" + ], + "background": [ + "Dis is what went down" + ], + "but": [ + "*", + "Buh" + ], + "examples": [ + "Examples" + ], + "feature": [ + "Feature" + ], + "given": [ + "*", + "Givun", + "Youse know when youse got" + ], + "name":"Scouse", + "native":"Scouse", + "rule": [ + "Rule" + ], + "scenario": [ + "The thing of it is" + ], + "scenarioOutline": [ + "Wharrimean is" + ], + "then": [ + "*", + "Dun", + "Den youse gotta" + ], + "when": [ + "*", + "Wun", + "Youse know like when" + ] + }, + "en-au": { + "and": [ + "*", + "Too right" + ], + "background": [ + "First off" + ], + "but": [ + "*", + "Yeah nah" + ], + "examples": [ + "You'll wanna" + ], + "feature": [ + "Pretty much" + ], + "given": [ + "*", + "Y'know" + ], + "name":"Australian", + "native":"Australian", + "rule": [ + "Rule" + ], + "scenario": [ + "Awww, look mate" + ], + "scenarioOutline": [ + "Reckon it's like" + ], + "then": [ + "*", + "But at the end of the day I reckon" + ], + "when": [ + "*", + "It's just unbelievable" + ] + }, + "en-lol": { + "and": [ + "*", + "AN" + ], + "background": [ + "B4" + ], + "but": [ + "*", + "BUT" + ], + "examples": [ + "EXAMPLZ" + ], + "feature": [ + "OH HAI" + ], + "given": [ + "*", + "I CAN HAZ" + ], + "name":"LOLCAT", + "native":"LOLCAT", + "rule": [ + "Rule" + ], + "scenario": [ + "MISHUN" + ], + "scenarioOutline": [ + "MISHUN SRSLY" + ], + "then": [ + "*", + "DEN" + ], + "when": [ + "*", + "WEN" + ] + }, + "en-old": { + "and": [ + "*", + "Ond", + "7" + ], + "background": [ + "Aer", + "Ær" + ], + "but": [ + "*", + "Ac" + ], + "examples": [ + "Se the", + "Se þe", + "Se ðe" + ], + "feature": [ + "Hwaet", + "Hwæt" + ], + "given": [ + "*", + "Thurh", + "Þurh", + "Ðurh" + ], + "name":"Old English", + "native":"Englisc", + "rule": [ + "Rule" + ], + "scenario": [ + "Swa" + ], + "scenarioOutline": [ + "Swa hwaer swa", + "Swa hwær swa" + ], + "then": [ + "*", + "Tha", + "Þa", + "Ða", + "Tha the", + "Þa þe", + "Ða ðe" + ], + "when": [ + "*", + "Tha", + "Þa", + "Ða" + ] + }, + "en-pirate": { + "and": [ + "*", + "Aye" + ], + "background": [ + "Yo-ho-ho" + ], + "but": [ + "*", + "Avast!" + ], + "examples": [ + "Dead men tell no tales" + ], + "feature": [ + "Ahoy matey!" + ], + "given": [ + "*", + "Gangway!" + ], + "name":"Pirate", + "native":"Pirate", + "rule": [ + "Rule" + ], + "scenario": [ + "Heave to" + ], + "scenarioOutline": [ + "Shiver me timbers" + ], + "then": [ + "*", + "Let go and haul" + ], + "when": [ + "*", + "Blimey!" + ] + }, + "eo": { + "and": [ + "*", + "Kaj" + ], + "background": [ + "Fono" + ], + "but": [ + "*", + "Sed" + ], + "examples": [ + "Ekzemploj" + ], + "feature": [ + "Trajto" + ], + "given": [ + "*", + "Donitaĵo", + "Komence" + ], + "name":"Esperanto", + "native":"Esperanto", + "rule": [ + "Rule" + ], + "scenario": [ + "Ekzemplo", + "Scenaro", + "Kazo" + ], + "scenarioOutline": [ + "Konturo de la scenaro", + "Skizo", + "Kazo-skizo" + ], + "then": [ + "*", + "Do" + ], + "when": [ + "*", + "Se" + ] + }, + "es": { + "and": [ + "*", + "Y", + "E" + ], + "background": [ + "Antecedentes" + ], + "but": [ + "*", + "Pero" + ], + "examples": [ + "Ejemplos" + ], + "feature": [ + "Característica" + ], + "given": [ + "*", + "Dado", + "Dada", + "Dados", + "Dadas" + ], + "name":"Spanish", + "native":"español", + "rule": [ + "Regla" + ], + "scenario": [ + "Ejemplo", + "Escenario" + ], + "scenarioOutline": [ + "Esquema del escenario" + ], + "then": [ + "*", + "Entonces" + ], + "when": [ + "*", + "Cuando" + ] + }, + "et": { + "and": [ + "*", + "Ja" + ], + "background": [ + "Taust" + ], + "but": [ + "*", + "Kuid" + ], + "examples": [ + "Juhtumid" + ], + "feature": [ + "Omadus" + ], + "given": [ + "*", + "Eeldades" + ], + "name":"Estonian", + "native":"eesti keel", + "rule": [ + "Reegel" + ], + "scenario": [ + "Juhtum", + "Stsenaarium" + ], + "scenarioOutline": [ + "Raamjuhtum", + "Raamstsenaarium" + ], + "then": [ + "*", + "Siis" + ], + "when": [ + "*", + "Kui" + ] + }, + "fa": { + "and": [ + "*", + "و" + ], + "background": [ + "زمینه" + ], + "but": [ + "*", + "اما" + ], + "examples": [ + "نمونه ها" + ], + "feature": [ + "وِیژگی" + ], + "given": [ + "*", + "با فرض" + ], + "name":"Persian", + "native":"فارسی", + "rule": [ + "Rule" + ], + "scenario": [ + "مثال", + "سناریو" + ], + "scenarioOutline": [ + "الگوی سناریو" + ], + "then": [ + "*", + "آنگاه" + ], + "when": [ + "*", + "هنگامی" + ] + }, + "fi": { + "and": [ + "*", + "Ja" + ], + "background": [ + "Tausta" + ], + "but": [ + "*", + "Mutta" + ], + "examples": [ + "Tapaukset" + ], + "feature": [ + "Ominaisuus" + ], + "given": [ + "*", + "Oletetaan" + ], + "name":"Finnish", + "native":"suomi", + "rule": [ + "Rule" + ], + "scenario": [ + "Tapaus" + ], + "scenarioOutline": [ + "Tapausaihio" + ], + "then": [ + "*", + "Niin" + ], + "when": [ + "*", + "Kun" + ] + }, + "fr": { + "and": [ + "*", + "Et que", + "Et qu'", + "Et" + ], + "background": [ + "Contexte" + ], + "but": [ + "*", + "Mais que", + "Mais qu'", + "Mais" + ], + "examples": [ + "Exemples" + ], + "feature": [ + "Fonctionnalité" + ], + "given": [ + "*", + "Soit", + "Sachant que", + "Sachant qu'", + "Sachant", + "Etant donné que", + "Etant donné qu'", + "Etant donné", + "Etant donnée", + "Etant donnés", + "Etant données", + "Étant donné que", + "Étant donné qu'", + "Étant donné", + "Étant donnée", + "Étant donnés", + "Étant données" + ], + "name":"French", + "native":"français", + "rule": [ + "Règle" + ], + "scenario": [ + "Exemple", + "Scénario" + ], + "scenarioOutline": [ + "Plan du scénario", + "Plan du Scénario" + ], + "then": [ + "*", + "Alors", + "Donc" + ], + "when": [ + "*", + "Quand", + "Lorsque", + "Lorsqu'" + ] + }, + "ga": { + "and": [ + "*", + "Agus" + ], + "background": [ + "Cúlra" + ], + "but": [ + "*", + "Ach" + ], + "examples": [ + "Samplaí" + ], + "feature": [ + "Gné" + ], + "given": [ + "*", + "Cuir i gcás go", + "Cuir i gcás nach", + "Cuir i gcás gur", + "Cuir i gcás nár" + ], + "name":"Irish", + "native":"Gaeilge", + "rule": [ + "Rule" + ], + "scenario": [ + "Sampla", + "Cás" + ], + "scenarioOutline": [ + "Cás Achomair" + ], + "then": [ + "*", + "Ansin" + ], + "when": [ + "*", + "Nuair a", + "Nuair nach", + "Nuair ba", + "Nuair nár" + ] + }, + "gj": { + "and": [ + "*", + "અને" + ], + "background": [ + "બેકગ્રાઉન્ડ" + ], + "but": [ + "*", + "પણ" + ], + "examples": [ + "ઉદાહરણો" + ], + "feature": [ + "લક્ષણ", + "વ્યાપાર જરૂર", + "ક્ષમતા" + ], + "given": [ + "*", + "આપેલ છે" + ], + "name":"Gujarati", + "native":"ગુજરાતી", + "rule": [ + "Rule" + ], + "scenario": [ + "ઉદાહરણ", + "સ્થિતિ" + ], + "scenarioOutline": [ + "પરિદ્દશ્ય રૂપરેખા", + "પરિદ્દશ્ય ઢાંચો" + ], + "then": [ + "*", + "પછી" + ], + "when": [ + "*", + "ક્યારે" + ] + }, + "gl": { + "and": [ + "*", + "E" + ], + "background": [ + "Contexto" + ], + "but": [ + "*", + "Mais", + "Pero" + ], + "examples": [ + "Exemplos" + ], + "feature": [ + "Característica" + ], + "given": [ + "*", + "Dado", + "Dada", + "Dados", + "Dadas" + ], + "name":"Galician", + "native":"galego", + "rule": [ + "Rule" + ], + "scenario": [ + "Exemplo", + "Escenario" + ], + "scenarioOutline": [ + "Esbozo do escenario" + ], + "then": [ + "*", + "Entón", + "Logo" + ], + "when": [ + "*", + "Cando" + ] + }, + "he": { + "and": [ + "*", + "וגם" + ], + "background": [ + "רקע" + ], + "but": [ + "*", + "אבל" + ], + "examples": [ + "דוגמאות" + ], + "feature": [ + "תכונה" + ], + "given": [ + "*", + "בהינתן" + ], + "name":"Hebrew", + "native":"עברית", + "rule": [ + "כלל" + ], + "scenario": [ + "דוגמא", + "תרחיש" + ], + "scenarioOutline": [ + "תבנית תרחיש" + ], + "then": [ + "*", + "אז", + "אזי" + ], + "when": [ + "*", + "כאשר" + ] + }, + "hi": { + "and": [ + "*", + "और", + "तथा" + ], + "background": [ + "पृष्ठभूमि" + ], + "but": [ + "*", + "पर", + "परन्तु", + "किन्तु" + ], + "examples": [ + "उदाहरण" + ], + "feature": [ + "रूप लेख" + ], + "given": [ + "*", + "अगर", + "यदि", + "चूंकि" + ], + "name":"Hindi", + "native":"हिंदी", + "rule": [ + "Rule" + ], + "scenario": [ + "परिदृश्य" + ], + "scenarioOutline": [ + "परिदृश्य रूपरेखा" + ], + "then": [ + "*", + "तब", + "तदा" + ], + "when": [ + "*", + "जब", + "कदा" + ] + }, + "hr": { + "and": [ + "*", + "I" + ], + "background": [ + "Pozadina" + ], + "but": [ + "*", + "Ali" + ], + "examples": [ + "Primjeri", + "Scenariji" + ], + "feature": [ + "Osobina", + "Mogućnost", + "Mogucnost" + ], + "given": [ + "*", + "Zadan", + "Zadani", + "Zadano", + "Ukoliko" + ], + "name":"Croatian", + "native":"hrvatski", + "rule": [ + "Rule" + ], + "scenario": [ + "Primjer", + "Scenarij" + ], + "scenarioOutline": [ + "Skica", + "Koncept" + ], + "then": [ + "*", + "Onda" + ], + "when": [ + "*", + "Kada", + "Kad" + ] + }, + "ht": { + "and": [ + "*", + "Ak", + "Epi", + "E" + ], + "background": [ + "Kontèks", + "Istorik" + ], + "but": [ + "*", + "Men" + ], + "examples": [ + "Egzanp" + ], + "feature": [ + "Karakteristik", + "Mak", + "Fonksyonalite" + ], + "given": [ + "*", + "Sipoze", + "Sipoze ke", + "Sipoze Ke" + ], + "name":"Creole", + "native":"kreyòl", + "rule": [ + "Rule" + ], + "scenario": [ + "Senaryo" + ], + "scenarioOutline": [ + "Plan senaryo", + "Plan Senaryo", + "Senaryo deskripsyon", + "Senaryo Deskripsyon", + "Dyagram senaryo", + "Dyagram Senaryo" + ], + "then": [ + "*", + "Lè sa a", + "Le sa a" + ], + "when": [ + "*", + "Lè", + "Le" + ] + }, + "hu": { + "and": [ + "*", + "És" + ], + "background": [ + "Háttér" + ], + "but": [ + "*", + "De" + ], + "examples": [ + "Példák" + ], + "feature": [ + "Jellemző" + ], + "given": [ + "*", + "Amennyiben", + "Adott" + ], + "name":"Hungarian", + "native":"magyar", + "rule": [ + "Rule" + ], + "scenario": [ + "Példa", + "Forgatókönyv" + ], + "scenarioOutline": [ + "Forgatókönyv vázlat" + ], + "then": [ + "*", + "Akkor" + ], + "when": [ + "*", + "Majd", + "Ha", + "Amikor" + ] + }, + "id": { + "and": [ + "*", + "Dan" + ], + "background": [ + "Dasar", + "Latar Belakang" + ], + "but": [ + "*", + "Tapi", + "Tetapi" + ], + "examples": [ + "Contoh", + "Misal" + ], + "feature": [ + "Fitur" + ], + "given": [ + "*", + "Dengan", + "Diketahui", + "Diasumsikan", + "Bila", + "Jika" + ], + "name":"Indonesian", + "native":"Bahasa Indonesia", + "rule": [ + "Rule", + "Aturan" + ], + "scenario": [ + "Skenario" + ], + "scenarioOutline": [ + "Skenario konsep", + "Garis-Besar Skenario" + ], + "then": [ + "*", + "Maka", + "Kemudian" + ], + "when": [ + "*", + "Ketika" + ] + }, + "is": { + "and": [ + "*", + "Og" + ], + "background": [ + "Bakgrunnur" + ], + "but": [ + "*", + "En" + ], + "examples": [ + "Dæmi", + "Atburðarásir" + ], + "feature": [ + "Eiginleiki" + ], + "given": [ + "*", + "Ef" + ], + "name":"Icelandic", + "native":"Íslenska", + "rule": [ + "Rule" + ], + "scenario": [ + "Atburðarás" + ], + "scenarioOutline": [ + "Lýsing Atburðarásar", + "Lýsing Dæma" + ], + "then": [ + "*", + "Þá" + ], + "when": [ + "*", + "Þegar" + ] + }, + "it": { + "and": [ + "*", + "E" + ], + "background": [ + "Contesto" + ], + "but": [ + "*", + "Ma" + ], + "examples": [ + "Esempi" + ], + "feature": [ + "Funzionalità" + ], + "given": [ + "*", + "Dato", + "Data", + "Dati", + "Date" + ], + "name":"Italian", + "native":"italiano", + "rule": [ + "Rule" + ], + "scenario": [ + "Esempio", + "Scenario" + ], + "scenarioOutline": [ + "Schema dello scenario" + ], + "then": [ + "*", + "Allora" + ], + "when": [ + "*", + "Quando" + ] + }, + "ja": { + "and": [ + "*", + "かつ" + ], + "background": [ + "背景" + ], + "but": [ + "*", + "しかし", + "但し", + "ただし" + ], + "examples": [ + "例", + "サンプル" + ], + "feature": [ + "フィーチャ", + "機能" + ], + "given": [ + "*", + "前提" + ], + "name":"Japanese", + "native":"日本語", + "rule": [ + "Rule" + ], + "scenario": [ + "シナリオ" + ], + "scenarioOutline": [ + "シナリオアウトライン", + "シナリオテンプレート", + "テンプレ", + "シナリオテンプレ" + ], + "then": [ + "*", + "ならば" + ], + "when": [ + "*", + "もし" + ] + }, + "jv": { + "and": [ + "*", + "Lan" + ], + "background": [ + "Dasar" + ], + "but": [ + "*", + "Tapi", + "Nanging", + "Ananging" + ], + "examples": [ + "Conto", + "Contone" + ], + "feature": [ + "Fitur" + ], + "given": [ + "*", + "Nalika", + "Nalikaning" + ], + "name":"Javanese", + "native":"Basa Jawa", + "rule": [ + "Rule" + ], + "scenario": [ + "Skenario" + ], + "scenarioOutline": [ + "Konsep skenario" + ], + "then": [ + "*", + "Njuk", + "Banjur" + ], + "when": [ + "*", + "Manawa", + "Menawa" + ] + }, + "ka": { + "and": [ + "*", + "და" + ], + "background": [ + "კონტექსტი" + ], + "but": [ + "*", + "მაგ­რამ" + ], + "examples": [ + "მაგალითები" + ], + "feature": [ + "თვისება" + ], + "given": [ + "*", + "მოცემული" + ], + "name":"Georgian", + "native":"ქართველი", + "rule": [ + "Rule" + ], + "scenario": [ + "მაგალითად", + "სცენარის" + ], + "scenarioOutline": [ + "სცენარის ნიმუში" + ], + "then": [ + "*", + "მაშინ" + ], + "when": [ + "*", + "როდესაც" + ] + }, + "kn": { + "and": [ + "*", + "ಮತ್ತು" + ], + "background": [ + "ಹಿನ್ನೆಲೆ" + ], + "but": [ + "*", + "ಆದರೆ" + ], + "examples": [ + "ಉದಾಹರಣೆಗಳು" + ], + "feature": [ + "ಹೆಚ್ಚಳ" + ], + "given": [ + "*", + "ನೀಡಿದ" + ], + "name":"Kannada", + "native":"ಕನ್ನಡ", + "rule": [ + "Rule" + ], + "scenario": [ + "ಉದಾಹರಣೆ", + "ಕಥಾಸಾರಾಂಶ" + ], + "scenarioOutline": [ + "ವಿವರಣೆ" + ], + "then": [ + "*", + "ನಂತರ" + ], + "when": [ + "*", + "ಸ್ಥಿತಿಯನ್ನು" + ] + }, + "ko": { + "and": [ + "*", + "그리고" + ], + "background": [ + "배경" + ], + "but": [ + "*", + "하지만", + "단" + ], + "examples": [ + "예" + ], + "feature": [ + "기능" + ], + "given": [ + "*", + "조건", + "먼저" + ], + "name":"Korean", + "native":"한국어", + "rule": [ + "Rule" + ], + "scenario": [ + "시나리오" + ], + "scenarioOutline": [ + "시나리오 개요" + ], + "then": [ + "*", + "그러면" + ], + "when": [ + "*", + "만일", + "만약" + ] + }, + "lt": { + "and": [ + "*", + "Ir" + ], + "background": [ + "Kontekstas" + ], + "but": [ + "*", + "Bet" + ], + "examples": [ + "Pavyzdžiai", + "Scenarijai", + "Variantai" + ], + "feature": [ + "Savybė" + ], + "given": [ + "*", + "Duota" + ], + "name":"Lithuanian", + "native":"lietuvių kalba", + "rule": [ + "Rule" + ], + "scenario": [ + "Pavyzdys", + "Scenarijus" + ], + "scenarioOutline": [ + "Scenarijaus šablonas" + ], + "then": [ + "*", + "Tada" + ], + "when": [ + "*", + "Kai" + ] + }, + "lu": { + "and": [ + "*", + "an", + "a" + ], + "background": [ + "Hannergrond" + ], + "but": [ + "*", + "awer", + "mä" + ], + "examples": [ + "Beispiller" + ], + "feature": [ + "Funktionalitéit" + ], + "given": [ + "*", + "ugeholl" + ], + "name":"Luxemburgish", + "native":"Lëtzebuergesch", + "rule": [ + "Rule" + ], + "scenario": [ + "Beispill", + "Szenario" + ], + "scenarioOutline": [ + "Plang vum Szenario" + ], + "then": [ + "*", + "dann" + ], + "when": [ + "*", + "wann" + ] + }, + "lv": { + "and": [ + "*", + "Un" + ], + "background": [ + "Konteksts", + "Situācija" + ], + "but": [ + "*", + "Bet" + ], + "examples": [ + "Piemēri", + "Paraugs" + ], + "feature": [ + "Funkcionalitāte", + "Fīča" + ], + "given": [ + "*", + "Kad" + ], + "name":"Latvian", + "native":"latviešu", + "rule": [ + "Rule" + ], + "scenario": [ + "Piemērs", + "Scenārijs" + ], + "scenarioOutline": [ + "Scenārijs pēc parauga" + ], + "then": [ + "*", + "Tad" + ], + "when": [ + "*", + "Ja" + ] + }, + "mk-Cyrl": { + "and": [ + "*", + "И" + ], + "background": [ + "Контекст", + "Содржина" + ], + "but": [ + "*", + "Но" + ], + "examples": [ + "Примери", + "Сценарија" + ], + "feature": [ + "Функционалност", + "Бизнис потреба", + "Можност" + ], + "given": [ + "*", + "Дадено", + "Дадена" + ], + "name":"Macedonian", + "native":"Македонски", + "rule": [ + "Rule" + ], + "scenario": [ + "Пример", + "Сценарио", + "На пример" + ], + "scenarioOutline": [ + "Преглед на сценарија", + "Скица", + "Концепт" + ], + "then": [ + "*", + "Тогаш" + ], + "when": [ + "*", + "Кога" + ] + }, + "mk-Latn": { + "and": [ + "*", + "I" + ], + "background": [ + "Kontekst", + "Sodrzhina" + ], + "but": [ + "*", + "No" + ], + "examples": [ + "Primeri", + "Scenaria" + ], + "feature": [ + "Funkcionalnost", + "Biznis potreba", + "Mozhnost" + ], + "given": [ + "*", + "Dadeno", + "Dadena" + ], + "name":"Macedonian (Latin)", + "native":"Makedonski (Latinica)", + "rule": [ + "Rule" + ], + "scenario": [ + "Scenario", + "Na primer" + ], + "scenarioOutline": [ + "Pregled na scenarija", + "Skica", + "Koncept" + ], + "then": [ + "*", + "Togash" + ], + "when": [ + "*", + "Koga" + ] + }, + "mn": { + "and": [ + "*", + "Мөн", + "Тэгээд" + ], + "background": [ + "Агуулга" + ], + "but": [ + "*", + "Гэхдээ", + "Харин" + ], + "examples": [ + "Тухайлбал" + ], + "feature": [ + "Функц", + "Функционал" + ], + "given": [ + "*", + "Өгөгдсөн нь", + "Анх" + ], + "name":"Mongolian", + "native":"монгол", + "rule": [ + "Rule" + ], + "scenario": [ + "Сценар" + ], + "scenarioOutline": [ + "Сценарын төлөвлөгөө" + ], + "then": [ + "*", + "Тэгэхэд", + "Үүний дараа" + ], + "when": [ + "*", + "Хэрэв" + ] + }, + "ne": { + "and": [ + "*", + "र", + "अनी" + ], + "background": [ + "पृष्ठभूमी" + ], + "but": [ + "*", + "तर" + ], + "examples": [ + "उदाहरण", + "उदाहरणहरु" + ], + "feature": [ + "सुविधा", + "विशेषता" + ], + "given": [ + "*", + "दिइएको", + "दिएको", + "यदि" + ], + "name":"Nepali", + "native":"नेपाली", + "rule": [ + "नियम" + ], + "scenario": [ + "परिदृश्य" + ], + "scenarioOutline": [ + "परिदृश्य रूपरेखा" + ], + "then": [ + "*", + "त्यसपछि", + "अनी" + ], + "when": [ + "*", + "जब" + ] + }, + "nl": { + "and": [ + "*", + "En" + ], + "background": [ + "Achtergrond" + ], + "but": [ + "*", + "Maar" + ], + "examples": [ + "Voorbeelden" + ], + "feature": [ + "Functionaliteit" + ], + "given": [ + "*", + "Gegeven", + "Stel" + ], + "name":"Dutch", + "native":"Nederlands", + "rule": [ + "Rule" + ], + "scenario": [ + "Voorbeeld", + "Scenario" + ], + "scenarioOutline": [ + "Abstract Scenario" + ], + "then": [ + "*", + "Dan" + ], + "when": [ + "*", + "Als", + "Wanneer" + ] + }, + "no": { + "and": [ + "*", + "Og" + ], + "background": [ + "Bakgrunn" + ], + "but": [ + "*", + "Men" + ], + "examples": [ + "Eksempler" + ], + "feature": [ + "Egenskap" + ], + "given": [ + "*", + "Gitt" + ], + "name":"Norwegian", + "native":"norsk", + "rule": [ + "Regel" + ], + "scenario": [ + "Eksempel", + "Scenario" + ], + "scenarioOutline": [ + "Scenariomal", + "Abstrakt Scenario" + ], + "then": [ + "*", + "Så" + ], + "when": [ + "*", + "Når" + ] + }, + "pa": { + "and": [ + "*", + "ਅਤੇ" + ], + "background": [ + "ਪਿਛੋਕੜ" + ], + "but": [ + "*", + "ਪਰ" + ], + "examples": [ + "ਉਦਾਹਰਨਾਂ" + ], + "feature": [ + "ਖਾਸੀਅਤ", + "ਮੁਹਾਂਦਰਾ", + "ਨਕਸ਼ ਨੁਹਾਰ" + ], + "given": [ + "*", + "ਜੇਕਰ", + "ਜਿਵੇਂ ਕਿ" + ], + "name":"Panjabi", + "native":"ਪੰਜਾਬੀ", + "rule": [ + "Rule" + ], + "scenario": [ + "ਉਦਾਹਰਨ", + "ਪਟਕਥਾ" + ], + "scenarioOutline": [ + "ਪਟਕਥਾ ਢਾਂਚਾ", + "ਪਟਕਥਾ ਰੂਪ ਰੇਖਾ" + ], + "then": [ + "*", + "ਤਦ" + ], + "when": [ + "*", + "ਜਦੋਂ" + ] + }, + "pl": { + "and": [ + "*", + "Oraz", + "I" + ], + "background": [ + "Założenia" + ], + "but": [ + "*", + "Ale" + ], + "examples": [ + "Przykłady" + ], + "feature": [ + "Właściwość", + "Funkcja", + "Aspekt", + "Potrzeba biznesowa" + ], + "given": [ + "*", + "Zakładając", + "Mając", + "Zakładając, że" + ], + "name":"Polish", + "native":"polski", + "rule": [ + "Rule" + ], + "scenario": [ + "Przykład", + "Scenariusz" + ], + "scenarioOutline": [ + "Szablon scenariusza" + ], + "then": [ + "*", + "Wtedy" + ], + "when": [ + "*", + "Jeżeli", + "Jeśli", + "Gdy", + "Kiedy" + ] + }, + "pt": { + "and": [ + "*", + "E" + ], + "background": [ + "Contexto", + "Cenário de Fundo", + "Cenario de Fundo", + "Fundo" + ], + "but": [ + "*", + "Mas" + ], + "examples": [ + "Exemplos", + "Cenários", + "Cenarios" + ], + "feature": [ + "Funcionalidade", + "Característica", + "Caracteristica" + ], + "given": [ + "*", + "Dado", + "Dada", + "Dados", + "Dadas" + ], + "name":"Portuguese", + "native":"português", + "rule": [ + "Regra" + ], + "scenario": [ + "Exemplo", + "Cenário", + "Cenario" + ], + "scenarioOutline": [ + "Esquema do Cenário", + "Esquema do Cenario", + "Delineação do Cenário", + "Delineacao do Cenario" + ], + "then": [ + "*", + "Então", + "Entao" + ], + "when": [ + "*", + "Quando" + ] + }, + "ro": { + "and": [ + "*", + "Si", + "Și", + "Şi" + ], + "background": [ + "Context" + ], + "but": [ + "*", + "Dar" + ], + "examples": [ + "Exemple" + ], + "feature": [ + "Functionalitate", + "Funcționalitate", + "Funcţionalitate" + ], + "given": [ + "*", + "Date fiind", + "Dat fiind", + "Dată fiind", + "Dati fiind", + "Dați fiind", + "Daţi fiind" + ], + "name":"Romanian", + "native":"română", + "rule": [ + "Rule" + ], + "scenario": [ + "Exemplu", + "Scenariu" + ], + "scenarioOutline": [ + "Structura scenariu", + "Structură scenariu" + ], + "then": [ + "*", + "Atunci" + ], + "when": [ + "*", + "Cand", + "Când" + ] + }, + "ru": { + "and": [ + "*", + "И", + "К тому же", + "Также" + ], + "background": [ + "Предыстория", + "Контекст" + ], + "but": [ + "*", + "Но", + "А", + "Иначе" + ], + "examples": [ + "Примеры" + ], + "feature": [ + "Функция", + "Функциональность", + "Функционал", + "Свойство" + ], + "given": [ + "*", + "Допустим", + "Дано", + "Пусть" + ], + "name":"Russian", + "native":"русский", + "rule": [ + "Правило" + ], + "scenario": [ + "Пример", + "Сценарий" + ], + "scenarioOutline": [ + "Структура сценария" + ], + "then": [ + "*", + "То", + "Затем", + "Тогда" + ], + "when": [ + "*", + "Когда", + "Если" + ] + }, + "sk": { + "and": [ + "*", + "A", + "A tiež", + "A taktiež", + "A zároveň" + ], + "background": [ + "Pozadie" + ], + "but": [ + "*", + "Ale" + ], + "examples": [ + "Príklady" + ], + "feature": [ + "Požiadavka", + "Funkcia", + "Vlastnosť" + ], + "given": [ + "*", + "Pokiaľ", + "Za predpokladu" + ], + "name":"Slovak", + "native":"Slovensky", + "rule": [ + "Rule" + ], + "scenario": [ + "Príklad", + "Scenár" + ], + "scenarioOutline": [ + "Náčrt Scenáru", + "Náčrt Scenára", + "Osnova Scenára" + ], + "then": [ + "*", + "Tak", + "Potom" + ], + "when": [ + "*", + "Keď", + "Ak" + ] + }, + "sl": { + "and": [ + "In", + "Ter" + ], + "background": [ + "Kontekst", + "Osnova", + "Ozadje" + ], + "but": [ + "Toda", + "Ampak", + "Vendar" + ], + "examples": [ + "Primeri", + "Scenariji" + ], + "feature": [ + "Funkcionalnost", + "Funkcija", + "Možnosti", + "Moznosti", + "Lastnost", + "Značilnost" + ], + "given": [ + "Dano", + "Podano", + "Zaradi", + "Privzeto" + ], + "name":"Slovenian", + "native":"Slovenski", + "rule": [ + "Rule" + ], + "scenario": [ + "Primer", + "Scenarij" + ], + "scenarioOutline": [ + "Struktura scenarija", + "Skica", + "Koncept", + "Oris scenarija", + "Osnutek" + ], + "then": [ + "Nato", + "Potem", + "Takrat" + ], + "when": [ + "Ko", + "Ce", + "Če", + "Kadar" + ] + }, + "sr-Cyrl": { + "and": [ + "*", + "И" + ], + "background": [ + "Контекст", + "Основа", + "Позадина" + ], + "but": [ + "*", + "Али" + ], + "examples": [ + "Примери", + "Сценарији" + ], + "feature": [ + "Функционалност", + "Могућност", + "Особина" + ], + "given": [ + "*", + "За дато", + "За дате", + "За дати" + ], + "name":"Serbian", + "native":"Српски", + "rule": [ + "Rule" + ], + "scenario": [ + "Пример", + "Сценарио", + "Пример" + ], + "scenarioOutline": [ + "Структура сценарија", + "Скица", + "Концепт" + ], + "then": [ + "*", + "Онда" + ], + "when": [ + "*", + "Када", + "Кад" + ] + }, + "sr-Latn": { + "and": [ + "*", + "I" + ], + "background": [ + "Kontekst", + "Osnova", + "Pozadina" + ], + "but": [ + "*", + "Ali" + ], + "examples": [ + "Primeri", + "Scenariji" + ], + "feature": [ + "Funkcionalnost", + "Mogućnost", + "Mogucnost", + "Osobina" + ], + "given": [ + "*", + "Za dato", + "Za date", + "Za dati" + ], + "name":"Serbian (Latin)", + "native":"Srpski (Latinica)", + "rule": [ + "Rule" + ], + "scenario": [ + "Scenario", + "Primer" + ], + "scenarioOutline": [ + "Struktura scenarija", + "Skica", + "Koncept" + ], + "then": [ + "*", + "Onda" + ], + "when": [ + "*", + "Kada", + "Kad" + ] + }, + "sv": { + "and": [ + "*", + "Och" + ], + "background": [ + "Bakgrund" + ], + "but": [ + "*", + "Men" + ], + "examples": [ + "Exempel" + ], + "feature": [ + "Egenskap" + ], + "given": [ + "*", + "Givet" + ], + "name":"Swedish", + "native":"Svenska", + "rule": [ + "Rule" + ], + "scenario": [ + "Scenario" + ], + "scenarioOutline": [ + "Abstrakt Scenario", + "Scenariomall" + ], + "then": [ + "*", + "Så" + ], + "when": [ + "*", + "När" + ] + }, + "ta": { + "and": [ + "*", + "மேலும் ", + "மற்றும்" + ], + "background": [ + "பின்னணி" + ], + "but": [ + "*", + "ஆனால் " + ], + "examples": [ + "எடுத்துக்காட்டுகள்", + "காட்சிகள்", + "நிலைமைகளில்" + ], + "feature": [ + "அம்சம்", + "வணிக தேவை", + "திறன்" + ], + "given": [ + "*", + "கொடுக்கப்பட்ட" + ], + "name":"Tamil", + "native":"தமிழ்", + "rule": [ + "Rule" + ], + "scenario": [ + "உதாரணமாக", + "காட்சி" + ], + "scenarioOutline": [ + "காட்சி சுருக்கம்", + "காட்சி வார்ப்புரு" + ], + "then": [ + "*", + "அப்பொழுது" + ], + "when": [ + "*", + "எப்போது" + ] + }, + "th": { + "and": [ + "*", + "และ" + ], + "background": [ + "แนวคิด" + ], + "but": [ + "*", + "แต่" + ], + "examples": [ + "ชุดของตัวอย่าง", + "ชุดของเหตุการณ์" + ], + "feature": [ + "โครงหลัก", + "ความต้องการทางธุรกิจ", + "ความสามารถ" + ], + "given": [ + "*", + "กำหนดให้" + ], + "name":"Thai", + "native":"ไทย", + "rule": [ + "Rule" + ], + "scenario": [ + "เหตุการณ์" + ], + "scenarioOutline": [ + "สรุปเหตุการณ์", + "โครงสร้างของเหตุการณ์" + ], + "then": [ + "*", + "ดังนั้น" + ], + "when": [ + "*", + "เมื่อ" + ] + }, + "tl": { + "and": [ + "*", + "మరియు" + ], + "background": [ + "నేపథ్యం" + ], + "but": [ + "*", + "కాని" + ], + "examples": [ + "ఉదాహరణలు" + ], + "feature": [ + "గుణము" + ], + "given": [ + "*", + "చెప్పబడినది" + ], + "name":"Telugu", + "native":"తెలుగు", + "rule": [ + "Rule" + ], + "scenario": [ + "ఉదాహరణ", + "సన్నివేశం" + ], + "scenarioOutline": [ + "కథనం" + ], + "then": [ + "*", + "అప్పుడు" + ], + "when": [ + "*", + "ఈ పరిస్థితిలో" + ] + }, + "tlh": { + "and": [ + "*", + "'ej", + "latlh" + ], + "background": [ + "mo'" + ], + "but": [ + "*", + "'ach", + "'a" + ], + "examples": [ + "ghantoH", + "lutmey" + ], + "feature": [ + "Qap", + "Qu'meH 'ut", + "perbogh", + "poQbogh malja'", + "laH" + ], + "given": [ + "*", + "ghu' noblu'", + "DaH ghu' bejlu'" + ], + "name":"Klingon", + "native":"tlhIngan", + "rule": [ + "Rule" + ], + "scenario": [ + "lut" + ], + "scenarioOutline": [ + "lut chovnatlh" + ], + "then": [ + "*", + "vaj" + ], + "when": [ + "*", + "qaSDI'" + ] + }, + "tr": { + "and": [ + "*", + "Ve" + ], + "background": [ + "Geçmiş" + ], + "but": [ + "*", + "Fakat", + "Ama" + ], + "examples": [ + "Örnekler" + ], + "feature": [ + "Özellik" + ], + "given": [ + "*", + "Diyelim ki" + ], + "name":"Turkish", + "native":"Türkçe", + "rule": [ + "Rule" + ], + "scenario": [ + "Örnek", + "Senaryo" + ], + "scenarioOutline": [ + "Senaryo taslağı" + ], + "then": [ + "*", + "O zaman" + ], + "when": [ + "*", + "Eğer ki" + ] + }, + "tt": { + "and": [ + "*", + "Һәм", + "Вә" + ], + "background": [ + "Кереш" + ], + "but": [ + "*", + "Ләкин", + "Әмма" + ], + "examples": [ + "Үрнәкләр", + "Мисаллар" + ], + "feature": [ + "Мөмкинлек", + "Үзенчәлеклелек" + ], + "given": [ + "*", + "Әйтик" + ], + "name":"Tatar", + "native":"Татарча", + "rule": [ + "Rule" + ], + "scenario": [ + "Сценарий" + ], + "scenarioOutline": [ + "Сценарийның төзелеше" + ], + "then": [ + "*", + "Нәтиҗәдә" + ], + "when": [ + "*", + "Әгәр" + ] + }, + "uk": { + "and": [ + "*", + "І", + "А також", + "Та" + ], + "background": [ + "Передумова" + ], + "but": [ + "*", + "Але" + ], + "examples": [ + "Приклади" + ], + "feature": [ + "Функціонал" + ], + "given": [ + "*", + "Припустимо", + "Припустимо, що", + "Нехай", + "Дано" + ], + "name":"Ukrainian", + "native":"Українська", + "rule": [ + "Rule" + ], + "scenario": [ + "Приклад", + "Сценарій" + ], + "scenarioOutline": [ + "Структура сценарію" + ], + "then": [ + "*", + "То", + "Тоді" + ], + "when": [ + "*", + "Якщо", + "Коли" + ] + }, + "ur": { + "and": [ + "*", + "اور" + ], + "background": [ + "پس منظر" + ], + "but": [ + "*", + "لیکن" + ], + "examples": [ + "مثالیں" + ], + "feature": [ + "صلاحیت", + "کاروبار کی ضرورت", + "خصوصیت" + ], + "given": [ + "*", + "اگر", + "بالفرض", + "فرض کیا" + ], + "name":"Urdu", + "native":"اردو", + "rule": [ + "Rule" + ], + "scenario": [ + "منظرنامہ" + ], + "scenarioOutline": [ + "منظر نامے کا خاکہ" + ], + "then": [ + "*", + "پھر", + "تب" + ], + "when": [ + "*", + "جب" + ] + }, + "uz": { + "and": [ + "*", + "Ва" + ], + "background": [ + "Тарих" + ], + "but": [ + "*", + "Лекин", + "Бирок", + "Аммо" + ], + "examples": [ + "Мисоллар" + ], + "feature": [ + "Функционал" + ], + "given": [ + "*", + "Агар" + ], + "name":"Uzbek", + "native":"Узбекча", + "rule": [ + "Rule" + ], + "scenario": [ + "Сценарий" + ], + "scenarioOutline": [ + "Сценарий структураси" + ], + "then": [ + "*", + "Унда" + ], + "when": [ + "*", + "Агар" + ] + }, + "vi": { + "and": [ + "*", + "Và" + ], + "background": [ + "Bối cảnh" + ], + "but": [ + "*", + "Nhưng" + ], + "examples": [ + "Dữ liệu" + ], + "feature": [ + "Tính năng" + ], + "given": [ + "*", + "Biết", + "Cho" + ], + "name":"Vietnamese", + "native":"Tiếng Việt", + "rule": [ + "Rule" + ], + "scenario": [ + "Tình huống", + "Kịch bản" + ], + "scenarioOutline": [ + "Khung tình huống", + "Khung kịch bản" + ], + "then": [ + "*", + "Thì" + ], + "when": [ + "*", + "Khi" + ] + }, + "zh-CN": { + "and": [ + "*", + "而且", + "并且", + "同时" + ], + "background": [ + "背景" + ], + "but": [ + "*", + "但是" + ], + "examples": [ + "例子" + ], + "feature": [ + "功能" + ], + "given": [ + "*", + "假如", + "假设", + "假定" + ], + "name":"Chinese simplified", + "native":"简体中文", + "rule": [ + "Rule" + ], + "scenario": [ + "场景", + "剧本" + ], + "scenarioOutline": [ + "场景大纲", + "剧本大纲" + ], + "then": [ + "*", + "那么" + ], + "when": [ + "*", + "当" + ] + }, + "zh-TW": { + "and": [ + "*", + "而且", + "並且", + "同時" + ], + "background": [ + "背景" + ], + "but": [ + "*", + "但是" + ], + "examples": [ + "例子" + ], + "feature": [ + "功能" + ], + "given": [ + "*", + "假如", + "假設", + "假定" + ], + "name":"Chinese traditional", + "native":"繁體中文", + "rule": [ + "Rule" + ], + "scenario": [ + "場景", + "劇本" + ], + "scenarioOutline": [ + "場景大綱", + "劇本大綱" + ], + "then": [ + "*", + "那麼" + ], + "when": [ + "*", + "當" + ] + }, + "mr": { + "and": [ + "*", + "आणि", + "तसेच" + ], + "background": [ + "पार्श्वभूमी" + ], + "but": [ + "*", + "पण", + "परंतु" + ], + "examples": [ + "उदाहरण" + ], + "feature": [ + "वैशिष्ट्य", + "सुविधा" + ], + "given": [ + "*", + "जर", + "दिलेल्या प्रमाणे" + ], + "name":"Marathi", + "native":"मराठी", + "rule": [ + "नियम" + ], + "scenario": [ + "परिदृश्य" + ], + "scenarioOutline": [ + "परिदृश्य रूपरेखा" + ], + "then": [ + "*", + "मग", + "तेव्हा" + ], + "when": [ + "*", + "जेव्हा" + ] + } +} \ No newline at end of file diff --git a/ExtentReports/Listener/Entity/AttributeEntity.cs b/ExtentReports/Listener/Entity/AttributeEntity.cs new file mode 100644 index 0000000..55680ce --- /dev/null +++ b/ExtentReports/Listener/Entity/AttributeEntity.cs @@ -0,0 +1,9 @@ +using AventStack.ExtentReports.Model; + +namespace AventStack.ExtentReports.Listener.Entity +{ + public class AttributeEntity : IObservedEntity + { + + } +} diff --git a/ExtentReports/Listener/Entity/IObservedEntity.cs b/ExtentReports/Listener/Entity/IObservedEntity.cs new file mode 100644 index 0000000..a656d75 --- /dev/null +++ b/ExtentReports/Listener/Entity/IObservedEntity.cs @@ -0,0 +1,6 @@ +namespace AventStack.ExtentReports.Listener.Entity +{ + public interface IObservedEntity + { + } +} diff --git a/ExtentReports/Listener/Entity/LogEntity.cs b/ExtentReports/Listener/Entity/LogEntity.cs new file mode 100644 index 0000000..1c2e055 --- /dev/null +++ b/ExtentReports/Listener/Entity/LogEntity.cs @@ -0,0 +1,9 @@ +using AventStack.ExtentReports.Model; + +namespace AventStack.ExtentReports.Listener.Entity +{ + public class LogEntity : IObservedEntity + { + + } +} diff --git a/ExtentReports/Listener/Entity/MediaEntity.cs b/ExtentReports/Listener/Entity/MediaEntity.cs new file mode 100644 index 0000000..de1bf3c --- /dev/null +++ b/ExtentReports/Listener/Entity/MediaEntity.cs @@ -0,0 +1,9 @@ +using AventStack.ExtentReports.Model; + +namespace AventStack.ExtentReports.Listener.Entity +{ + public class MediaEntity : IObservedEntity + { + + } +} diff --git a/ExtentReports/Listener/Entity/NamedAttributeTestEntity.cs b/ExtentReports/Listener/Entity/NamedAttributeTestEntity.cs new file mode 100644 index 0000000..46c6075 --- /dev/null +++ b/ExtentReports/Listener/Entity/NamedAttributeTestEntity.cs @@ -0,0 +1,9 @@ +using AventStack.ExtentReports.Model; + +namespace AventStack.ExtentReports.Listener.Entity +{ + public class NamedAttributeTestEntity : IObservedEntity + { + + } +} diff --git a/ExtentReports/Listener/Entity/ReportEntity.cs b/ExtentReports/Listener/Entity/ReportEntity.cs new file mode 100644 index 0000000..5fc8098 --- /dev/null +++ b/ExtentReports/Listener/Entity/ReportEntity.cs @@ -0,0 +1,9 @@ +using AventStack.ExtentReports.Model; + +namespace AventStack.ExtentReports.Listener.Entity +{ + public class ReportEntity : IObservedEntity + { + public Report Report { get; set; } + } +} diff --git a/ExtentReports/Listener/Entity/TestEntity.cs b/ExtentReports/Listener/Entity/TestEntity.cs new file mode 100644 index 0000000..e8903f8 --- /dev/null +++ b/ExtentReports/Listener/Entity/TestEntity.cs @@ -0,0 +1,9 @@ +using AventStack.ExtentReports.Model; + +namespace AventStack.ExtentReports.Listener.Entity +{ + public class TestEntity : IObservedEntity + { + + } +} diff --git a/ExtentReports/Listener/IExtentObserver.cs b/ExtentReports/Listener/IExtentObserver.cs new file mode 100644 index 0000000..327977b --- /dev/null +++ b/ExtentReports/Listener/IExtentObserver.cs @@ -0,0 +1,8 @@ +using AventStack.ExtentReports.Listener.Entity; + +namespace AventStack.ExtentReports.Listener +{ + public interface IExtentObserver where T : IObservedEntity + { + } +} diff --git a/ExtentReports/Listener/IReportObserver.cs b/ExtentReports/Listener/IReportObserver.cs new file mode 100644 index 0000000..bf5cb04 --- /dev/null +++ b/ExtentReports/Listener/IReportObserver.cs @@ -0,0 +1,9 @@ +using AventStack.ExtentReports.Listener.Entity; + +namespace AventStack.ExtentReports.Listener +{ + public interface IReportObserver : IExtentObserver where T : ReportEntity + { + + } +} diff --git a/extentreports-dotnet-core/MarkupUtils/CodeBlock.cs b/ExtentReports/MarkupUtils/CodeBlock.cs similarity index 51% rename from extentreports-dotnet-core/MarkupUtils/CodeBlock.cs rename to ExtentReports/MarkupUtils/CodeBlock.cs index aee7127..efe0ffd 100644 --- a/extentreports-dotnet-core/MarkupUtils/CodeBlock.cs +++ b/ExtentReports/MarkupUtils/CodeBlock.cs @@ -4,26 +4,39 @@ namespace AventStack.ExtentReports.MarkupUtils { internal class CodeBlock : IMarkup { - public string Code { get; set; } - public CodeLanguage CodeLang { get; set; } + public string[] Code { get; set; } + public CodeLanguage CodeLang { get; set; } = CodeLanguage.Xml; private int _id { get; } = Interlocked.Increment(ref _cntr); private static int _cntr; public string GetMarkup() { + if (Code == null) + { + return ""; + } + if (CodeLang == CodeLanguage.Json) { return "
" + ""; } - var lhs = ""; - return lhs + Code + rhs; + var col = (12 / Code.Length) % 1 == 0 ? 12 / Code.Length : 12; + var lhs = "
"; + var code = string.Empty; + + foreach (var c in Code) + { + code += lhs + c + rhs; + } + + return "
" + code + "
"; } } } diff --git a/extentreports-dotnet-core/MarkupUtils/CodeLanguage.cs b/ExtentReports/MarkupUtils/CodeLanguage.cs similarity index 100% rename from extentreports-dotnet-core/MarkupUtils/CodeLanguage.cs rename to ExtentReports/MarkupUtils/CodeLanguage.cs diff --git a/extentreports-dotnet-core/MarkupUtils/ExtentColor.cs b/ExtentReports/MarkupUtils/ExtentColor.cs similarity index 100% rename from extentreports-dotnet-core/MarkupUtils/ExtentColor.cs rename to ExtentReports/MarkupUtils/ExtentColor.cs diff --git a/extentreports-dotnet-core/MarkupUtils/IMarkup.cs b/ExtentReports/MarkupUtils/IMarkup.cs similarity index 100% rename from extentreports-dotnet-core/MarkupUtils/IMarkup.cs rename to ExtentReports/MarkupUtils/IMarkup.cs diff --git a/extentreports-dotnet-core/MarkupUtils/Label.cs b/ExtentReports/MarkupUtils/Label.cs similarity index 68% rename from extentreports-dotnet-core/MarkupUtils/Label.cs rename to ExtentReports/MarkupUtils/Label.cs index 9ceceec..0f6c2ed 100644 --- a/extentreports-dotnet-core/MarkupUtils/Label.cs +++ b/ExtentReports/MarkupUtils/Label.cs @@ -4,11 +4,15 @@ internal class Label : IMarkup { public string Text { get; set; } public ExtentColor Color { get; set; } - public ExtentColor TextColor { get; set; } = ExtentColor.Black; public string GetMarkup() { - var textColor = TextColor.ToString().ToLower() + "-text"; + if (string.IsNullOrEmpty(Text)) + { + return ""; + } + + var textColor = Color != ExtentColor.White ? "white-text" : "black-text"; var lhs = ""; var rhs = ""; return lhs + Text + rhs; diff --git a/ExtentReports/MarkupUtils/ListMarkup.cs b/ExtentReports/MarkupUtils/ListMarkup.cs new file mode 100644 index 0000000..1328fec --- /dev/null +++ b/ExtentReports/MarkupUtils/ListMarkup.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Text; + +namespace AventStack.ExtentReports.MarkupUtils +{ + internal class ListMarkup : IMarkup + { + public string Type { get; internal set; } + public IEnumerable Object { get; internal set; } + + public string GetMarkup() + { + var sb = new StringBuilder(); + sb.Append("<" + Type + ">"); + + foreach (var x in Object) + { + sb.Append("
  • "); + if (x != null) + { + sb.Append(x.ToString()); + } + sb.Append("
  • "); + } + + sb.Append(""); + return sb.ToString(); + } + } +} diff --git a/ExtentReports/MarkupUtils/ListType.cs b/ExtentReports/MarkupUtils/ListType.cs new file mode 100644 index 0000000..5230cfa --- /dev/null +++ b/ExtentReports/MarkupUtils/ListType.cs @@ -0,0 +1,7 @@ +namespace AventStack.ExtentReports.MarkupUtils +{ + internal enum ListType + { + OL, UL + } +} diff --git a/ExtentReports/MarkupUtils/MarkupHelper.cs b/ExtentReports/MarkupUtils/MarkupHelper.cs new file mode 100644 index 0000000..40f4345 --- /dev/null +++ b/ExtentReports/MarkupUtils/MarkupHelper.cs @@ -0,0 +1,79 @@ +using System.Collections.Generic; + +namespace AventStack.ExtentReports.MarkupUtils +{ + public class MarkupHelper + { + public static IMarkup CreateLabel(string text, ExtentColor color) + { + var label = new Label + { + Text = text, + Color = color + }; + return label; + } + + public static IMarkup CreateCodeBlock(string code, CodeLanguage lang = CodeLanguage.Xml) + { + if (code == null) + { + return new CodeBlock(); + } + + var cb = new CodeBlock + { + Code = new string[] { code }, + CodeLang = lang + }; + return cb; + } + + public static IMarkup CreateCodeBlock(params string[] code) + { + var cb = new CodeBlock + { + Code = code + }; + return cb; + } + + public static IMarkup CreateTable(string[,] data) + { + var t = new Table + { + Data = data + }; + return t; + } + + public static IMarkup ToTable(object obj) + { + var t = new Table + { + Object = obj + }; + return t; + } + + public static IMarkup CreateOrderedList(IEnumerable enumerable) + { + var x = new ListMarkup + { + Type = "ol", + Object = enumerable + }; + return x; + } + + public static IMarkup CreateUnorderedList(IEnumerable enumerable) + { + var x = new ListMarkup + { + Type = "ul", + Object = enumerable + }; + return x; + } + } +} diff --git a/ExtentReports/MarkupUtils/Table.cs b/ExtentReports/MarkupUtils/Table.cs new file mode 100644 index 0000000..c2b6374 --- /dev/null +++ b/ExtentReports/MarkupUtils/Table.cs @@ -0,0 +1,114 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AventStack.ExtentReports.MarkupUtils +{ + internal class Table : IMarkup + { + public string[,] Data { get; internal set; } + public object Object { get; internal set; } + + public string GetMarkup() + { + if (Object == null && Data == null) + { + return ""; + } + + var sb = new StringBuilder(); + if (Object != null) + { + sb.Append(""); + sb.Append(""); + sb.Append(""); + + var t = typeof(T); + var props = t.GetProperties(); + + foreach (var col in props) + { + sb.Append(""); + } + + sb.Append(""); + sb.Append(""); + sb.Append(""); + + var tableInfo = new TableInfo(); + + for (var ix = 0; ix < props.Length; ix++) + { + var value = props[ix].GetValue(Object, null); + if (!(value is string) && (value is IEnumerable || value.GetType().IsArray)) + { + foreach (var x in (IEnumerable)value) + { + if (value != null) + { + tableInfo.AddCellValue(x.ToString(), ix); + } + else + { + tableInfo.AddCellValue("", ix); + } + } + } + else + { + tableInfo.AddCellValue(value.ToString(), ix); + } + } + + var maxRows = tableInfo.Cells.Max(x => x.Count); + + for (var row = 0; row < maxRows; row++) + { + sb.Append(""); + foreach (var cell in tableInfo.Cells) + { + var value = cell.Count <= row ? "" : cell[row].ToString(); + sb.Append(""); + } + sb.Append(""); + } + + sb.Append(""); + sb.Append("
    "); + sb.Append(col.Name); + sb.Append("
    " + value + "
    "); + + return sb.ToString(); + } + + sb.Append(""); + for (int row = 0; row < Data.GetLength(0); row++) + { + sb.Append(""); + for (int col = 0; col < Data.GetLength(1); col++) + { + sb.Append(""); + } + sb.Append(""); + } + sb.Append("
    " + Data[row, col] + "
    "); + return sb.ToString(); + } + + class TableInfo + { + internal List> Cells = new List>(); + + internal void AddCellValue(string value, int colIndex) + { + if (Cells.Count <= colIndex) + { + Cells.Add(new List()); + } + + Cells[colIndex].Add(value); + } + } + } +} diff --git a/ExtentReports/Model/Author.cs b/ExtentReports/Model/Author.cs new file mode 100644 index 0000000..071c298 --- /dev/null +++ b/ExtentReports/Model/Author.cs @@ -0,0 +1,7 @@ +namespace AventStack.ExtentReports.Model +{ + public class Author : NamedAttribute + { + public Author(string name) : base(name) { } + } +} diff --git a/ExtentReports/Model/BaseEntity.cs b/ExtentReports/Model/BaseEntity.cs new file mode 100644 index 0000000..7ffef67 --- /dev/null +++ b/ExtentReports/Model/BaseEntity.cs @@ -0,0 +1,9 @@ +namespace AventStack.ExtentReports.Model +{ + /// + /// Marker interface for ExtentReports entities + /// + public interface IBaseEntity + { + } +} diff --git a/ExtentReports/Model/Category.cs b/ExtentReports/Model/Category.cs new file mode 100644 index 0000000..f087104 --- /dev/null +++ b/ExtentReports/Model/Category.cs @@ -0,0 +1,7 @@ +namespace AventStack.ExtentReports.Model +{ + public class Category : NamedAttribute + { + public Category(string name) : base(name) { } + } +} diff --git a/ExtentReports/Model/Context/Manager/NamedAttributeContextManager.cs b/ExtentReports/Model/Context/Manager/NamedAttributeContextManager.cs new file mode 100644 index 0000000..f3bea74 --- /dev/null +++ b/ExtentReports/Model/Context/Manager/NamedAttributeContextManager.cs @@ -0,0 +1,55 @@ +using System.Collections.Concurrent; +using System.Linq; + +namespace AventStack.ExtentReports.Model.Context.Manager +{ + public class NamedAttributeContextManager where T: NamedAttribute + { + public ConcurrentDictionary> Context = new ConcurrentDictionary>(); + + public bool HasItems => !Context.IsEmpty; + + public void AddContext(T attr, Test test) + { + if (Context.ContainsKey(attr.Name)) + { + if (!Context[attr.Name].Tests.Any(x => x.Id == test.Id)) + { + Context[attr.Name].AddTest(test); + } + } + else + { + Context.TryAdd(attr.Name, new NamedAttributeContext(attr, test)); + } + } + + public void AddContext(T attr, ConcurrentBag bag) + { + foreach (var v in bag) + { + AddContext(attr, v); + } + } + + public void RemoveTest(Test test) + { + foreach (var context in Context) + { + context.Value.RemoveTest(test); + if (context.Value.Tests.Count == 0) + { + _ = Context.TryRemove(context.Value.Attr.Name, out _); + } + } + } + + public void RefreshAll() + { + foreach (var kv in Context) + { + kv.Value.Refresh(); + } + } + } +} diff --git a/ExtentReports/Model/Context/NamedAttributeContext.cs b/ExtentReports/Model/Context/NamedAttributeContext.cs new file mode 100644 index 0000000..b6dc797 --- /dev/null +++ b/ExtentReports/Model/Context/NamedAttributeContext.cs @@ -0,0 +1,77 @@ +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using AventStack.ExtentReports.Util; + +namespace AventStack.ExtentReports.Model.Context +{ + public class NamedAttributeContext where T : NamedAttribute + { + public static int adding = 0; + public static int removing = 0; + + public ConcurrentQueue Tests { get; private set; } = new ConcurrentQueue(); + public T Attr; + public int Passed { get; private set; } + public int Failed { get; private set; } + public int Skipped { get; private set; } + public int Others { get; private set; } + + private static readonly object _synclock = new object(); + + public NamedAttributeContext(T attr, Test test) + { + Attr = attr; + AddTest(test); + } + + public void AddTest(Test test) + { + Assert.NotNull(test, "Test cannot be null"); + Tests.Enqueue(test); + Compute(test); + } + + private void Compute(Test test) + { + lock (_synclock) + { + Passed += test.Status == Status.Pass ? 1 : 0; + Failed += test.Status == Status.Fail ? 1 : 0; + Skipped += test.Status == Status.Skip ? 1 : 0; + Others += test.Status != Status.Pass + && test.Status != Status.Fail + && test.Status != Status.Skip ? 1 : 0; + } + } + + public void Refresh() + { + Reset(); + + foreach (var t in Tests) + { + Compute(t); + } + } + + public void RemoveTest(Test test) + { + lock (_synclock) + { + IEnumerable enumerable = Tests.Where(x => x.Id != test.Id); + Tests = new ConcurrentQueue(enumerable); + } + } + + public void Reset() + { + Passed = Failed = Skipped = Others = 0; + } + + public int Count() + { + return Tests.Count; + } + } +} diff --git a/ExtentReports/Model/Context/SharedContext.cs b/ExtentReports/Model/Context/SharedContext.cs new file mode 100644 index 0000000..8a90713 --- /dev/null +++ b/ExtentReports/Model/Context/SharedContext.cs @@ -0,0 +1,10 @@ +using AventStack.ExtentReports.Model.Context.Manager; + +namespace AventStack.ExtentReports.Model.Context +{ + public class SharedContext where T : NamedAttribute + { + public NamedAttributeContextManager Ctx { get; set; } + public string View { get; set; } + } +} diff --git a/ExtentReports/Model/Convert/TestEntityParser.cs b/ExtentReports/Model/Convert/TestEntityParser.cs new file mode 100644 index 0000000..4b8d62b --- /dev/null +++ b/ExtentReports/Model/Convert/TestEntityParser.cs @@ -0,0 +1,120 @@ +using AventStack.ExtentReports.Gherkin; +using Newtonsoft.Json; +using System.Collections.Generic; +using System.IO; + +namespace AventStack.ExtentReports.Model.Convert +{ + internal class TestEntityParser + { + private readonly ExtentReports _extent; + + public TestEntityParser(ExtentReports extent) + { + _extent = extent; + } + + public void CreateEntities(string jsonFilePath) + { + if (!File.Exists(jsonFilePath)) + { + return; + } + + _extent.UsingNaturalConf = false; + + var text = File.ReadAllText(jsonFilePath); + var tests = JsonConvert.DeserializeObject>(text); + + foreach (var test in tests) + { + if (test.BddType == null) + { + CreateEntity(test, _extent.CreateTest(test.Name, test.Description)); + } + else + { + var keyword = new GherkinKeyword(test.BddType.Name); + var et = _extent.CreateTest(keyword, test.Name, test.Description); + CreateEntity(test, et); + } + } + } + + public void CreateEntity(Test test, ExtentTest extentTest) + { + extentTest.Test.StartTime = test.StartTime; + extentTest.Test.EndTime = test.EndTime; + + if (test.Logs != null) + { + foreach (var log in test.Logs) + { + ScreenCapture m = null; + + if (log.Media != null) + { + m = log.Media; + } + if (log.Details != null) + { + extentTest.Log(log.Status, log.Details, m); + } + if (log.ExceptionInfo != null) + { + extentTest.Log(log.Status, log.ExceptionInfo.Exception, m); + } + + } + } + + foreach (var x in test.Author) + { + extentTest.AssignAuthor(x.Name); + } + + foreach (var x in test.Category) + { + extentTest.AssignCategory(x.Name); + } + + foreach (var x in test.Device) + { + extentTest.AssignDevice(x.Name); + } + + foreach (var x in test.Media) + { + if (x.Base64 != null) + { + extentTest.AddScreenCaptureFromBase64String(x.Base64); + } + else + { + var path = x.ResolvedPath ?? x.Path; + extentTest.AddScreenCaptureFromPath(path); + } + } + + if (test.HasChildren) + { + foreach (var node in test.Children) + { + ExtentTest extentNode; + + if (test.BddType == null) + { + extentNode = extentTest.CreateNode(node.Name, node.Description); + } + else + { + var keyword = new GherkinKeyword(node.BddType.Name); + extentNode = extentTest.CreateNode(keyword, node.Name, node.Description); + } + + CreateEntity(node, extentNode); + } + } + } + } +} diff --git a/ExtentReports/Model/Device.cs b/ExtentReports/Model/Device.cs new file mode 100644 index 0000000..1b307aa --- /dev/null +++ b/ExtentReports/Model/Device.cs @@ -0,0 +1,7 @@ +namespace AventStack.ExtentReports.Model +{ + public class Device : NamedAttribute + { + public Device(string name) : base(name) { } + } +} diff --git a/extentreports-dotnet-core/Model/ExceptionInfo.cs b/ExtentReports/Model/ExceptionInfo.cs similarity index 60% rename from extentreports-dotnet-core/Model/ExceptionInfo.cs rename to ExtentReports/Model/ExceptionInfo.cs index 8e2e78d..e8d09d4 100644 --- a/extentreports-dotnet-core/Model/ExceptionInfo.cs +++ b/ExtentReports/Model/ExceptionInfo.cs @@ -2,11 +2,10 @@ namespace AventStack.ExtentReports.Model { - [Serializable] - public class ExceptionInfo : Attribute + public class ExceptionInfo: NamedAttribute { - public Exception Exception { get; private set; } - + public Exception Exception { get; set; } + public ExceptionInfo(Exception ex) : base(ex.GetType().FullName) { Exception = ex; diff --git a/ExtentReports/Model/ExtensionMethods/ClonedExtensions.cs b/ExtentReports/Model/ExtensionMethods/ClonedExtensions.cs new file mode 100644 index 0000000..87ce0c3 --- /dev/null +++ b/ExtentReports/Model/ExtensionMethods/ClonedExtensions.cs @@ -0,0 +1,23 @@ +using Newtonsoft.Json; + +namespace AventStack.ExtentReports.Model.ExtensionMethods +{ + public static class ClonedExtensions + { + public static T DeepClone(this T obj) + { + // Don't serialize a null object, simply return the default for that object + if (obj == null) + { + return default; + } + + // initialize inner objects individually + // for example in default constructor some list property initialized with some values, + // but in 'source' these items are cleaned - + // without ObjectCreationHandling.Replace default constructor values will be added to result + var deserializeSettings = new JsonSerializerSettings { ObjectCreationHandling = ObjectCreationHandling.Replace }; + return JsonConvert.DeserializeObject(JsonConvert.SerializeObject(obj), deserializeSettings); + } + } +} diff --git a/ExtentReports/Model/IMetaDataStorable.cs b/ExtentReports/Model/IMetaDataStorable.cs new file mode 100644 index 0000000..64dab97 --- /dev/null +++ b/ExtentReports/Model/IMetaDataStorable.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace AventStack.ExtentReports.Model +{ + public interface IMetaDataStorable + { + IDictionary Info { get; } + } +} \ No newline at end of file diff --git a/ExtentReports/Model/IRunResult.cs b/ExtentReports/Model/IRunResult.cs new file mode 100644 index 0000000..b5cde6d --- /dev/null +++ b/ExtentReports/Model/IRunResult.cs @@ -0,0 +1,7 @@ +namespace AventStack.ExtentReports.Model +{ + public interface IRunResult + { + Status Status { get; } + } +} diff --git a/ExtentReports/Model/Log.cs b/ExtentReports/Model/Log.cs new file mode 100644 index 0000000..af582d6 --- /dev/null +++ b/ExtentReports/Model/Log.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; + +namespace AventStack.ExtentReports.Model +{ + public class Log : IMetaDataStorable, IRunResult, IBaseEntity + { + public DateTime Timestamp { get; set; } = DateTime.Now; + public Status Status { get; set; } = Status.Pass; + public string Details { get; set; } + public int Seq { get; set; } = -1; + public ExceptionInfo ExceptionInfo { get; set; } + public ScreenCapture Media { get; set; } + public IDictionary Info { get; set; } = new Dictionary(); + + public bool HasMedia => Media != null; + + public bool HasException => ExceptionInfo != null; + + public void AddMedia(Media media) + { + if (media != null && ((media.Path != null || media.ResolvedPath != null) + || media is ScreenCapture capture && capture.Base64 != null)) + Media = (ScreenCapture)media; + } + + public Log(Status status = Status.Pass) + { + Status = status; + } + } +} diff --git a/ExtentReports/Model/Media.cs b/ExtentReports/Model/Media.cs new file mode 100644 index 0000000..6356323 --- /dev/null +++ b/ExtentReports/Model/Media.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Threading; + +namespace AventStack.ExtentReports.Model +{ + public class Media : IBaseEntity + { + private static int _cntr; + + public int Id = Interlocked.Increment(ref _cntr); + public string Path { get; set; } + public string Title { get; set; } + public string ResolvedPath { get; set; } + public IDictionary Info = new Dictionary(); + + public Media(string path = null, string title = null) + { + Path = path; + Title = title; + } + } +} diff --git a/ExtentReports/Model/NameValuePair.cs b/ExtentReports/Model/NameValuePair.cs new file mode 100644 index 0000000..846606b --- /dev/null +++ b/ExtentReports/Model/NameValuePair.cs @@ -0,0 +1,12 @@ +namespace AventStack.ExtentReports.Model +{ + public abstract class NameValuePair : NamedAttribute, IBaseEntity + { + public string Value { get; set; } + + public NameValuePair(string name, string value) : base(name) + { + Value = value; + } + } +} diff --git a/ExtentReports/Model/NamedAttribute.cs b/ExtentReports/Model/NamedAttribute.cs new file mode 100644 index 0000000..b028abb --- /dev/null +++ b/ExtentReports/Model/NamedAttribute.cs @@ -0,0 +1,23 @@ +namespace AventStack.ExtentReports.Model +{ + public abstract class NamedAttribute : IBaseEntity + { + protected NamedAttribute(string name) + { + Name = name; + } + + public string Name { get; set; } + + public override bool Equals(object obj) + { + var attr = obj as NamedAttribute; + return attr != null && attr.Name == Name; + } + + public override int GetHashCode() + { + return Name.GetHashCode(); + } + } +} diff --git a/ExtentReports/Model/Report.cs b/ExtentReports/Model/Report.cs new file mode 100644 index 0000000..7f6ac63 --- /dev/null +++ b/ExtentReports/Model/Report.cs @@ -0,0 +1,159 @@ +using System; +using System.Linq; +using System.Collections.Concurrent; +using System.Collections.Generic; +using AventStack.ExtentReports.Collections; +using AventStack.ExtentReports.Model.Context.Manager; + +namespace AventStack.ExtentReports.Model +{ + public class Report : IBaseEntity, IMetaDataStorable + { + public AnalysisStrategy AnalysisStrategy = AnalysisStrategy.Test; + public DateTime StartTime { get; set; } = DateTime.Now; + public DateTime EndTime { get; set; } = DateTime.Now; + public ReportStats Stats { get; } = new ReportStats(); + public IList Tests { get; private set; } = new SynchronizedList(); + public NamedAttributeContextManager AuthorCtx { get; } = new NamedAttributeContextManager(); + public NamedAttributeContextManager CategoryCtx { get; } = new NamedAttributeContextManager(); + public NamedAttributeContextManager DeviceCtx { get; } = new NamedAttributeContextManager(); + public NamedAttributeContextManager ExceptionInfoCtx { get; } = new NamedAttributeContextManager(); + public ConcurrentQueue Logs { get; } = new ConcurrentQueue(); + public List SystemEnvInfo { get; } = new List(); + public IDictionary Info { get; set; } = new Dictionary(); + + private readonly object _synclock = new object(); + + public void Refresh() + { + AuthorCtx.RefreshAll(); + CategoryCtx.RefreshAll(); + DeviceCtx.RefreshAll(); + ExceptionInfoCtx.RefreshAll(); + Stats.Update(Tests); + + lock (_synclock) + { + EndTime = DateTime.Now; + } + } + + public Status Status + { + get + { + if (Tests.Count == 0) + { + return Status.Pass; + } + + var allStatus = Tests.Select(x => x.Status).Distinct(); + var s = allStatus.Max(); + return s == Status.Skip ? Status.Pass : s; + } + } + + public bool IsBDD => Tests.Count != 0 && Tests.Any(x => x.IsBdd); + + public TimeSpan TimeTaken => EndTime.Subtract(StartTime); + + public bool HasAuthors => AuthorCtx.HasItems; + + public bool HasCategories => CategoryCtx.HasItems; + + public bool HasDevices => DeviceCtx.HasItems; + + public bool HasExceptions => ExceptionInfoCtx.HasItems; + + public bool HasTests => Tests.Count > 0; + + public void AddTest(Test test) + { + Tests.Add(test); + } + + public void RemoveTest(IList tests, Test test, bool deep = true) + { + var item = tests.SingleOrDefault(x => x.Id == test.Id); + + if (item == null && deep) + { + foreach (Test t in tests) + { + RemoveTest(t.Children, test); + } + } + + tests.Remove(test); + } + + public void RemoveTest(Test test) + { + RemoveTest(Tests, test, true); + } + + public void RemoveTest(int id) + { + var test = FindTest(id); + RemoveTest(test); + } + + public void ApplyOverrideConf() + { + var list = Tests.ToList(); + var min = list.Select(x => x.StartTime).Min(); + var max = list.Select(x => x.EndTime).Max(); + + lock (_synclock) + { + StartTime = min; + EndTime = max; + } + } + + public bool AnyTestHasStatus(Status status) + { + return Tests.Any(x => x.Status == status); + } + + public Test FindTest(IList list, string name) + { + var test = list.SingleOrDefault(x => x.Name.Equals(name)); + + if (test == null) + { + foreach (Test t in list) + { + return FindTest(t.Children, name); + } + } + + return test; + } + + public Test FindTest(string name) + { + return FindTest(Tests, name); + } + + public Test FindTest(IList list, int id) + { + var test = list.SingleOrDefault(x => x.Id.Equals(id)); + + if (test == null) + { + foreach (Test t in list) + { + return FindTest(t.Children, id); + } + } + + return test; + } + + public Test FindTest(int id) + { + return FindTest(Tests, id); + } + } +} diff --git a/ExtentReports/Model/ReportStats.cs b/ExtentReports/Model/ReportStats.cs new file mode 100644 index 0000000..eab4482 --- /dev/null +++ b/ExtentReports/Model/ReportStats.cs @@ -0,0 +1,86 @@ +using AventStack.ExtentReports.Util; +using AventStack.ExtentReports.Extensions; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; + +namespace AventStack.ExtentReports.Model +{ + public class ReportStats + { + public AnalysisStrategy AnalysisStrategy { get; set; } = AnalysisStrategy.Test; + public ConcurrentDictionary Parent = new ConcurrentDictionary(); + public ConcurrentDictionary Child = new ConcurrentDictionary(); + public ConcurrentDictionary Grandchild = new ConcurrentDictionary(); + public ConcurrentDictionary Log = new ConcurrentDictionary(); + public ConcurrentDictionary ParentPercentage = new ConcurrentDictionary(); + public ConcurrentDictionary ChildPercentage = new ConcurrentDictionary(); + public ConcurrentDictionary GrandchildPercentage = new ConcurrentDictionary(); + public ConcurrentDictionary LogPercentage = new ConcurrentDictionary(); + + private readonly static List _status = Enum.GetValues(typeof(Status)).Cast().ToList(); + + public void Update(IEnumerable tests) + { + Reset(); + + if (tests == null || tests.Count() == 0) + return; + + // Level 0 + Update(tests, ref Parent, ref ParentPercentage); + + // level 1, for BDD, this would also include Scenario and excludes ScenarioOutline + var children = tests.SelectMany(x => x.Children) + .Where(x => x.BddType == null || (x.BddType != null && !x.BddType.Name.ToUpper().Equals("SCENARIOOUTLINE"))); + var scenarios = tests.SelectMany(x => x.Children) + .SelectMany(x => x.Children) + .Where(x => x.BddType != null && x.BddType.Name.ToUpper().Equals("SCENARIO")); + children.Concat(scenarios); + Update(children, ref Child, ref ChildPercentage); + + // level 2, for BDD, this only includes Steps + var grandchildren = children.SelectMany(x => x.Children) + .Where(x => x.BddType == null || (x.BddType != null && !x.BddType.Name.ToUpper().Equals("SCENARIO"))); + Update(grandchildren, ref Grandchild, ref GrandchildPercentage); + + // events + var logs = tests.SelectMany(x => x.Logs); + logs = logs.Concat(children.SelectMany(x => x.Logs)); + logs = logs.Concat(grandchildren.SelectMany(x => x.Logs)); + Update(logs, ref Log, ref LogPercentage); + } + + private void Update(IEnumerable> list, ref ConcurrentDictionary countDict, ref ConcurrentDictionary percentDict) + { + Assert.NotNull(list, "Collection must not be null"); + + countDict.AddRange(_status.ToDictionary(x => x, x => 0)); + percentDict.AddRange(_status.ToDictionary(x => x, x => 0.0)); + + if (list.Count() > 0) + { + var count = list.Select(x => x.Status).GroupBy(x => x).ToDictionary(x => x.Key, x => x.Count()); + countDict.AddRange(count); + + var percent = countDict.ToDictionary(x => x.Key, x => (double)(x.Value / list.Count())); + percentDict.AddRange(percent); + } + } + + public void Reset() + { + var list = new List>(); + Update(list, ref Parent, ref ParentPercentage); + Update(list, ref Child, ref ChildPercentage); + Update(list, ref Grandchild, ref GrandchildPercentage); + Update(list, ref Log, ref LogPercentage); + } + + public int SumStat(IDictionary dict) + { + return dict.Values.Sum(); + } + } +} diff --git a/ExtentReports/Model/ScreenCapture.cs b/ExtentReports/Model/ScreenCapture.cs new file mode 100644 index 0000000..f91bb01 --- /dev/null +++ b/ExtentReports/Model/ScreenCapture.cs @@ -0,0 +1,17 @@ +namespace AventStack.ExtentReports.Model +{ + public class ScreenCapture : Media + { + public ScreenCapture(string path = null, string title = null) : base(path, title) { } + + public string Base64 { get; set; } + + public bool IsBase64 + { + get + { + return !string.IsNullOrEmpty(Base64); + } + } + } +} diff --git a/ExtentReports/Model/SystemEnvInfo.cs b/ExtentReports/Model/SystemEnvInfo.cs new file mode 100644 index 0000000..2824cf5 --- /dev/null +++ b/ExtentReports/Model/SystemEnvInfo.cs @@ -0,0 +1,9 @@ +namespace AventStack.ExtentReports.Model +{ + public class SystemEnvInfo : NameValuePair, IBaseEntity + { + public SystemEnvInfo(string name, string value) : base(name, value) + { + } + } +} diff --git a/ExtentReports/Model/Test.cs b/ExtentReports/Model/Test.cs new file mode 100644 index 0000000..eafebfe --- /dev/null +++ b/ExtentReports/Model/Test.cs @@ -0,0 +1,259 @@ +using AventStack.ExtentReports.Collections; +using AventStack.ExtentReports.Extensions; +using AventStack.ExtentReports.Gherkin; +using AventStack.ExtentReports.Gherkin.Model; +using AventStack.ExtentReports.Util; +using Newtonsoft.Json; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; + +namespace AventStack.ExtentReports.Model +{ + public class Test : IMetaDataStorable, IRunResult, IBaseEntity + { + private const char Separator = '.'; + + private readonly StatusDeterminator _determinator = new StatusDeterminator(); + private static int _cntr; + private readonly object _synclock = new object(); + + public Test() { } + + public Test(string name, string description = null, GherkinKeyword bddType = null) + { + Name = name; + Description = description; + BddType = bddType; + } + + public int Id = Interlocked.Increment(ref _cntr); + public bool UseNaturalConf { get; set; } = true; + public DateTime StartTime { get; set; } = DateTime.Now; + public DateTime EndTime { get; set; } = DateTime.Now; + public Status Status { get; set; } = Status.Pass; + public int Level { get; set; } = 0; + public bool Leaf { get; set; } = true; + public string Name { get; set; } + public string Description { get; set; } + public GherkinKeyword BddType { get; set; } + public IList Children { get; set; } = new SynchronizedList(); + public ConcurrentQueue Logs { get; set; } = new ConcurrentQueue(); + public ConcurrentQueue GeneratedLog { get; set; } = new ConcurrentQueue(); + public List Media { get; set; } = new List(); + public List ExceptionInfo { get; set; } = new List(); + public ISet Author { get; set; } = new HashSet(); + public ISet Category { get; set; } = new HashSet(); + public ISet Device { get; set; } = new HashSet(); + public IDictionary Info { get; set; } = new Dictionary(); + + [JsonIgnore] + public Test Parent { get; set; } + + public string FullName + { + get + { + var test = this; + var sb = new StringBuilder(test.Name); + while (test.Parent != null) + { + test = test.Parent; + if (!test.IsBdd || test.BddType.GetType() == typeof(ScenarioOutline)) + { + sb.Insert(0, test.Name + Separator); + } + } + return sb.ToString(); + } + } + + [JsonIgnore] + public Test Ancestor + { + get + { + var test = this; + while (test.Parent != null) + { + test = test.Parent; + } + + return test; + } + } + + public double TimeTaken => EndTime.Subtract(StartTime).TotalMilliseconds; + + public bool IsBdd => BddType != null; + + public void AddChild(Test test) + { + Assert.NotNull(test, "The assigned node must not be null"); + + test.Level = Level + 1; + test.Parent = this; + test.Leaf = true; + Leaf = false; + if (!test.IsBdd || test.BddType.GetType() == typeof(Scenario)) + { + test.Author.UnionWith(Author); + test.Category.UnionWith(Category); + test.Device.UnionWith(Device); + } + End(test.Status); + Children.Add(test); + } + + private void End(Status s) + { + Status = Status.Max(s); + + if (UseNaturalConf) + { + EndTime = DateTime.Now; + } + + Propagate(); + } + + private void Propagate() + { + if (Parent != null) + { + Parent.End(Status); + } + } + + public void AddLog(Log log) + { + if (log != null) + { + Logs.Enqueue(log); + AddLogCommon(log); + } + } + + public void AddGeneratedLog(Log log) + { + if (log != null) + { + GeneratedLog.Enqueue(log); + AddLogCommon(log); + } + } + + private void AddLogCommon(Log log) + { + log.Seq = Logs.Count + GeneratedLog.Count; + End(log.Status); + //UpdateResult(); + } + + public void AddMedia(ScreenCapture m) + { + if (m != null && (m.Path != null || m.ResolvedPath != null || ((ScreenCapture)m).Base64 != null)) + { + Media.Add(m); + } + } + + public bool HasAnyLog => !Logs.IsEmpty || !GeneratedLog.IsEmpty; + + public bool HasGeneratedLog => !GeneratedLog.IsEmpty; + + public bool HasLog => !Logs.IsEmpty; + + public bool HasChildren => Children.Count != 0; + + public bool HasAttributes => HasCategory || HasDevice || HasAuthor; + + public bool HasAuthor => Author.Count > 0; + + public bool HasCategory => Category.Count > 0; + + public bool HasDevice => Device.Count > 0; + + public bool HasScreenCapture => Media.Count > 0; + + public bool HasScreenCaptureDeep => HasScreenCapture || HasScreenCaptureDeepImpl(this); + + private bool HasScreenCaptureDeepImpl(Test test) + { + if (test.HasChildren) + { + var nodes = test.Children.ToList(); + + foreach (Test node in nodes) + { + if (node.HasScreenCapture) + { + return true; + } + + return HasScreenCaptureDeepImpl(node); + } + } + + return false; + } + + public void UpdateResult() + { + lock (_synclock) + { + _determinator.ComputeStatus(this); + } + } + + private class StatusDeterminator + { + public void ComputeStatus(Test test) + { + var list = FindLeafNodes(test); + ComputeStatus(list); + } + + private void ComputeStatus(List list) + { + list.ForEach(ComputeStatusSingle); + } + + private void ComputeStatusSingle(Test test) + { + if (test.Parent != null) + { + test.Parent.Status = test.Status.Max(test.Parent.Status); + ComputeStatusSingle(test.Parent); + } + } + + private List FindLeafNodes(Test test) + { + var list = new List(); + if (test.Leaf) + { + list.Add(test); + } + else + { + foreach (var t in test.Children) + { + if (t.Leaf) + { + list.Add(t); + } + else + { + list.AddRange(FindLeafNodes(t)); + } + } + } + return list; + } + } + } +} diff --git a/ExtentReports/Reporter/AbstractFileReporter.cs b/ExtentReports/Reporter/AbstractFileReporter.cs new file mode 100644 index 0000000..fa56d00 --- /dev/null +++ b/ExtentReports/Reporter/AbstractFileReporter.cs @@ -0,0 +1,22 @@ +using System.IO; + +namespace AventStack.ExtentReports.Reporter +{ + public abstract class AbstractFileReporter : AbstractFilterableReporter + { + internal string SavePath { get; set; } = "Index.html"; + internal string FolderSavePath { get; set; } + + public AbstractFileReporter(string filePath) + { + SavePath = filePath; + FolderSavePath = Path.GetDirectoryName(filePath); + FolderSavePath = string.IsNullOrEmpty(FolderSavePath) ? "." + Path.DirectorySeparatorChar : FolderSavePath; + + if (!Directory.Exists(FolderSavePath)) + { + Directory.CreateDirectory(FolderSavePath); + } + } + } +} diff --git a/ExtentReports/Reporter/AbstractFilterableReporter.cs b/ExtentReports/Reporter/AbstractFilterableReporter.cs new file mode 100644 index 0000000..315d1ce --- /dev/null +++ b/ExtentReports/Reporter/AbstractFilterableReporter.cs @@ -0,0 +1,64 @@ +using AventStack.ExtentReports.Extensions; +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Model.ExtensionMethods; +using AventStack.ExtentReports.Reporter.Filter; +using AventStack.ExtentReports.Util; +using System.Collections.Generic; +using System.Linq; + +namespace AventStack.ExtentReports.Reporter +{ + public abstract class AbstractFilterableReporter : AbstractReporter, IStatusFilterable + { + public Report FilterReport(Report report, HashSet set) + { + Assert.NotNull(report, "Report must not be empty"); + + if (set != null) + { + var cloned = report.DeepClone(); + cloned.Tests.Clear(); + + var tests = report.Tests.Where(x => set.Contains(x.Status)); + + foreach (Test test in tests) + { + cloned.AddTest(test); + } + + RefreshContext(cloned); + + return cloned; + } + + return report; + } + + private void RefreshContext(Report cloned) + { + var list = cloned.Tests.ToList(); + + foreach (var test in list) + { + foreach (var x in test.Author) + { + cloned.AuthorCtx.AddContext(x, test); + } + foreach (var x in test.Category) + { + cloned.CategoryCtx.AddContext(x, test); + } + foreach (var x in test.Device) + { + cloned.DeviceCtx.AddContext(x, test); + } + foreach (var x in test.ExceptionInfo) + { + cloned.ExceptionInfoCtx.AddContext(x, test); + } + } + + cloned.Refresh(); + } + } +} diff --git a/ExtentReports/Reporter/AbstractReporter.cs b/ExtentReports/Reporter/AbstractReporter.cs new file mode 100644 index 0000000..3066d2b --- /dev/null +++ b/ExtentReports/Reporter/AbstractReporter.cs @@ -0,0 +1,7 @@ +namespace AventStack.ExtentReports.Reporter +{ + public class AbstractReporter : IExtentReporter + { + + } +} diff --git a/ExtentReports/Reporter/Config/AbstractConfiguration.cs b/ExtentReports/Reporter/Config/AbstractConfiguration.cs new file mode 100644 index 0000000..a60ec06 --- /dev/null +++ b/ExtentReports/Reporter/Config/AbstractConfiguration.cs @@ -0,0 +1,13 @@ +using AventStack.ExtentReports.Config; +using System.Xml.Serialization; + +namespace AventStack.ExtentReports.Reporter.Config +{ + public class AbstractConfiguration + { + protected ConfigStore Store = new ConfigStore(); + + [XmlElement("reportName")] + public string ReportName = ""; + } +} diff --git a/ExtentReports/Reporter/Config/ExtentSparkReporterConfig.cs b/ExtentReports/Reporter/Config/ExtentSparkReporterConfig.cs new file mode 100644 index 0000000..8eee89a --- /dev/null +++ b/ExtentReports/Reporter/Config/ExtentSparkReporterConfig.cs @@ -0,0 +1,59 @@ +using Newtonsoft.Json; +using System.IO; +using System.Threading.Tasks; +using System.Xml.Serialization; + +namespace AventStack.ExtentReports.Reporter.Config +{ + [XmlRoot("configuration")] + public class ExtentSparkReporterConfig : InteractiveReporterConfig + { + private const string OfflinePackage = "extent"; + private const string Package = "AventStack.ExtentReports.Views.Spark.Offline"; + private bool _offline = false; + + internal ExtentSparkReporter Reporter { get; set; } + + [XmlElement("offlineMode")] + public bool OfflineMode + { + get + { + return _offline; + } + set + { + _offline = value; + + if (value) + { + Task.Run(() => SaveOfflineResources()); + } + } + } + + public ExtentSparkReporterConfig() { } + + [JsonConstructor] + public ExtentSparkReporterConfig(ExtentSparkReporter reporter) + { + Reporter = reporter; + } + + internal void SaveOfflineResources() + { + if (Reporter == null) + { + return; + } + + string folderPath = Reporter.FolderSavePath; + folderPath += Path.DirectorySeparatorChar + OfflinePackage + Path.DirectorySeparatorChar; + Directory.CreateDirectory(folderPath); + + SaveResourceToDisk(Package + ".spark-style.css", folderPath + "spark-style.css"); + SaveResourceToDisk(Package + ".spark-script.js", folderPath + "spark-script.js"); + SaveCommonsResources(folderPath); + } + } +} diff --git a/ExtentReports/Reporter/Config/FileReporterConfig.cs b/ExtentReports/Reporter/Config/FileReporterConfig.cs new file mode 100644 index 0000000..506c66e --- /dev/null +++ b/ExtentReports/Reporter/Config/FileReporterConfig.cs @@ -0,0 +1,13 @@ +using System.Xml.Serialization; + +namespace AventStack.ExtentReports.Reporter.Config +{ + public class FileReporterConfig : AbstractConfiguration + { + [XmlElement("encoding")] + public string Encoding = "utf-8"; + + [XmlElement("documentTitle")] + public string DocumentTitle = ""; + } +} diff --git a/ExtentReports/Reporter/Config/IReporterConfigurable.cs b/ExtentReports/Reporter/Config/IReporterConfigurable.cs new file mode 100644 index 0000000..33a87dc --- /dev/null +++ b/ExtentReports/Reporter/Config/IReporterConfigurable.cs @@ -0,0 +1,23 @@ +namespace AventStack.ExtentReports.Reporter.Config +{ + public interface IReporterConfigurable + { + /// + /// Loads reporter configuration from JSON + /// + /// + void LoadJSONConfig(string filePath); + + /// + /// Loads XML configuration + /// + /// + void LoadXMLConfig(string filePath); + + /// + /// Loads XML configuration (for backward compatibility) + /// + /// + void LoadConfig(string filePath); + } +} diff --git a/ExtentReports/Reporter/Config/InteractiveReporterConfig.cs b/ExtentReports/Reporter/Config/InteractiveReporterConfig.cs new file mode 100644 index 0000000..f121d06 --- /dev/null +++ b/ExtentReports/Reporter/Config/InteractiveReporterConfig.cs @@ -0,0 +1,63 @@ +using System.IO; +using System.Xml.Serialization; + +namespace AventStack.ExtentReports.Reporter.Config +{ + public class InteractiveReporterConfig : FileReporterConfig + { + private readonly string OfflinePackage = "AventStack.ExtentReports.Views.Commons.Offline"; + + [XmlElement("protocol")] + public Protocol Protocol = Protocol.HTTP; + + [XmlElement("theme")] + public Theme Theme = Theme.Standard; + + [XmlElement("timelineEnabled")] + public bool TimelineEnabled = true; + + [XmlElement("styles")] + public string CSS = ""; + + [XmlElement("scripts")] + public string JS = ""; + + protected void SaveResourceToDisk(string resourceStreamPath, string savePath) + { + var stream = this.GetType().Assembly.GetManifestResourceStream(resourceStreamPath); + var text = new StreamReader(stream).ReadToEnd(); + File.WriteAllText(savePath, text); + } + + protected void SaveBinaryResourceToDisk(string resourceStreamPath, string savePath) + { + using (var sourceFileStream = this.GetType().Assembly.GetManifestResourceStream(resourceStreamPath)) + { + using (var destinationFileStream = new FileStream(savePath, FileMode.OpenOrCreate)) + { + while (sourceFileStream.Position < sourceFileStream.Length) + { + destinationFileStream.WriteByte((byte)sourceFileStream.ReadByte()); + } + } + } + } + + protected void SaveCommonsResources(string folderPath, bool saveFontAwesomeFonts = true) + { + SaveResourceToDisk(OfflinePackage + ".jsontree.js", folderPath + "jsontree.js"); + SaveBinaryResourceToDisk(OfflinePackage + ".logo.png", folderPath + "logo.png"); + + if (saveFontAwesomeFonts) + { + SaveResourceToDisk(OfflinePackage + ".font-awesome.min.css", folderPath + "font-awesome.min.css"); + SaveBinaryResourceToDisk(OfflinePackage + ".FontAwesome.otf", folderPath + "FontAwesome.otf"); + SaveBinaryResourceToDisk(OfflinePackage + ".fontawesome-webfont.eot", folderPath + "fontawesome-webfont.eot"); + SaveBinaryResourceToDisk(OfflinePackage + ".fontawesome-webfont.svg", folderPath + "fontawesome-webfont.svg"); + SaveBinaryResourceToDisk(OfflinePackage + ".fontawesome-webfont.ttf", folderPath + "fontawesome-webfont.ttf"); + SaveBinaryResourceToDisk(OfflinePackage + ".fontawesome-webfont.woff", folderPath + "fontawesome-webfont.woff"); + SaveBinaryResourceToDisk(OfflinePackage + ".fontawesome-webfont.woff2", folderPath + "fontawesome-webfont.woff2"); + } + } + } +} diff --git a/ExtentReports/Reporter/Config/Protocol.cs b/ExtentReports/Reporter/Config/Protocol.cs new file mode 100644 index 0000000..5f2a175 --- /dev/null +++ b/ExtentReports/Reporter/Config/Protocol.cs @@ -0,0 +1,7 @@ +namespace AventStack.ExtentReports.Reporter.Config +{ + public enum Protocol + { + HTTP, HTTPS + } +} diff --git a/ExtentReports/Reporter/Config/Theme.cs b/ExtentReports/Reporter/Config/Theme.cs new file mode 100644 index 0000000..162e558 --- /dev/null +++ b/ExtentReports/Reporter/Config/Theme.cs @@ -0,0 +1,7 @@ +namespace AventStack.ExtentReports.Reporter.Config +{ + public enum Theme + { + Standard, Dark + } +} diff --git a/ExtentReports/Reporter/ExtentSparkReporter.cs b/ExtentReports/Reporter/ExtentSparkReporter.cs new file mode 100644 index 0000000..cc6cd57 --- /dev/null +++ b/ExtentReports/Reporter/ExtentSparkReporter.cs @@ -0,0 +1,113 @@ +using AventStack.ExtentReports.Config; +using AventStack.ExtentReports.Listener.Entity; +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Reporter.Config; +using AventStack.ExtentReports.Reporter.Filter; +using AventStack.ExtentReports.Reporter.Templating; +using AventStack.ExtentReports.Views.Spark; +using RazorEngine.Templating; +using System; +using System.IO; + +namespace AventStack.ExtentReports.Reporter +{ + public class ExtentSparkReporter : AbstractFileReporter, IReporterFilterable, IReporterConfigurable, IObserver + { + private EntityFilters _filter; + + public ExtentSparkReporterConfig Config; + public Report Report; + + public EntityFilters Filter + { + get + { + if (_filter == null) + { + _filter = new EntityFilters(this); + } + + return _filter; + } + } + + public ExtentSparkReporter(string filePath) : base(filePath) + { + AddTemplates(); + Config = new ExtentSparkReporterConfig(this); + } + + public void LoadJSONConfig(string filePath) + { + var loader = new JsonConfigLoader(); + loader.LoadJSONConfig(ref Config, filePath); + ApplyConfig(); + } + + private void ApplyConfig() + { + if (Config.OfflineMode) + { + Config.Reporter = this; + Config.SaveOfflineResources(); + } + } + + public void LoadXMLConfig(string filePath) + { + var loader = new XmlConfigLoader(); + loader.LoadXMLConfig(ref Config, filePath); + ApplyConfig(); + } + + public void LoadConfig(string filePath) + { + LoadXMLConfig(filePath); + } + + public void OnCompleted() { } + + public void OnError(Exception error) { } + + public void OnNext(ReportEntity value) + { + Report = _filter == null ? value.Report : FilterReport(value.Report, _filter.StatusFilter.Status); + + if (Report.HasTests) + { + var source = RazorEngineManager.Instance.Razor.RunCompile("SparkIndexSPA", typeof(ExtentSparkReporter), this); + File.WriteAllText(Path.Combine(FolderSavePath, SavePath), source); + } + } + + private void AddTemplates() + { + string[] templates = new string[] + { + "Partials.Attributes", + "Partials.AttributesView", + "Partials.Head", + "Partials.Log", + "Partials.Navbar", + "Partials.RecurseNodes", + "Partials.Scripts", + "Partials.Sidenav", + "Partials.SparkBDD", + "Partials.SparkStandard", + "Partials.SparkStepDetails", + "SparkIndexSPA", + "Partials.SparkMedia", + "Partials.SparkTestSPA", + "Partials.SparkAuthorSPA", + "Partials.SparkDeviceSPA", + "Partials.SparkTagSPA", + "Partials.SparkExceptionSPA", + "Partials.SparkDashboardSPA", + "Partials.SparkLogsSPA", + "Partials.StepDetails" + }; + + TemplateLoadService.LoadTemplate(templates); + } + } +} diff --git a/ExtentReports/Reporter/Filter/ContextFilter.cs b/ExtentReports/Reporter/Filter/ContextFilter.cs new file mode 100644 index 0000000..33f94f9 --- /dev/null +++ b/ExtentReports/Reporter/Filter/ContextFilter.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; + +namespace AventStack.ExtentReports.Reporter.Filter +{ + public class ContextFilter + { + private static readonly ContextFilter Filter = new ContextFilter(); + + public HashSet Status { get; set; } + public HashSet Author { get; set; } + public HashSet Category { get; set; } + public HashSet Device { get; set; } + + public static ContextFilterBuilder Builder => new ContextFilterBuilder(Filter); + + public class ContextFilterBuilder + { + private readonly ContextFilter _filter; + + public ContextFilterBuilder(ContextFilter filter) + { + _filter = filter; + } + + public ContextFilterBuilder Status(Status[] status) + { + foreach (Status s in status) + { + _filter.Status.Add(s); + } + + return this; + } + + public ContextFilterBuilder Author(string[] author) + { + foreach (string s in author) + { + _filter.Author.Add(s); + } + + return this; + } + + public ContextFilterBuilder Category(string[] category) + { + foreach (string s in category) + { + _filter.Category.Add(s); + } + + return this; + } + + public ContextFilterBuilder Device(string[] device) + { + foreach (string s in device) + { + _filter.Device.Add(s); + } + + return this; + } + + public ContextFilter Build() + { + return _filter; + } + } + } +} diff --git a/ExtentReports/Reporter/Filter/EntityFilters.cs b/ExtentReports/Reporter/Filter/EntityFilters.cs new file mode 100644 index 0000000..fb5c1c2 --- /dev/null +++ b/ExtentReports/Reporter/Filter/EntityFilters.cs @@ -0,0 +1,19 @@ +namespace AventStack.ExtentReports.Reporter.Filter +{ + public class EntityFilters where T : AbstractReporter + { + public StatusFilter StatusFilter; + private readonly T _reporter; + + public EntityFilters(T reporter) + { + _reporter = reporter; + StatusFilter = new StatusFilter(this); + } + + public T Apply() + { + return _reporter; + } + } +} diff --git a/ExtentReports/Reporter/Filter/IReporterFilterable.cs b/ExtentReports/Reporter/Filter/IReporterFilterable.cs new file mode 100644 index 0000000..e757245 --- /dev/null +++ b/ExtentReports/Reporter/Filter/IReporterFilterable.cs @@ -0,0 +1,7 @@ +namespace AventStack.ExtentReports.Reporter.Filter +{ + public interface IReporterFilterable where T : AbstractReporter + { + EntityFilters Filter { get; } + } +} diff --git a/ExtentReports/Reporter/Filter/IStatusFilterable.cs b/ExtentReports/Reporter/Filter/IStatusFilterable.cs new file mode 100644 index 0000000..1fd16db --- /dev/null +++ b/ExtentReports/Reporter/Filter/IStatusFilterable.cs @@ -0,0 +1,10 @@ +using AventStack.ExtentReports.Model; +using System.Collections.Generic; + +namespace AventStack.ExtentReports.Reporter.Filter +{ + public interface IStatusFilterable + { + Report FilterReport(Report report, HashSet set); + } +} diff --git a/ExtentReports/Reporter/Filter/StatusFilter.cs b/ExtentReports/Reporter/Filter/StatusFilter.cs new file mode 100644 index 0000000..edee5ae --- /dev/null +++ b/ExtentReports/Reporter/Filter/StatusFilter.cs @@ -0,0 +1,33 @@ +using System.Collections.Generic; +using System.Linq; + +namespace AventStack.ExtentReports.Reporter.Filter +{ + public class StatusFilter where T : AbstractReporter + { + private readonly EntityFilters _configurer; + + public HashSet Status { get; private set; } + + public StatusFilter(EntityFilters configurer) + { + _configurer = configurer; + } + + public EntityFilters As(HashSet status) + { + Status = status; + return _configurer; + } + + public EntityFilters As(List status) + { + return As(new HashSet(status)); + } + + public EntityFilters As(Status[] status) + { + return As(status.ToList()); + } + } +} \ No newline at end of file diff --git a/ExtentReports/Reporter/Formatter/ExtentJsonFormatter.cs b/ExtentReports/Reporter/Formatter/ExtentJsonFormatter.cs new file mode 100644 index 0000000..f9fdc1b --- /dev/null +++ b/ExtentReports/Reporter/Formatter/ExtentJsonFormatter.cs @@ -0,0 +1,30 @@ +using AventStack.ExtentReports.Listener.Entity; +using Newtonsoft.Json; +using System; +using System.IO; + +namespace AventStack.ExtentReports.Reporter +{ + public class ExtentJsonFormatter : AbstractFileReporter, IObserver + { + public ExtentJsonFormatter(string filePath) : base(filePath) + { + } + + public void OnCompleted() + { + + } + + public void OnError(Exception error) + { + + } + + public void OnNext(ReportEntity value) + { + var json = JsonConvert.SerializeObject(value.Report.Tests, Formatting.None); + File.WriteAllText(SavePath, json); + } + } +} diff --git a/ExtentReports/Reporter/IExtentReporter.cs b/ExtentReports/Reporter/IExtentReporter.cs new file mode 100644 index 0000000..7bfb6aa --- /dev/null +++ b/ExtentReports/Reporter/IExtentReporter.cs @@ -0,0 +1,6 @@ +namespace AventStack.ExtentReports.Reporter +{ + public interface IExtentReporter + { + } +} diff --git a/extentreports-dotnet-core/Reporter/TemplateEngine/RazorEngineManager.cs b/ExtentReports/Reporter/Templating/RazorEngineManager.cs similarity index 78% rename from extentreports-dotnet-core/Reporter/TemplateEngine/RazorEngineManager.cs rename to ExtentReports/Reporter/Templating/RazorEngineManager.cs index 2846c83..8b8f219 100644 --- a/extentreports-dotnet-core/Reporter/TemplateEngine/RazorEngineManager.cs +++ b/ExtentReports/Reporter/Templating/RazorEngineManager.cs @@ -2,10 +2,9 @@ using RazorEngine.Configuration; using RazorEngine.Templating; using RazorEngine.Text; - using System; -namespace AventStack.ExtentReports.Reporter.TemplateEngine +namespace AventStack.ExtentReports.Reporter.Templating { internal sealed class RazorEngineManager { @@ -24,20 +23,20 @@ internal void InitializeRazor() if (_initialized) return; - TemplateServiceConfiguration templateConfig = new TemplateServiceConfiguration + var templateConfig = new TemplateServiceConfiguration { DisableTempFileLocking = true, EncodedStringFactory = new RawStringFactory(), CachingProvider = new DefaultCachingProvider(x => { }) }; + var service = RazorEngineService.Create(templateConfig); Engine.Razor = service; _initialized = true; } - private static readonly Lazy lazy = - new Lazy(() => new RazorEngineManager()); + private static readonly Lazy lazy = new Lazy(() => new RazorEngineManager()); public static RazorEngineManager Instance { get { return lazy.Value; } } diff --git a/extentreports-dotnet-core/Reporter/TemplateEngine/TemplateLoadService.cs b/ExtentReports/Reporter/Templating/TemplateLoadService.cs similarity index 95% rename from extentreports-dotnet-core/Reporter/TemplateEngine/TemplateLoadService.cs rename to ExtentReports/Reporter/Templating/TemplateLoadService.cs index 5379818..c78f910 100644 --- a/extentreports-dotnet-core/Reporter/TemplateEngine/TemplateLoadService.cs +++ b/ExtentReports/Reporter/Templating/TemplateLoadService.cs @@ -1,10 +1,8 @@ using AventStack.ExtentReports.Views; - using RazorEngine.Templating; - using System.IO; -namespace AventStack.ExtentReports.Reporter.TemplateEngine +namespace AventStack.ExtentReports.Reporter.Templating { internal static class TemplateLoadService { diff --git a/ExtentReports/Util/Assert.cs b/ExtentReports/Util/Assert.cs new file mode 100644 index 0000000..5a1ce99 --- /dev/null +++ b/ExtentReports/Util/Assert.cs @@ -0,0 +1,23 @@ +using System; + +namespace AventStack.ExtentReports.Util +{ + internal static class Assert + { + public static void NotNull(Object o, string message) + { + if (o == null) + { + throw new ArgumentNullException(message); + } + } + + public static void NotEmpty(string s, string message) + { + if (s == null || s.Length == 0) + { + throw new ArgumentException(message); + } + } + } +} diff --git a/extentreports-dotnet-core/Views/Commons/CommonsAttributes.cshtml b/ExtentReports/Views/Commons/CommonsAttributes.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsAttributes.cshtml rename to ExtentReports/Views/Commons/CommonsAttributes.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/CommonsDashboard.cshtml b/ExtentReports/Views/Commons/CommonsDashboard.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsDashboard.cshtml rename to ExtentReports/Views/Commons/CommonsDashboard.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/CommonsException.cshtml b/ExtentReports/Views/Commons/CommonsException.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsException.cshtml rename to ExtentReports/Views/Commons/CommonsException.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/CommonsHead.cshtml b/ExtentReports/Views/Commons/CommonsHead.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsHead.cshtml rename to ExtentReports/Views/Commons/CommonsHead.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/CommonsInjectCss.cshtml b/ExtentReports/Views/Commons/CommonsInjectCss.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsInjectCss.cshtml rename to ExtentReports/Views/Commons/CommonsInjectCss.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/CommonsInjectJs.cshtml b/ExtentReports/Views/Commons/CommonsInjectJs.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsInjectJs.cshtml rename to ExtentReports/Views/Commons/CommonsInjectJs.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/CommonsMedia.cshtml b/ExtentReports/Views/Commons/CommonsMedia.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsMedia.cshtml rename to ExtentReports/Views/Commons/CommonsMedia.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/CommonsNav.cshtml b/ExtentReports/Views/Commons/CommonsNav.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsNav.cshtml rename to ExtentReports/Views/Commons/CommonsNav.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/CommonsNavRight.cshtml b/ExtentReports/Views/Commons/CommonsNavRight.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsNavRight.cshtml rename to ExtentReports/Views/Commons/CommonsNavRight.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/CommonsRow.cshtml b/ExtentReports/Views/Commons/CommonsRow.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsRow.cshtml rename to ExtentReports/Views/Commons/CommonsRow.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/CommonsTag.cshtml b/ExtentReports/Views/Commons/CommonsTag.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Commons/CommonsTag.cshtml rename to ExtentReports/Views/Commons/CommonsTag.cshtml diff --git a/extentreports-dotnet-core/Views/Commons/ICommonsMarker.cs b/ExtentReports/Views/Commons/ICommonsMarker.cs similarity index 100% rename from extentreports-dotnet-core/Views/Commons/ICommonsMarker.cs rename to ExtentReports/Views/Commons/ICommonsMarker.cs diff --git a/ExtentReports/Views/Commons/Offline/FontAwesome.otf b/ExtentReports/Views/Commons/Offline/FontAwesome.otf new file mode 100644 index 0000000..401ec0f Binary files /dev/null and b/ExtentReports/Views/Commons/Offline/FontAwesome.otf differ diff --git a/ExtentReports/Views/Commons/Offline/font-awesome.min.css b/ExtentReports/Views/Commons/Offline/font-awesome.min.css new file mode 100644 index 0000000..4b2d4cb --- /dev/null +++ b/ExtentReports/Views/Commons/Offline/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('https://extentreports.s3.us-east-2.amazonaws.com/dist/v5/avent/fontawesome-webfont.eot?v=4.7.0');src:url('https://extentreports.s3.us-east-2.amazonaws.com/dist/v5/avent/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('https://extentreports.s3.us-east-2.amazonaws.com/dist/v5/avent/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('https://extentreports.s3.us-east-2.amazonaws.com/dist/v5/avent/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('https://extentreports.s3.us-east-2.amazonaws.com/dist/v5/avent/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('https://extentreports.s3.us-east-2.amazonaws.com/dist/v5/avent/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/ExtentReports/Views/Commons/Offline/fontawesome-webfont.eot b/ExtentReports/Views/Commons/Offline/fontawesome-webfont.eot new file mode 100644 index 0000000..e9f60ca Binary files /dev/null and b/ExtentReports/Views/Commons/Offline/fontawesome-webfont.eot differ diff --git a/ExtentReports/Views/Commons/Offline/fontawesome-webfont.svg b/ExtentReports/Views/Commons/Offline/fontawesome-webfont.svg new file mode 100644 index 0000000..855c845 --- /dev/null +++ b/ExtentReports/Views/Commons/Offline/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExtentReports/Views/Commons/Offline/fontawesome-webfont.ttf b/ExtentReports/Views/Commons/Offline/fontawesome-webfont.ttf new file mode 100644 index 0000000..35acda2 Binary files /dev/null and b/ExtentReports/Views/Commons/Offline/fontawesome-webfont.ttf differ diff --git a/ExtentReports/Views/Commons/Offline/fontawesome-webfont.woff b/ExtentReports/Views/Commons/Offline/fontawesome-webfont.woff new file mode 100644 index 0000000..400014a Binary files /dev/null and b/ExtentReports/Views/Commons/Offline/fontawesome-webfont.woff differ diff --git a/ExtentReports/Views/Commons/Offline/fontawesome-webfont.woff2 b/ExtentReports/Views/Commons/Offline/fontawesome-webfont.woff2 new file mode 100644 index 0000000..4d13fc6 Binary files /dev/null and b/ExtentReports/Views/Commons/Offline/fontawesome-webfont.woff2 differ diff --git a/ExtentReports/Views/Commons/Offline/jsontree.js b/ExtentReports/Views/Commons/Offline/jsontree.js new file mode 100644 index 0000000..a539d1b --- /dev/null +++ b/ExtentReports/Views/Commons/Offline/jsontree.js @@ -0,0 +1,2 @@ +/*! json-tree - v0.2.2 - 2017-09-25, MIT LICENSE */ +var JSONTree=function(){var n={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/"},t=0,r=0;this.create=function(n,t){return r+=1,N(u(n,0,!1),{class:"jstValue"})};var e=function(t){return t.replace(/[&<>'"]/g,function(t){return n[t]})},s=function(){return r+"_"+t++},u=function(n,t,r){if(null===n)return f(r?t:0);switch(typeof n){case"boolean":return l(n,r?t:0);case"number":return i(n,r?t:0);case"string":return o(n,r?t:0);default:return n instanceof Array?a(n,t,r):c(n,t,r)}},c=function(n,t,r){var e=s(),u=Object.keys(n).map(function(r){return j(r,n[r],t+1,!0)}).join(m()),c=[g("{",r?t:0,e),N(u,{id:e}),p("}",t)].join("\n");return N(c,{})},a=function(n,t,r){var e=s(),c=n.map(function(n){return u(n,t+1,!0)}).join(m());return[g("[",r?t:0,e),N(c,{id:e}),p("]",t)].join("\n")},o=function(n,t){var r=e(JSON.stringify(n));return N(v(r,t),{class:"jstStr"})},i=function(n,t){return N(v(n,t),{class:"jstNum"})},l=function(n,t){return N(v(n,t),{class:"jstBool"})},f=function(n){return N(v("null",n),{class:"jstNull"})},j=function(n,t,r){var s=v(e(JSON.stringify(n))+": ",r),c=N(u(t,r,!1),{});return N(s+c,{class:"jstProperty"})},m=function(){return N(",\n",{class:"jstComma"})},N=function(n,t){return d("span",t,n)},d=function(n,t,r){return"<"+n+Object.keys(t).map(function(n){return" "+n+'="'+t[n]+'"'}).join("")+">"+r+""},g=function(n,t,r){return N(v(n,t),{class:"jstBracket"})+N("",{class:"jstFold",onclick:"JSONTree.toggle('"+r+"')"})};this.toggle=function(n){var t=document.getElementById(n),r=t.parentNode,e=t.previousElementSibling;""===t.className?(t.className="jstHiddenBlock",r.className="jstFolded",e.className="jstExpand"):(t.className="",r.className="",e.className="jstFold")};var p=function(n,t){return N(v(n,t),{})},v=function(n,t){return Array(2*t+1).join(" ")+n};return this}(); diff --git a/ExtentReports/Views/Commons/Offline/logo.png b/ExtentReports/Views/Commons/Offline/logo.png new file mode 100644 index 0000000..1c3ec6a Binary files /dev/null and b/ExtentReports/Views/Commons/Offline/logo.png differ diff --git a/extentreports-dotnet-core/Views/IViewsMarker.cs b/ExtentReports/Views/IViewsMarker.cs similarity index 100% rename from extentreports-dotnet-core/Views/IViewsMarker.cs rename to ExtentReports/Views/IViewsMarker.cs diff --git a/ExtentReports/Views/Spark/ISparkMarker.cs b/ExtentReports/Views/Spark/ISparkMarker.cs new file mode 100644 index 0000000..35d7f2f --- /dev/null +++ b/ExtentReports/Views/Spark/ISparkMarker.cs @@ -0,0 +1,6 @@ +namespace AventStack.ExtentReports.Views.Spark +{ + internal interface ISparkMarker : IViewsMarker + { + } +} diff --git a/ExtentReports/Views/Spark/Offline/spark-script.js b/ExtentReports/Views/Spark/Offline/spark-script.js new file mode 100644 index 0000000..edf10a7 --- /dev/null +++ b/ExtentReports/Views/Spark/Offline/spark-script.js @@ -0,0 +1,502 @@ +/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S), +a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/\s*$/g;function Ea(a,b){return B(a,"table")&&B(11!==b.nodeType?b:b.firstChild,"tr")?r(">tbody",a)[0]||a:a}function Fa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Ga(a){var b=Ca.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ha(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(W.hasData(a)&&(f=W.access(a),g=W.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Ba.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ja(f,b,c,d)});if(m&&(e=qa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(na(e,"script"),Fa),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=na(h),f=na(a),d=0,e=f.length;d0&&oa(g,!i&&na(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(U(c)){if(b=c[W.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[W.expando]=void 0}c[X.expando]&&(c[X.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ka(this,a,!0)},remove:function(a){return Ka(this,a)},text:function(a){return T(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.appendChild(a)}})},prepend:function(){return Ja(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ea(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ja(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(na(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return T(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!Aa.test(a)&&!ma[(ka.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function _a(a,b,c,d,e){return new _a.prototype.init(a,b,c,d,e)}r.Tween=_a,_a.prototype={constructor:_a,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=_a.propHooks[this.prop];return a&&a.get?a.get(this):_a.propHooks._default.get(this)},run:function(a){var b,c=_a.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):_a.propHooks._default.set(this),this}},_a.prototype.init.prototype=_a.prototype,_a.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},_a.propHooks.scrollTop=_a.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=_a.prototype.init,r.fx.step={};var ab,bb,cb=/^(?:toggle|show|hide)$/,db=/queueHooks$/;function eb(){bb&&(d.hidden===!1&&a.requestAnimationFrame?a.requestAnimationFrame(eb):a.setTimeout(eb,r.fx.interval),r.fx.tick())}function fb(){return a.setTimeout(function(){ab=void 0}),ab=r.now()}function gb(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ca[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function hb(a,b,c){for(var d,e=(kb.tweeners[b]||[]).concat(kb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?lb:void 0)),void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b), +null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&B(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(L);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),lb={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=mb[b]||r.find.attr;mb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=mb[g],mb[g]=e,e=null!=c(a,b,d)?g:null,mb[g]=f),e}});var nb=/^(?:input|select|textarea|button)$/i,ob=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return T(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):nb.test(a.nodeName)||ob.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function pb(a){var b=a.match(L)||[];return b.join(" ")}function qb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,qb(this)))});if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,qb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(L)||[];while(c=this[i++])if(e=qb(c),d=1===c.nodeType&&" "+pb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=pb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,qb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(L)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=qb(this),b&&W.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":W.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+pb(qb(c))+" ").indexOf(b)>-1)return!0;return!1}});var rb=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":Array.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:pb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(Array.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var sb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!sb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,sb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(W.get(h,"events")||{})[b.type]&&W.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&U(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!U(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=W.access(d,b);e||d.addEventListener(a,c,!0),W.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=W.access(d,b)-1;e?W.access(d,b,e):(d.removeEventListener(a,c,!0),W.remove(d,b))}}});var tb=a.location,ub=r.now(),vb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(Array.isArray(b))r.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(Array.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!ja.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:Array.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}});var Bb=/%20/g,Cb=/#.*$/,Db=/([?&])_=[^&]*/,Eb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Fb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Gb=/^(?:GET|HEAD)$/,Hb=/^\/\//,Ib={},Jb={},Kb="*/".concat("*"),Lb=d.createElement("a");Lb.href=tb.href;function Mb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(L)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nb(a,b,c,d){var e={},f=a===Jb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Ob(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Pb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Qb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:tb.href,type:"GET",isLocal:Fb.test(tb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Ob(Ob(a,r.ajaxSettings),b):Ob(r.ajaxSettings,a)},ajaxPrefilter:Mb(Ib),ajaxTransport:Mb(Jb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Eb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||tb.href)+"").replace(Hb,tb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(L)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Lb.protocol+"//"+Lb.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Nb(Ib,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Gb.test(o.type),f=o.url.replace(Cb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(Bb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(vb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Db,"$1"),n=(vb.test(f)?"&":"?")+"_="+ub++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Kb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Nb(Jb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Pb(o,y,d)),v=Qb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Rb={0:200,1223:204},Sb=r.ajaxSettings.xhr();o.cors=!!Sb&&"withCredentials"in Sb,o.ajax=Sb=!!Sb,r.ajaxTransport(function(b){var c,d;if(o.cors||Sb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Rb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" + } else { + + + + + + } + + \ No newline at end of file diff --git a/ExtentReports/Views/Spark/Partials/Log.cshtml b/ExtentReports/Views/Spark/Partials/Log.cshtml new file mode 100644 index 0000000..9d6cd53 --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/Log.cshtml @@ -0,0 +1,35 @@ +@using AventStack.ExtentReports +@using AventStack.ExtentReports.Model +@using System +@using RazorEngine +@using RazorEngine.Templating + +@{ + var logs = new List(Model.Logs); +} + + + + + @foreach (var log in logs) + { + var status = log.Status.ToString().ToLower(); + + + + + + } + +
    StatusTimestampDetails
    @log.Status@log.Timestamp.ToShortTimeString() + @if (log.HasException) + { + + } + else { @log.Details } + @if (log.HasMedia) { @Include("SparkMedia", log.Media) } +
    \ No newline at end of file diff --git a/ExtentReports/Views/Spark/Partials/Navbar.cshtml b/ExtentReports/Views/Spark/Partials/Navbar.cshtml new file mode 100644 index 0000000..dfa165d --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/Navbar.cshtml @@ -0,0 +1,36 @@ +@{ +var offline = Model.Config.OfflineMode; +var cdnURI="cdn.jsdelivr.net/gh/extent-framework/extent-github-cdn@"; +var csscommit="c43b89d03a7c43dae8bb8f0f078bad1997af6b3b"; +var cssURI = cdnURI + csscommit; +} + \ No newline at end of file diff --git a/ExtentReports/Views/Spark/Partials/RecurseNodes.cshtml b/ExtentReports/Views/Spark/Partials/RecurseNodes.cshtml new file mode 100644 index 0000000..c3bd903 --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/RecurseNodes.cshtml @@ -0,0 +1,72 @@ +@using AventStack.ExtentReports +@using AventStack.ExtentReports.Model +@using System +@using RazorEngine +@using RazorEngine.Templating + +@if (Model.HasChildren) +{ + @{ + var children = new List(Model.Children); + } +
    + @foreach (var child in children) + { +
    +
    +
    +
      +
    • @child.Status
    • +
    • @Math.Round(child.TimeTaken, 2)
    • +
    +
    +
    +
    @child.Name
    +
    + @Include("Attributes", child) +
    + @if (child.HasScreenCaptureDeep) + { +
    + } +
    +
    + @if (child.HasLog) + { + @{ + var css = child.Status != Status.Fail ? "collapse" : ""; + } +
    +
    + @if (child.HasAnyLog) + { +
    + @if (child.HasGeneratedLog) + { + var genLog = new List(child.GeneratedLog); + @foreach (var l in genLog) + { +
    +
    @l.Status
    +
    @l.Details
    +
    + } + } + @if (child.HasLog) { @Include("Log", child) } +
    + } + @foreach (var m in child.Media) + { + @Include("SparkMedia", m) + } +
    +
    + } + @if (child.HasChildren) + { + @Include("RecurseNodes", child) + } +
    + } +
    +} \ No newline at end of file diff --git a/ExtentReports/Views/Spark/Partials/Scripts.cshtml b/ExtentReports/Views/Spark/Partials/Scripts.cshtml new file mode 100644 index 0000000..b8bad50 --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/Scripts.cshtml @@ -0,0 +1,15 @@ +@{ +var offline = Model.Config.OfflineMode; +var cdnURI="cdn.jsdelivr.net/gh/extent-framework/extent-github-cdn@"; +var jscommit="de1c2dd4a8b447f3d7310eed870ae331ba333878";; +var jsURI = cdnURI + jscommit; +} +@if (offline) +{ + +} +else +{ + +} + \ No newline at end of file diff --git a/ExtentReports/Views/Spark/Partials/Sidenav.cshtml b/ExtentReports/Views/Spark/Partials/Sidenav.cshtml new file mode 100644 index 0000000..aa35559 --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/Sidenav.cshtml @@ -0,0 +1,56 @@ +
    +
    +
      + + @if (Model.Report.CategoryCtx.Context.Count > 0) + { + + } + @if (Model.Report.AuthorCtx.Context.Count > 0) + { + + } + @if (Model.Report.DeviceCtx.Context.Count > 0) + { + + } + @if (Model.Report.ExceptionInfoCtx.Context.Count > 0) + { + + } + + @if (Model.Report.Logs.Count > 0) + { + + } +
    +
    +
    diff --git a/ExtentReports/Views/Spark/Partials/SparkAuthorSPA.cshtml b/ExtentReports/Views/Spark/Partials/SparkAuthorSPA.cshtml new file mode 100644 index 0000000..98a3e1a --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/SparkAuthorSPA.cshtml @@ -0,0 +1,9 @@ +@using AventStack.ExtentReports.Model +@using AventStack.ExtentReports.Model.Context + +@{ + var ctx = new SharedContext(); + ctx.Ctx = Model.Report.AuthorCtx; + ctx.View = "Author"; +} +@Include("AttributesView", ctx) \ No newline at end of file diff --git a/ExtentReports/Views/Spark/Partials/SparkBDD.cshtml b/ExtentReports/Views/Spark/Partials/SparkBDD.cshtml new file mode 100644 index 0000000..6f036a9 --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/SparkBDD.cshtml @@ -0,0 +1,79 @@ +@using AventStack.ExtentReports +@using AventStack.ExtentReports.Model +@using System +@using RazorEngine +@using RazorEngine.Templating + +@if (Model.HasChildren) +{ + var children = new List(Model.Children); +
    + @foreach (var node in children) + { +
    + + @if (node.HasChildren) + { + if (node.IsBdd && node.BddType.Name.Replace(" ", "") == "ScenarioOutline") + { + var css = node.Status == Status.Pass ? "collapse" : ""; + var scenarios = new List(node.Children); +
    + @foreach (var child in scenarios) + { +
    +
    +
    +
    @child.Status@child.BddType.Name: @child.Name
    + @if (child.HasScreenCaptureDeep) + { +
    + } +
    +
    + @{ + css = child.Status == Status.Pass ? "collapse" : ""; + var steps = new List(child.Children); + } +
    + @foreach (var step in steps) + { +
    + @step.BddType.Name @step.Name + @Include("StepDetails", step) +
    + } +
    +
    + } +
    + } + else + { + var css = node.Status == Status.Pass ? "collapse" : ""; + var steps = new List(node.Children); +
    +
    + @foreach (var child in steps) + { +
    + @child.BddType.Name @child.Name + @Include("StepDetails", child) +
    + } +
    +
    + } + } +
    + } +
    +} diff --git a/ExtentReports/Views/Spark/Partials/SparkDashboardSPA.cshtml b/ExtentReports/Views/Spark/Partials/SparkDashboardSPA.cshtml new file mode 100644 index 0000000..7492863 --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/SparkDashboardSPA.cshtml @@ -0,0 +1,316 @@ +@using AventStack.ExtentReports +@using AventStack.ExtentReports.Model +@using RazorEngine +@using RazorEngine.Templating + +@{ + var testList = Model.Report.Tests; + + var chartsCount = 2; + chartsCount = Model.Report.Stats.SumStat(Model.Report.Stats.Child) > 0 ? 3 : chartsCount; + chartsCount = Model.Report.Stats.SumStat(Model.Report.Stats.Grandchild) > 0 ? 4 : chartsCount; + + var bdd = testList[0].IsBdd; + var boxSize = "col-md-" + (12/chartsCount); + + var chartWidth="115"; + var chartHeight="90"; + var chartBoxHeight="94"; + + var parentHeading="Classes"; + var childHeading="Tests"; + var grandChildHeading="Steps"; + var parentLabel="class(es)"; + var childLabel = "test(s)"; + var grandchildLabel="step(s)"; + + if (bdd) { + parentHeading="Features"; + childHeading="Scenarios"; + grandChildHeading="Steps"; + parentLabel="feature(s)"; + childLabel="scenario(s)"; + boxSize = "col-md-4"; + chartsCount = 3; + } else { + if (Model.Report.AnalysisStrategy == AnalysisStrategy.Test) { + parentHeading="Tests"; + childHeading="Steps"; + grandChildHeading=""; + parentLabel="test(s)"; + childLabel=grandchildLabel; + } + } +} + +
    +
    +
    +
    +

    Started

    +

    @Model.Report.StartTime

    +
    +
    +
    +
    +

    Ended

    +

    @Model.Report.EndTime

    +
    +
    +
    +
    +

    @parentHeading Passed

    +

    @Model.Report.Stats.Parent[Status.Pass]

    +
    +
    +
    +
    +

    @parentHeading Failed

    +

    @Model.Report.Stats.Parent[Status.Fail]

    +
    +
    +
    +
    +
    +
    +
    +
    @parentHeading
    +
    +
    +
    + +
    +
    + +
    +
    + @if (Model.Report.Stats.SumStat(Model.Report.Stats.Child) > 0) { +
    +
    +
    +
    @childHeading
    +
    +
    +
    + +
    +
    + +
    +
    + } + @if (Model.Report.Stats.SumStat(Model.Report.Stats.Grandchild) > 0) { +
    +
    +
    +
    @grandChildHeading
    +
    +
    +
    + +
    +
    + +
    +
    + } + @if (Model.Report.Stats.SumStat(Model.Report.Stats.Log) > 0 && !bdd) { +
    +
    +
    +
    Log events
    +
    +
    +
    + +
    +
    + +
    +
    + } +
    + @if (Model.Config.TimelineEnabled) + { +
    +

    Timeline

    +
    + +
    +
    +
    + + } +
    + @if (Model.Report.AuthorCtx.Context.Count > 0) + { +
    +
    +

    Author

    +
    + + + @foreach (var x in Model.Report.AuthorCtx.Context) + { + + + + + + + + + } + +
    NamePassedFailedSkippedOthersPassed %
    @x.Value.Attr.Name@x.Value.Passed@x.Value.Failed@x.Value.Skipped@x.Value.Others@((x.Value.Passed/x.Value.Tests.Count)*100)%
    +
    +
    + } + @if (Model.Report.CategoryCtx.Context.Count > 0) + { +
    +
    +

    Tags

    +
    + + @foreach (var x in Model.Report.CategoryCtx.Context) + { + + + + + + + + + } + +
    NamePassedFailedSkippedOthersPassed %
    @x.Value.Attr.Name@x.Value.Passed@x.Value.Failed@x.Value.Skipped@x.Value.Others@((x.Value.Passed/x.Value.Tests.Count)*100)%
    +
    +
    + } + @if (Model.Report.DeviceCtx.Context.Count > 0) + { +
    +
    +

    Device

    +
    + + + @foreach (var x in Model.Report.DeviceCtx.Context) + { + + + + + + + + + } + +
    NamePassedFailedSkippedOthersPassed %
    @x.Value.Attr.Name@x.Value.Passed@x.Value.Failed@x.Value.Skipped@x.Value.Others@((x.Value.Passed/x.Value.Tests.Count)*100)%
    +
    +
    + } + @if (Model.Report.SystemEnvInfo.Count > 0) { +
    +
    +

    System/Environment

    +
    + + + @foreach (var info in Model.Report.SystemEnvInfo) { + + + + + } + +
    NameValue
    @info.Name@info.Value
    +
    +
    + } +
    +
    + diff --git a/ExtentReports/Views/Spark/Partials/SparkDeviceSPA.cshtml b/ExtentReports/Views/Spark/Partials/SparkDeviceSPA.cshtml new file mode 100644 index 0000000..2edacd6 --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/SparkDeviceSPA.cshtml @@ -0,0 +1,9 @@ +@using AventStack.ExtentReports.Model +@using AventStack.ExtentReports.Model.Context + +@{ + var ctx = new SharedContext(); + ctx.Ctx = Model.Report.DeviceCtx; + ctx.View = "Device"; +} +@Include("AttributesView", ctx) \ No newline at end of file diff --git a/ExtentReports/Views/Spark/Partials/SparkExceptionSPA.cshtml b/ExtentReports/Views/Spark/Partials/SparkExceptionSPA.cshtml new file mode 100644 index 0000000..6d9aea3 --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/SparkExceptionSPA.cshtml @@ -0,0 +1,9 @@ +@using AventStack.ExtentReports.Model +@using AventStack.ExtentReports.Model.Context + +@{ + var ctx = new SharedContext(); + ctx.Ctx = Model.Report.ExceptionInfoCtx; + ctx.View = "Exception"; +} +@Include("AttributesView", ctx) \ No newline at end of file diff --git a/ExtentReports/Views/Spark/Partials/SparkLogsSPA.cshtml b/ExtentReports/Views/Spark/Partials/SparkLogsSPA.cshtml new file mode 100644 index 0000000..3475c73 --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/SparkLogsSPA.cshtml @@ -0,0 +1,13 @@ +@if (Model.Report.Logs.Count > 0) +{ +
    +
    +
    + @foreach (var log in Model.Report.Logs) + { + @Raw(log) + } +
    +
    +
    +} \ No newline at end of file diff --git a/ExtentReports/Views/Spark/Partials/SparkMedia.cshtml b/ExtentReports/Views/Spark/Partials/SparkMedia.cshtml new file mode 100644 index 0000000..261b35b --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/SparkMedia.cshtml @@ -0,0 +1,29 @@ +@using AventStack.ExtentReports +@using AventStack.ExtentReports.Model +@using System +@using RazorEngine +@using RazorEngine.Templating + +@if (Model is ScreenCapture) +{ +
    +
    + @if (Model.Base64 != null) + { + base64 img + } + @if (Model.ResolvedPath != null) + { + + } + else if (Model.Path != null) + { + + } + @if (!string.IsNullOrEmpty(Model.Title)) + { +
    @Model.Title
    + } +
    +
    +} diff --git a/ExtentReports/Views/Spark/Partials/SparkStandard.cshtml b/ExtentReports/Views/Spark/Partials/SparkStandard.cshtml new file mode 100644 index 0000000..5145dab --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/SparkStandard.cshtml @@ -0,0 +1,32 @@ +@using AventStack.ExtentReports +@using AventStack.ExtentReports.Model +@using System +@using RazorEngine +@using RazorEngine.Templating + +@foreach (var m in Model.Media) +{ + @Include("SparkMedia", m) +} + +@if (Model.HasAnyLog) +{ +
    + @if (Model.HasGeneratedLog) + { + var genLog = new List(Model.GeneratedLog); + @foreach (var l in genLog) + { +
    +
    @l.Status
    +
    @l.Details
    +
    + } + } + @if (Model.HasLog) { @Include("Log", Model) } +
    +} +@if (Model.HasChildren) +{ +
    @Include("RecurseNodes", Model)
    +} diff --git a/extentreports-dotnet-core/Views/Html/Partials/SparkStepDetails.cshtml b/ExtentReports/Views/Spark/Partials/SparkStepDetails.cshtml similarity index 100% rename from extentreports-dotnet-core/Views/Html/Partials/SparkStepDetails.cshtml rename to ExtentReports/Views/Spark/Partials/SparkStepDetails.cshtml diff --git a/ExtentReports/Views/Spark/Partials/SparkTagSPA.cshtml b/ExtentReports/Views/Spark/Partials/SparkTagSPA.cshtml new file mode 100644 index 0000000..89e12e6 --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/SparkTagSPA.cshtml @@ -0,0 +1,9 @@ +@using AventStack.ExtentReports.Model +@using AventStack.ExtentReports.Model.Context + +@{ + var ctx = new SharedContext(); + ctx.Ctx = Model.Report.CategoryCtx; + ctx.View = "Category"; +} +@Include("AttributesView", ctx) \ No newline at end of file diff --git a/ExtentReports/Views/Spark/Partials/SparkTestSPA.cshtml b/ExtentReports/Views/Spark/Partials/SparkTestSPA.cshtml new file mode 100644 index 0000000..94b948b --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/SparkTestSPA.cshtml @@ -0,0 +1,111 @@ +@using AventStack.ExtentReports +@using AventStack.ExtentReports.Model +@using System +@using RazorEngine +@using RazorEngine.Templating + +@{ + Test t = Model.Report.Tests[0]; + var isbdd = Model.Report.Tests.Count > 0 && t.IsBdd ? true : false; + var testList = Model.Report.Tests; +} + +
    +
    +
    + +
      + + @if (Model.Report.AuthorCtx.HasItems) + { + + } + @if (Model.Report.CategoryCtx.HasItems) + { + + } + @if (Model.Report.DeviceCtx.HasItems) + { + + } +
    +
    +
    +
      + @foreach (var test in testList) + { + var timeTaken = Math.Round(test.TimeTaken, 2); + var status = test.Status.ToString().ToLower(); + var authors = ""; var tags = ""; var devices = ""; + foreach (var x in test.Author) { authors += x.Name + " "; } + foreach (var x in test.Category) { tags += x.Name + " "; } + foreach (var x in test.Device) { devices += x.Name + " "; } +
    • +
      +

      @test.Name

      +

      + @test.StartTime.ToLongTimeString() / @timeTaken secs + @test.Status +

      +
      +
      +
      +
      +
      +
      @test.Name
      + @test.StartTime + @test.EndTime + @timeTaken secs + · #test-id=@test.Id + + + +
      + @if (test.HasAttributes) {
      @Include("Attributes", test)
      } + @if (!string.IsNullOrEmpty(test.Description)) {
      @test.Description
      } +
      +
      + @if (isbdd) { @Include("SparkBDD", test) } else { @Include("SparkStandard", test) } +
      +
    • + } +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    diff --git a/ExtentReports/Views/Spark/Partials/StepDetails.cshtml b/ExtentReports/Views/Spark/Partials/StepDetails.cshtml new file mode 100644 index 0000000..15b270c --- /dev/null +++ b/ExtentReports/Views/Spark/Partials/StepDetails.cshtml @@ -0,0 +1,27 @@ +@using AventStack.ExtentReports +@using AventStack.ExtentReports.Model +@using System +@using RazorEngine +@using RazorEngine.Templating + +@if (Model.HasLog) +{ + var logs = new List(Model.Logs); + foreach (var log in logs) + { +
    + @if (log.HasException) + { + + } + else + { + @log.Details + } + @if (log.HasMedia) + { + @Include("SparkMedia", log.Media); + } +
    + } +} diff --git a/ExtentReports/Views/Spark/SparkIndexSPA.cshtml b/ExtentReports/Views/Spark/SparkIndexSPA.cshtml new file mode 100644 index 0000000..1355f94 --- /dev/null +++ b/ExtentReports/Views/Spark/SparkIndexSPA.cshtml @@ -0,0 +1,36 @@ +@using AventStack.ExtentReports.Model +@using RazorEngine +@using RazorEngine.Templating + +@{ + var cls = ""; + if (Model.Report.Tests.Count > 0) { + Test test = Model.Report.Tests[0]; + cls = Model.Report.Tests.Count > 0 && test.IsBdd ? "bdd-report" : ""; + } +} + + + +@Include("Head") + +
    +
    + @Include("Navbar") + @Include("Sidenav") +
    +
    + @Include("SparkTestSPA") + @if (Model.Report.CategoryCtx.Context.Count > 0) { @Include("SparkTagSPA") } + @if (Model.Report.AuthorCtx.Context.Count > 0) { @Include("SparkAuthorSPA") } + @if (Model.Report.DeviceCtx.Context.Count > 0) { @Include("SparkDeviceSPA") } + @if (Model.Report.ExceptionInfoCtx.Context.Count > 0) { @Include("SparkExceptionSPA") } + @Include("SparkDashboardSPA") + @if (Model.Report.Logs.Count > 0) { @Include("SparkLogsSPA") } +
    +
    +
    +
    + @Include("Scripts") + + \ No newline at end of file diff --git a/KlovReporter/KlovReporter.csproj b/KlovReporter/KlovReporter.csproj new file mode 100644 index 0000000..92ceb18 --- /dev/null +++ b/KlovReporter/KlovReporter.csproj @@ -0,0 +1,29 @@ + + + + netstandard2.0 + KlovReporter + 5.0.0-alpha7 + anshooarora + AventStack + https://www.extentreports.com/logo.jpg + https://github.com/extent-framework/extentreports-csharp/LICENSE + true + anshooarora + https://github.com/extent-framework/extentreports-csharp + Klov Server's Client API (ExtentReports) + extent extentreports klov klovreporter + KlovReporter + KlovReporter .NET Standard (ExtentReports, Klov Server) + true + Fix issues with packaging + 5.0.0-alpha7 + + + + + + + + + diff --git a/KlovReporter/Reporter/ExtentKlovReporter.cs b/KlovReporter/Reporter/ExtentKlovReporter.cs new file mode 100644 index 0000000..f916b4e --- /dev/null +++ b/KlovReporter/Reporter/ExtentKlovReporter.cs @@ -0,0 +1,596 @@ +using AventStack.ExtentReports.Listener.Entity; +using AventStack.ExtentReports.Model; +using AventStack.ExtentReports.Model.Context.Manager; +using AventStack.ExtentReports.Reporter.Support; +using MongoDB.Bson; +using MongoDB.Driver; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace AventStack.ExtentReports.Reporter +{ + public class ExtentKlovReporter : IObserver + { + private const string DefaultProjectName = "Default"; + private const string DatabaseName = "klov"; + + public string ReportName { get; set; } + public ObjectId ReportId { get; private set; } + public string ProjectName { get; set; } + public ObjectId ProjectId { get; private set; } + + private string _url; + private bool _initialized = false; + + private NamedAttributeContextManager _authorContext; + private NamedAttributeContextManager _categoryContext; + private NamedAttributeContextManager _deviceContext; + private Dictionary _categoryNameObjectIdCollection = new Dictionary(); + private Dictionary _authorNameObjectIdCollection = new Dictionary(); + private Dictionary _deviceNameObjectIdCollection = new Dictionary(); + private Dictionary _exceptionNameObjectIdCollection = new Dictionary(); + + private KlovMediaStorageHandler _mediaStorageHandler; + + private long _reportSeq; + private MongoClient _mongoClient; + private IMongoCollection _projectCollection; + private IMongoCollection _reportCollection; + private IMongoCollection _testCollection; + private IMongoCollection _logCollection; + private IMongoCollection _exceptionCollection; + private IMongoCollection _mediaCollection; + private IMongoCollection _categoryCollection; + private IMongoCollection _authorCollection; + private IMongoCollection _deviceCollection; + private IMongoCollection _environmentCollection; + + public ExtentKlovReporter(string projectName, string reportName) + { + ProjectName = string.IsNullOrEmpty(projectName) ? DefaultProjectName : projectName; + ReportName = string.IsNullOrEmpty(reportName) ? "Build " + DateTime.Now : reportName; + } + + public ExtentKlovReporter(string projectName) : this(projectName, null) { } + + /// + /// Initializes KlovReporter with default Klov and MongoDB settings. This default + /// the Klov server and MongoDB to LOCALHOST and also uses default ports 80 and 27017 + /// respectively. + /// + /// ExtentKlovReporter + public ExtentKlovReporter InitWithDefaultSettings() + { + InitMongoDbConnection(); + InitKlovServerConnection(); + return this; + } + + public void InitKlovServerConnection(string url = "http://localhost") + { + _url = url; + } + + /// + /// Connects to MongoDB default settings, localhost:27017 + /// + public void InitMongoDbConnection() + { + _mongoClient = new MongoClient(); + } + + public void InitMongoDbConnection(string host = "localhost", int port = 27017) + { + var conn = "mongodb://" + host; + conn += port > -1 ? ":" + port : ""; + _mongoClient = new MongoClient(conn); + } + + /// + /// Connects to MongoDB using a connection string. + /// Example: mongodb://host:27017,host2:27017/?replicaSet=rs0 + /// + /// + public void InitMongoDbConnection(string connectionString) + { + _mongoClient = new MongoClient(connectionString); + } + + /// + /// Connects to MongoDB using MongoClientSettings + /// + /// The settings for MongoDB client + public void InitMongoDbConnection(MongoClientSettings settings) + { + _mongoClient = new MongoClient(settings); + } + + /// + /// Connects to MongoDB using a MongoUrl + /// + /// Represents an immutable URL style connection string + public void InitMongoDbConnection(MongoUrl url) + { + _mongoClient = new MongoClient(url); + } + + public void OnCompleted() + { + } + + public void OnError(Exception error) + { + } + + public void OnNext(ReportEntity value) + { + var report = value.Report; + var stats = report.Stats; + + if (report.TestQueue.Count == 0) + { + return; + } + + Init(); + UpdateReport(report, stats); + } + + private void Init() + { + if (!_initialized) + { + _initialized = true; + var db = _mongoClient.GetDatabase(DatabaseName); + InitializeCollections(db); + SetupProject(); + } + } + + private void InitializeCollections(IMongoDatabase db) + { + _projectCollection = db.GetCollection("project"); + _reportCollection = db.GetCollection("report"); + _testCollection = db.GetCollection("test"); + _logCollection = db.GetCollection("log"); + _exceptionCollection = db.GetCollection("exception"); + _mediaCollection = db.GetCollection("media"); + _categoryCollection = db.GetCollection("category"); + _authorCollection = db.GetCollection("author"); + _deviceCollection = db.GetCollection("device"); + _environmentCollection = db.GetCollection("environment"); + } + + private void SetupProject() + { + ProjectName = string.IsNullOrEmpty(ProjectName) ? DefaultProjectName : ProjectName; + var document = new BsonDocument + { + { "name", ProjectName } + }; + + var bsonProject = _projectCollection.Find(document).FirstOrDefault(); + if (bsonProject != null) + { + ProjectId = bsonProject["_id"].AsObjectId; + } + else + { + document.Add("createdAt", DateTime.Now); + _projectCollection.InsertOne(document); + ProjectId = document["_id"].AsObjectId; + } + + CreateReport(); + } + + private void CreateReport() + { + ReportName = string.IsNullOrEmpty(ReportName) ? "Build " + DateTime.Now : ReportName; + _reportSeq = _reportCollection.CountDocuments(new BsonDocument { { "project", ProjectId } }) + 1; + + var document = new BsonDocument + { + { "name", ReportName }, + { "project", ProjectId }, + { "projectName", ProjectName }, + { "startTime", DateTime.Now }, + { "seq", _reportSeq } + }; + + _reportCollection.InsertOne(document); + ReportId = document["_id"].AsObjectId; + } + + private void UpdateReport(Report report, ReportStats stats) + { + var doc = Builders.Update + .Set("endTime", report.EndTime) + .Set("duration", report.TimeTaken.TotalMilliseconds) + .Set("status", report.Status.ToString().ToLower()) + .Set("parentLength", stats.SumStat(stats.Parent)) + .Set("passParentLength", stats.Parent[Status.Pass]) + .Set("failParentLength", stats.Parent[Status.Fail]) + .Set("warningParentLength", stats.Parent[Status.Warning]) + .Set("skipParentLength", stats.Parent[Status.Skip]) + .Set("childLength", stats.SumStat(stats.Child)) + .Set("passChildLength", stats.Child[Status.Pass]) + .Set("failChildLength", stats.Child[Status.Fail]) + .Set("warningChildLength", stats.Child[Status.Warning]) + .Set("skipChildLength", stats.Child[Status.Skip]) + .Set("grandChildLength", stats.SumStat(stats.Grandchild)) + .Set("passGrandChildLength", stats.Grandchild[Status.Pass]) + .Set("failGrandChildLength", stats.Grandchild[Status.Fail]) + .Set("warningGrandChildLength", stats.Grandchild[Status.Warning]) + .Set("skipGrandChildLength", stats.Grandchild[Status.Skip]) + .Set("analysisStrategy", stats.AnalysisStrategy.ToString().ToUpper()) + .Set("bdd", report.IsBDD); + + if (report.HasAuthors) + { + var x = report.AuthorCtx.Context.Keys; + doc = doc.Set("authorNameList", x); + } + if (report.HasCategories) + { + var x = report.CategoryCtx.Context.Keys; + doc = doc.Set("categoryNameList", x); + } + if (report.HasDevices) + { + var x = report.DeviceCtx.Context.Keys; + doc = doc.Set("deviceNameList", x); + } + if (report.HasExceptions) + { + var x = report.ExceptionInfoCtx.Context.Keys; + doc = doc.Set("exceptions", x); + } + + _reportCollection.UpdateOne( + filter: new BsonDocument("_id", ReportId), + update: doc + ); + + UpdateSystemEnvInfo(report.SystemEnvInfo); + UpdateTests(report.TestQueue.ToList()); + } + + private void UpdateSystemEnvInfo(List env) + { + foreach (var attr in env) + { + var document = new BsonDocument + { + { "project", ProjectId }, + { "report", ReportId }, + { "name", attr.Name } + }; + + var findResult = _environmentCollection.Find(document); + + if (findResult == null && !findResult.Any()) + { + document.Add("value", attr.Value); + } + else + { + var id = findResult.First()["_id"].AsObjectId; + document = new BsonDocument + { + { "_id", id }, + { "value", attr.Value } + }; + + var filter = Builders.Filter.Eq("_id", id); + _environmentCollection.UpdateOne(filter, document); + } + } + } + + public void UpdateTests(List tests) + { + foreach (var test in tests) + { + var doc = new BsonDocument + { + { "project", ProjectId }, + { "report", ReportId }, + { "reportSeq", _reportSeq }, + { "reportName", ReportName } + }; + + doc["level"] = test.Level; + doc["name"] = test.Name; + doc["status"] = test.Status.ToString().ToLower(); + doc["duration"] = test.TimeTaken; + doc["description"] = test.Description ?? ""; + doc["startTime"] = test.StartTime; + doc["endTime"] = test.EndTime; + doc["bdd"] = test.IsBdd; + doc["leaf"] = test.Leaf; + doc["childNodesLength"] = test.Children.Count; + doc["mediaCount"] = test.Media.Count; + doc["logCount"] = test.Logs.Count + test.GeneratedLog.Count; + doc["categorized"] = test.HasAttributes; + + if (test.IsBdd) + { + doc["bddType"] = test.BddType.Name; + } + if (test.HasAuthor) + { + doc = doc.Set("authorNameList", new BsonArray(test.Author.Select(x => x.Name).ToArray())); + } + if (test.HasCategory) + { + doc = doc.Set("categoryNameList", new BsonArray(test.Category.Select(x => x.Name).ToArray())); + } + if (test.HasDevice) + { + doc = doc.Set("deviceNameList", new BsonArray(test.Device.Select(x => x.Name).ToArray())); + } + + if (test.Parent != null) + { + doc["parent"] = new ObjectId(test.Parent.Info["ObjectId"].ToString()); + doc["parentName"] = test.Parent.Name; + } + + if (test.Info.ContainsKey("ObjectId")) + { + _testCollection.UpdateOne( + filter: new BsonDocument("_id", new ObjectId(test.Info["ObjectId"].ToString())), + update: doc + ); + } + else + { + _testCollection.InsertOne(doc); + test.Info["ObjectId"] = doc["_id"].AsObjectId; + } + + UpdateLogs(test); + UpdateExceptions(test.ExceptionInfo, test); + UpdateAttributes(test, test.Author, _authorNameObjectIdCollection, _authorCollection, _authorContext); + UpdateAttributes(test, test.Category, _categoryNameObjectIdCollection, _categoryCollection, _categoryContext); + UpdateAttributes(test, test.Device, _deviceNameObjectIdCollection, _deviceCollection, _deviceContext); + UploadMedia(test); + + if (test.HasChildren) + { + UpdateTests(test.Children.ToList()); + } + } + } + + private void UpdateLogs(Test test) + { + var logs = test.Logs.ToList(); + logs.AddRange(test.GeneratedLog.ToList()); + + foreach (var log in logs) + { + var doc = new BsonDocument + { + { "project", ProjectId }, + { "report", ReportId }, + { "test", new ObjectId(test.Info["ObjectId"].ToString()) }, + { "testName", test.Name }, + { "sequence", log.Seq }, + { "status", log.Status.ToString().ToLower() }, + { "timestamp", log.Timestamp }, + { "mediaCount", log.HasMedia ? 1 : 0 }, + { "details", log.Details }, + }; + + if (log.HasException) + { + doc["exception"] = log.ExceptionInfo.Name; + doc["stacktrace"] = GetException(log.ExceptionInfo.Exception); + + var updateTest = Builders.Update + .Set("exceptionName", log.ExceptionInfo.Name); + _testCollection.UpdateOne( + filter: new BsonDocument("_id", new ObjectId(test.Info["ObjectId"].ToString())), + update: updateTest + ); + } + + if (log.HasMedia && !string.IsNullOrEmpty(log.Media.Base64)) + { + doc["details"] = log.Details + log.Media.Base64; + } + + if (log.Info.ContainsKey("ObjectId")) + { + _logCollection.UpdateOne( + filter: new BsonDocument("_id", new ObjectId(log.Info["ObjectId"].ToString())), + update: doc + ); + } + else + { + _logCollection.InsertOne(doc); + log.Info["ObjectId"] = doc["_id"].AsObjectId; + } + } + } + + private string GetException(Exception exception) + { + var ex = exception.Message ?? ""; + ex += exception.StackTrace ?? ""; + return ex; + } + + private void UpdateExceptions(List exceptionInfo, Test test) + { + foreach (var ex in exceptionInfo) + { + var doc = new BsonDocument + { + { "project", ProjectId }, + { "report", ReportId } + }; + + doc["name"] = ex.Name; + + var findResult = _exceptionCollection.Find(doc).FirstOrDefault(); + + if (!_exceptionNameObjectIdCollection.ContainsKey(ex.Name)) + { + if (findResult != null) + { + _exceptionNameObjectIdCollection.Add(ex.Name, findResult["_id"].AsObjectId); + } + else + { + doc = new BsonDocument + { + { "project", ProjectId }, + { "report", ReportId }, + { "name", ex.Name }, + { "stacktrace", GetException(ex.Exception) }, + { "testCount", 0 } + }; + + _exceptionCollection.InsertOne(doc); + + var exId = doc["_id"].AsObjectId; + + doc = new BsonDocument + { + { "_id", exId } + }; + findResult = _exceptionCollection.Find(doc).FirstOrDefault(); + + _exceptionNameObjectIdCollection.Add(ex.Name, exId); + } + } + + var testCount = ((int)findResult["testCount"]) + 1; + var filter = Builders.Filter.Eq("_id", findResult["_id"].AsObjectId); + var update = Builders.Update.Set("testCount", testCount); + _exceptionCollection.UpdateOne(filter, update); + + filter = Builders.Filter.Eq("_id", test.Info["ObjectId"]); + update = Builders.Update.Set("exception", _exceptionNameObjectIdCollection[ex.Name]); + _testCollection.UpdateOne(filter, update); + } + } + + private void UpdateAttributes(Test test, ISet set, Dictionary nameObjectIdCollection, + IMongoCollection mongoCollection, NamedAttributeContextManager attributeContext) where T : NamedAttribute + { + foreach (var attribute in set) + { + BsonDocument doc; + + if (!nameObjectIdCollection.ContainsKey(attribute.Name)) + { + doc = new BsonDocument + { + { "report", ReportId }, + { "project", ProjectId }, + { "name", attribute.Name } + }; + + var findResult = mongoCollection.Find(doc).FirstOrDefault(); + + if (findResult != null) + { + nameObjectIdCollection.Add(attribute.Name, findResult["_id"].AsObjectId); + } + else + { + doc = new BsonDocument + { + { "testIdList", new BsonArray { new ObjectId(test.Info["ObjectId"].ToString()) } }, + { "testNameList", new BsonArray { test.Name } }, + { "testLength", 1 }, + { "project", ProjectId }, + { "report", ReportId }, + { "name", attribute.Name }, + { "timeTaken", Convert.ToInt64(0) } + }; + + mongoCollection.InsertOne(doc); + var id = doc["_id"].AsObjectId; + nameObjectIdCollection.Add(attribute.Name, id); + } + } + else + { + var id = nameObjectIdCollection[attribute.Name]; + int testLength = 1; + + if (attributeContext != null) + { + var context = attributeContext.Context.Where(x => x.Key.Equals(attribute.Name)); + if (context.Any()) + { + testLength = context.Count() + 1; + } + } + + var filter = Builders.Filter.Eq("_id", id); + var push = Builders.Update + .Push("testIdList", new ObjectId(test.Info["ObjectId"].ToString())) + .Push("testNameList", test.Name); + mongoCollection.UpdateOne(filter, push); + + var update = Builders.Update + .Set("testLength", testLength); + mongoCollection.UpdateOne(filter, update); + } + } + } + + private void UploadMedia(Test test) + { + if (_mediaStorageHandler == null) + { + KlovMedia klovMedia = new KlovMedia() + { + ProjectId = ProjectId, + ReportId = ReportId, + MediaCollection = _mediaCollection + }; + _mediaStorageHandler = new KlovMediaStorageHandler(_url, klovMedia); + } + + if (test.HasScreenCapture) + { + foreach (var m in test.Media) + { + var path = m.ResolvedPath ?? m.Path; + + if (!m.Info.ContainsKey("TestObjectId") && !string.IsNullOrEmpty(path)) + { + m.Info["TestObjectId"] = test.Info["ObjectId"]; + m.Info["TestName"] = test.Name; + _mediaStorageHandler.SaveScreenCapture(m); + } + } + } + + foreach (var log in test.Logs.ToList()) + { + if (log.HasMedia) + { + var path = log.Media.ResolvedPath ?? log.Media.Path; + + if (!log.Media.Info.ContainsKey("LogObjectId") && !string.IsNullOrEmpty(path)) + { + log.Media.Info["TestObjectId"] = test.Info["ObjectId"]; + log.Media.Info["LogObjectId"] = log.Info["ObjectId"]; + log.Media.Info["TestName"] = test.Name; + _mediaStorageHandler.SaveScreenCapture(log.Media); + } + } + } + } + } +} diff --git a/KlovReporter/Reporter/Support/KlovHttpMediaManager.cs b/KlovReporter/Reporter/Support/KlovHttpMediaManager.cs new file mode 100644 index 0000000..6466e03 --- /dev/null +++ b/KlovReporter/Reporter/Support/KlovHttpMediaManager.cs @@ -0,0 +1,98 @@ +using AventStack.ExtentReports.Model; +using MongoDB.Bson; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Runtime.CompilerServices; + +namespace AventStack.ExtentReports.Reporter.Support +{ + internal class KlovHttpMediaManager + { + private const string Route = "api/files"; + + private string _host; + + public void Init(string host) + { + if (!host.Substring(host.Length - 1).Equals("/")) + { + host += "/"; + } + _host = host; + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public void StoreMedia(ScreenCapture m) + { + var path = string.IsNullOrEmpty(m.ResolvedPath) ? m.Path : m.ResolvedPath; + + if (string.IsNullOrEmpty(path)) + { + return; + } + + if (!File.Exists(path)) + { + throw new IOException("The system cannot find the file specified " + m.Path); + } + + var uri = new Uri(_host); + + var reader = new StreamReader(path); + var handler = new HttpClientHandler() { UseCookies = false }; + + if (_host.ToLower().StartsWith("https")) + { + handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; }; + } + + var client = new HttpClient(handler) + { + BaseAddress = uri + }; + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + client.DefaultRequestHeaders.Add("Accept", "application/json"); + client.DefaultRequestHeaders.Add("Connection", "keep-alive"); + client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0"); + + var content = new MultipartFormDataContent(DateTime.Now.ToString(CultureInfo.InvariantCulture)); + var logId = m.Info.ContainsKey("LogObjectId") ? new ObjectId(m.Info["LogObjectId"].ToString()).ToString() : null; + + var values = new[] + { + new KeyValuePair("name", m.Id.ToString() + Path.GetExtension(m.Path)), + new KeyValuePair("id", new ObjectId(m.Info["ObjectId"].ToString()).ToString()), + new KeyValuePair("reportId", new ObjectId(m.Info["ReportObjectId"].ToString()).ToString()), + new KeyValuePair("testId", new ObjectId(m.Info["TestObjectId"].ToString()).ToString()) + }.ToList(); + + if (logId != null) + { + values.Add(new KeyValuePair("logId", logId)); + } + + foreach (var keyValuePair in values) + { + content.Add(new StringContent(keyValuePair.Value), string.Format("\"{0}\"", keyValuePair.Key)); + } + + var file = File.ReadAllBytes(path); + var fileName = m.Id.ToString() + Path.GetExtension(path); + var imageContent = new ByteArrayContent(file); + content.Add(imageContent, "f", fileName); + + var result = client.PostAsync(_host + Route, content).Result; + + if (result.StatusCode != HttpStatusCode.OK) + { + throw new IOException("Unable to upload file to server: " + m.Path); + } + } + } +} \ No newline at end of file diff --git a/extentreports-dotnet-core/MediaStorage/KlovMedia.cs b/KlovReporter/Reporter/Support/KlovMedia.cs similarity index 83% rename from extentreports-dotnet-core/MediaStorage/KlovMedia.cs rename to KlovReporter/Reporter/Support/KlovMedia.cs index 474883d..dd6f08f 100644 --- a/extentreports-dotnet-core/MediaStorage/KlovMedia.cs +++ b/KlovReporter/Reporter/Support/KlovMedia.cs @@ -1,7 +1,7 @@ using MongoDB.Bson; using MongoDB.Driver; -namespace AventStack.ExtentReports.MediaStorage +namespace AventStack.ExtentReports.Reporter.Support { internal class KlovMedia { diff --git a/extentreports-dotnet-core/MediaStorage/KlovMediaStorageHandler.cs b/KlovReporter/Reporter/Support/KlovMediaStorageHandler.cs similarity index 50% rename from extentreports-dotnet-core/MediaStorage/KlovMediaStorageHandler.cs rename to KlovReporter/Reporter/Support/KlovMediaStorageHandler.cs index 5010bed..d4c8b8e 100644 --- a/extentreports-dotnet-core/MediaStorage/KlovMediaStorageHandler.cs +++ b/KlovReporter/Reporter/Support/KlovMediaStorageHandler.cs @@ -1,10 +1,8 @@ using AventStack.ExtentReports.Model; - using MongoDB.Bson; - using System; -namespace AventStack.ExtentReports.MediaStorage +namespace AventStack.ExtentReports.Reporter.Support { internal class KlovMediaStorageHandler { @@ -20,30 +18,39 @@ public KlovMediaStorageHandler(string url, KlovMedia media) _mediamanager.Init(url); } - public void SaveScreenCapture(BasicMongoReportElement el, ScreenCapture media) + public void SaveScreenCapture(ScreenCapture media) { - var document = new BsonDocument + var doc = new BsonDocument { { "project", _klovmedia.ProjectId }, { "report", _klovmedia.ReportId }, - { "sequence", media.Sequence }, - { "mediaType", "img" }, - { "test", media.TestObjectId } + { "test", new ObjectId(media.Info["TestObjectId"].ToString()) } }; - if (el is Test) + if (media.Info.ContainsKey("LogObjectId")) { - document.Add("testName", ((Test)el).Name); + doc.Add("log", new ObjectId(media.Info["LogObjectId"].ToString())); } else { - document.Add("log", el.ObjectId); + doc.Add("testName", media.Info["TestName"].ToString()); + } + + if (media.IsBase64) + { + doc.Add("base64String", media.Base64); + } + + _klovmedia.MediaCollection.InsertOne(doc); + var id = doc["_id"].AsObjectId; + media.Info["ObjectId"] = id; + media.Info["ReportObjectId"] = _klovmedia.ReportId; + + if (media.IsBase64) + { + return; } - _klovmedia.MediaCollection.InsertOne(document); - var id = document["_id"].AsObjectId; - media.ObjectId = id; - media.ReportObjectId = _klovmedia.ReportId; _mediamanager.StoreMedia(media); } diff --git a/Readme.md b/Readme.md index 89f5b61..5a5838a 100644 --- a/Readme.md +++ b/Readme.md @@ -1,20 +1,32 @@ -## ExtentReports 4 .NET Core [![NuGet](https://img.shields.io/nuget/v/extentreports.svg)](https://www.nuget.org/packages/ExtentReports) [![Join the chat at https://gitter.im/anshooarora/extentreports-csharp](https://badges.gitter.im/anshooarora/extentreports-csharp.svg)](https://gitter.im/anshooarora/extentreports-csharp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/8d4e66d07b9e4ebca7cef7c5b5eb7ba2)](https://www.codacy.com/app/anshooarora/extentreports-csharp?utm_source=github.com&utm_medium=referral&utm_content=extent-framework/extentreports-csharp&utm_campaign=Badge_Grade) ![](https://img.shields.io/github/license/extent-framework/extentreports-csharp.svg?style=plastic) +## ExtentReports 5 [![NuGet](https://img.shields.io/nuget/v/extentreports.svg)](https://www.nuget.org/packages/ExtentReports) [![Join the chat at https://gitter.im/anshooarora/extentreports-csharp](https://badges.gitter.im/anshooarora/extentreports-csharp.svg)](https://gitter.im/anshooarora/extentreports-csharp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ![](https://img.shields.io/github/license/extent-framework/extentreports-csharp.svg?style=plastic) -### Documentation +### Documentation ### -View [extentreports.com](http://extentreports.com/docs/versions/4/net/) for complete documentation. +Documentation for ExtentReports 5.x and lower versions is hosted on [ExtentReports.com](https://www.extentreports.com/docs/versions/5/net/index.html) + +### Official Package ### + +https://www.nuget.org/packages/ExtentReports + +### Samples ### + +* [Spark](http://extentreports.com/docs/v5/wiki/spark/spark.html) from [Docs: A Complete Example](https://www.extentreports.com/docs/versions/5/net/index.html#complete-example) ### Contributing ### For more information on contributing to the ExtentReports project, please see [CONTRIBUTING.md](https://github.com/extent-framework/extentreports-csharp/blob/master/Contributing.md). -A complete list of contributors since ExtentReports migrated from [@anshooarora/extentreports-csharp](https://github.com/anshooarora/extentreports-csharp) can be [found here](https://github.com/anshooarora/extentreports-csharp/graphs/contributors). +A complete list of contributors since ExtentReports migrated from [@anshooarora/extentreports-csharp](https://github.com/anshooarora/extentreports-csharp) can be [found here](https://github.com/extent-framework/extentreports-csharp/graphs/contributors). + +### Upcoming ### + +* Want to see a feature added? Let me know [here](https://github.com/extent-framework/extentreports-chsarp/issues) ### Versions ### -* ExtentReports 4.x is available from the [main branch](https://github.com/extent-framework/extentreports-csharp) +* ExtentReports 4.x is available from the [4.x branch](https://github.com/extent-framework/extentreports-chsarp/tree/4.x) * ExtentReports 3.x is no longer maintained, and is available from [@anshooarora/extentreports-csharp](https://github.com/anshooarora/extentreports-csharp) ### License ### -ExtentReports is Open Source software and ExtentReports 4.0 is released under Apache-2.0. +ExtentReports is Open Source software and ExtentReports 5.0 is released under Apache-2.0. diff --git a/config/html-config.xml b/config/html-config.xml deleted file mode 100644 index 45cae19..0000000 --- a/config/html-config.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - standard - - - - UTF-8 - - - - https - - - Extent Framework - - - Build 1 - - - - - - - - - - - - - \ No newline at end of file diff --git a/config/logger-config.xml b/config/logger-config.xml deleted file mode 100644 index f3b5742..0000000 --- a/config/logger-config.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - standard - - - - UTF-8 - - - true - - - - https - - - Extent Framework - - - Build 1 - - - MMM dd, yyyy HH:mm:ss - - - - - - - - - - - - diff --git a/config/v3html-config.xml b/config/v3html-config.xml deleted file mode 100644 index 0d40510..0000000 --- a/config/v3html-config.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - standard - - - - UTF-8 - - - - https - - - Extent Framework - - - Build 1 - - - MMM dd, yyyy HH:mm:ss - - - true - false - true - true - - - - - - - - - - - - - \ No newline at end of file diff --git a/extentreports-dotnet-core.sln b/extentreports-dotnet-core.sln deleted file mode 100644 index d556989..0000000 --- a/extentreports-dotnet-core.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.960 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExtentReports", "extentreports-dotnet-core\ExtentReports.csproj", "{2B516987-7D8F-4A9F-A654-2E826BF76E1D}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2B516987-7D8F-4A9F-A654-2E826BF76E1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2B516987-7D8F-4A9F-A654-2E826BF76E1D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2B516987-7D8F-4A9F-A654-2E826BF76E1D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2B516987-7D8F-4A9F-A654-2E826BF76E1D}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {86644F5F-5313-4E77-BB04-FAA15DA956AE} - EndGlobalSection -EndGlobal diff --git a/extentreports-dotnet-core/App.cs b/extentreports-dotnet-core/App.cs deleted file mode 100644 index 91c5383..0000000 --- a/extentreports-dotnet-core/App.cs +++ /dev/null @@ -1,13 +0,0 @@ -using AventStack.ExtentReports.Reporter; -using System; - -namespace AventStack.ExtentReports -{ - public class App - { - public static void Main(string[] args) - { - - } - } -} diff --git a/extentreports-dotnet-core/Configuration/Config.cs b/extentreports-dotnet-core/Configuration/Config.cs deleted file mode 100644 index a8c5c73..0000000 --- a/extentreports-dotnet-core/Configuration/Config.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace AventStack.ExtentReports.Configuration -{ - public class Config - { - public string Key { get; private set; } - public string Value { get; private set; } - - public Config(string k, string v) - { - Key = k; - Value = v; - } - } -} diff --git a/extentreports-dotnet-core/Configuration/ConfigurationManager.cs b/extentreports-dotnet-core/Configuration/ConfigurationManager.cs deleted file mode 100644 index 155dbdf..0000000 --- a/extentreports-dotnet-core/Configuration/ConfigurationManager.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace AventStack.ExtentReports.Configuration -{ - public class ConfigurationManager - { - public List Configuration { get; internal set; } = new List(); - - public string GetValue(string k) - { - var c = Configuration.Where(x => x.Key.Equals(k)); - - if (c.Count() > 0) - return c.First().Value; - - return null; - } - - public void AddConfig(Config c) - { - if (ContainsConfig(c.Key)) - RemoveConfig(c.Key); - - Configuration.Add(c); - } - - private bool ContainsConfig(string k) - { - return Configuration.Where(x => x.Key.Equals(k)).Count() == 1; - } - - private void RemoveConfig(string k) - { - var c = Configuration.Where(x => x.Key.Equals(k)).First(); - Configuration.Remove(c); - } - } -} diff --git a/extentreports-dotnet-core/Core/IAnalysisStrategyService.cs b/extentreports-dotnet-core/Core/IAnalysisStrategyService.cs deleted file mode 100644 index e61258e..0000000 --- a/extentreports-dotnet-core/Core/IAnalysisStrategyService.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AventStack.ExtentReports.Core -{ - public interface IAnalysisStrategyService - { - AnalysisStrategy AnalysisStrategy { get; set; } - } -} diff --git a/extentreports-dotnet-core/Core/IExtentReporter.cs b/extentreports-dotnet-core/Core/IExtentReporter.cs deleted file mode 100644 index 9207eef..0000000 --- a/extentreports-dotnet-core/Core/IExtentReporter.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace AventStack.ExtentReports.Core -{ - public interface IExtentReporter : ITestListener, IAnalysisStrategyService - { - /// - /// Name of the Reporter - /// - string ReporterName { get; } - - /// - /// Starts passing run information to the reporter - /// - void Start(); - - /// - /// Stops the reporter. Ensures no information is passed to the reporter. - /// - void Stop(); - - /// - /// Write to or update the target source (file, database) - /// - /// - void Flush(ReportAggregates reportAggregates); - } -} diff --git a/extentreports-dotnet-core/Core/IMediaContainer.cs b/extentreports-dotnet-core/Core/IMediaContainer.cs deleted file mode 100644 index 079ce39..0000000 --- a/extentreports-dotnet-core/Core/IMediaContainer.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace AventStack.ExtentReports.Core -{ - public interface IMediaContainer - { - T AddScreenCaptureFromPath(string path, string title = null); - T AddScreenCaptureFromBase64String(string s, string title = null); - } -} diff --git a/extentreports-dotnet-core/Core/IReportAggregatesListener.cs b/extentreports-dotnet-core/Core/IReportAggregatesListener.cs deleted file mode 100644 index 9563da2..0000000 --- a/extentreports-dotnet-core/Core/IReportAggregatesListener.cs +++ /dev/null @@ -1,18 +0,0 @@ -using AventStack.ExtentReports; -using AventStack.ExtentReports.Model; - -using System.Collections.Generic; - -namespace AventStack.ExtentReports.Core -{ - public interface IReportAggregatesListener - { - List TestList { set; } - - List TestRunnerLogs { set; } - - ReportStatusStats ReportStatusStats { set; } - - List StatusList { set; } - } -} diff --git a/extentreports-dotnet-core/Core/IReportService.cs b/extentreports-dotnet-core/Core/IReportService.cs deleted file mode 100644 index b2a1081..0000000 --- a/extentreports-dotnet-core/Core/IReportService.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AventStack.ExtentReports.Core -{ - public interface IReportService - { - void AttachReporter(params IExtentReporter[] reporter); - } -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Core/IRunResult.cs b/extentreports-dotnet-core/Core/IRunResult.cs deleted file mode 100644 index 2f3f234..0000000 --- a/extentreports-dotnet-core/Core/IRunResult.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace AventStack.ExtentReports.Core -{ - /// - /// Marker interface for execution's result providing a Status - /// - public interface IRunResult - { - Status Status { get; } - } -} diff --git a/extentreports-dotnet-core/Core/ITestListener.cs b/extentreports-dotnet-core/Core/ITestListener.cs deleted file mode 100644 index a22fb73..0000000 --- a/extentreports-dotnet-core/Core/ITestListener.cs +++ /dev/null @@ -1,17 +0,0 @@ -using AventStack.ExtentReports.Model; - -namespace AventStack.ExtentReports.Core -{ - public interface ITestListener - { - void OnTestStarted(Test test); - void OnTestRemoved(Test test); - void OnNodeStarted(Test node); - void OnLogAdded(Test test, Log log); - void OnCategoryAssigned(Test test, Category category); - void OnAuthorAssigned(Test test, Author author); - void OnDeviceAssigned(Test test, Device device); - void OnScreenCaptureAdded(Test test, ScreenCapture screenCapture); - void OnScreenCaptureAdded(Log log, ScreenCapture screenCapture); - } -} diff --git a/extentreports-dotnet-core/Core/InvalidAnalysisStrategyException.cs b/extentreports-dotnet-core/Core/InvalidAnalysisStrategyException.cs deleted file mode 100644 index 85a4687..0000000 --- a/extentreports-dotnet-core/Core/InvalidAnalysisStrategyException.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; - -namespace AventStack.ExtentReports.Core -{ - [Serializable] - internal class InvalidAnalysisStrategyException : Exception - { - public InvalidAnalysisStrategyException() - { - } - - public InvalidAnalysisStrategyException(string message) : base(message) - { - } - - public InvalidAnalysisStrategyException(string message, Exception innerException) : base(message, innerException) - { - } - } -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Core/RazorEngineTemplate.cs b/extentreports-dotnet-core/Core/RazorEngineTemplate.cs deleted file mode 100644 index f8e4044..0000000 --- a/extentreports-dotnet-core/Core/RazorEngineTemplate.cs +++ /dev/null @@ -1,13 +0,0 @@ -using RazorEngine.Templating; - -namespace AventStack.ExtentReports.Core -{ - public class RazorEngineTemplate : TemplateBase - { - public new T Model - { - get { return base.Model; } - set { base.Model = value; } - } - } -} diff --git a/extentreports-dotnet-core/Core/ReportAggregates.cs b/extentreports-dotnet-core/Core/ReportAggregates.cs deleted file mode 100644 index af70773..0000000 --- a/extentreports-dotnet-core/Core/ReportAggregates.cs +++ /dev/null @@ -1,28 +0,0 @@ -using AventStack.ExtentReports.Model; -using AventStack.ExtentReports.Model.Context; - -using System.Collections.Generic; - -namespace AventStack.ExtentReports.Core -{ - public class ReportAggregates - { - public List TestList { get; internal set; } - - public List TestRunnerLogs { get; internal set; } - - public ReportStatusStats ReportStatusStats { get; internal set; } - - public List StatusList { get; internal set; } - - public TestAttributeTestContextProvider AuthorContext { get; internal set; } - - public TestAttributeTestContextProvider CategoryContext { get; internal set; } - - public TestAttributeTestContextProvider DeviceContext { get; internal set; } - - public TestAttributeTestContextProvider ExceptionInfoContext { get; internal set; } - - public SystemAttributeContext SystemAttributeContext { get; internal set; } - } -} diff --git a/extentreports-dotnet-core/Core/ReportConfigurator.cs b/extentreports-dotnet-core/Core/ReportConfigurator.cs deleted file mode 100644 index 10371ae..0000000 --- a/extentreports-dotnet-core/Core/ReportConfigurator.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; - -namespace AventStack.ExtentReports.Core -{ - public class ReportConfigurator - { - private static readonly Lazy lazy = new Lazy(() => new ReportConfigurator()); - - public static ReportConfigurator I { get { return lazy.Value; } } - - private ReportConfigurator() - { - } - - public StatusConfigurator StatusConfigurator - { - get - { - return StatusConfigurator.I; - } - } - } -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Core/ReportObservable.cs b/extentreports-dotnet-core/Core/ReportObservable.cs deleted file mode 100644 index 41cf291..0000000 --- a/extentreports-dotnet-core/Core/ReportObservable.cs +++ /dev/null @@ -1,414 +0,0 @@ -using AventStack.ExtentReports.Model; -using AventStack.ExtentReports.Model.Context; -using AventStack.ExtentReports.Utils; - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace AventStack.ExtentReports.Core -{ - public abstract class ReportObservable - { - /// - /// The current AnalysisStrategy for the run session. Ths decides the technique used - /// to count the test status at different levels. For example, for a BDD-style report, - /// the levels to be calculated are Feature, Scenario and Step: 3 levels. For a generic, - /// non-BDD style report, levels can be dynamic and typically consist of: - /// - /// - /// 1 Level: Test - /// 2 Levels: Test, Method - /// 2 Levels: Class, Test - /// - /// - protected internal AnalysisStrategy AnalysisStrategy - { - get - { - return _analysisStrategy; - } - set - { - _analysisStrategy = value; - ReportStatusStats = new ReportStatusStats(value); - } - } - - /// - /// Execution status - /// - protected internal Status ReportStatus { get; private set; } = Status.Pass; - - /// - /// Instance of - /// - protected internal ReportStatusStats ReportStatusStats { get; private set; } = new ReportStatusStats(); - - /// - /// Report start time - /// - public DateTime ReportStartDateTime { get; } = DateTime.Now; - - /// - /// Report end time - /// - public DateTime ReportEndDateTime { get; private set; } = DateTime.Now; - - /// - /// A list of all reporters started by the attachReporter method - /// - protected internal List StarterReporterList { get; private set; } = new List(); - - protected TestAttributeTestContextProvider AuthorContext = new TestAttributeTestContextProvider(); - protected TestAttributeTestContextProvider CategoryContext = new TestAttributeTestContextProvider(); - protected TestAttributeTestContextProvider DeviceContext = new TestAttributeTestContextProvider(); - protected TestAttributeTestContextProvider ExceptionInfoContext = new TestAttributeTestContextProvider(); - protected SystemAttributeContext SystemAttributeContext = new SystemAttributeContext(); - - /// - /// Any logs added by to the test runner can be added to Extent - /// - protected internal List TestRunnerLogs { get; private set; } = new List(); - - /// - /// A list of all started tests - /// - private List _testList = new List(); - - /// - /// A unique list of test status - /// - /// Consider a report having 5 tests: - /// - /// - /// Test 1: Pass - /// Test 2: Skip - /// Test 3: Pass - /// Test 4: Fail - /// Test 5: Fail - /// - /// - /// Distinct list of contained status: - /// - /// - /// Test 1: Pass - /// Test 2: Skip - /// Test 5: Fail - /// - /// - private List _statusList = new List(); - - /// - /// Contains status as keys, which are translated over to _statusList - /// - private Dictionary _statusMap = new Dictionary(); - - private readonly object _synclock = new object(); - private AnalysisStrategy _analysisStrategy = AnalysisStrategy.Test; - - protected internal ReportObservable() { } - - /// - /// Subscribe the reporter to receive updates - /// - /// - protected void Register(IExtentReporter reporter) - { - lock (_synclock) - { - reporter.Start(); - StarterReporterList.Add(reporter); - } - } - - protected void Deregister(IExtentReporter reporter) - { - lock (_synclock) - { - reporter.Stop(); - StarterReporterList.Remove(reporter); - } - } - - internal void SaveTest(Test test) - { - lock (_synclock) - { - _testList.Add(test); - StarterReporterList.ForEach(x => x.OnTestStarted(test)); - } - } - - internal void RemoveTest(Test test) - { - lock (_synclock) - { - RemoveTestTestList(test); - RemoveTestTestAttributeContext(test); - StarterReporterList.ForEach(x => x.OnTestRemoved(test)); - } - } - - private void RemoveTestTestList(Test test) - { - TestRemoveService.Remove(_testList, test); - RefreshReportEntities(); - } - - private void RemoveTestTestAttributeContext(Test test) - { - if (test.HasAuthor) - { - AuthorContext.RemoveTest(test); - } - if (test.HasCategory) - { - CategoryContext.RemoveTest(test); - } - if (test.HasDevice) - { - DeviceContext.RemoveTest(test); - } - if (test.HasException) - { - ExceptionInfoContext.RemoveTest(test); - } - } - - private void RefreshReportEntities() - { - RefreshReportStats(); - } - - private void RefreshReportStats() - { - ReportStatusStats.Refresh(_testList); - RefreshStatusList(); - } - - private void RefreshStatusList() - { - lock (_synclock) - { - _statusMap.Clear(); - _statusList.Clear(); - RefreshStatusList(_testList); - _statusMap.ToList().ForEach(x => _statusList.Add(x.Key)); - } - } - - private void RefreshStatusList(List testList) - { - lock (_synclock) - { - if (testList.IsNullOrEmpty()) - { - return; - } - - var distinctStatusList = testList.Select(x => x.Status).Distinct(); - - foreach (var s in distinctStatusList) - { - if (!_statusMap.ContainsKey(s)) - { - _statusMap.Add(s, false); - } - } - - // recursively, do the same for child tests - foreach (var test in testList.ToList()) - { - if (test.HasChildren) - { - RefreshStatusList(test.NodeContext.All().ToList()); - } - } - } - } - - internal void AddNode(Test node) - { - lock(_synclock) - { - StarterReporterList.ForEach(x => x.OnNodeStarted(node)); - } - } - - internal void AddLog(Test test, Log log) - { - lock (_synclock) - { - CollectRunInfo(); - StarterReporterList.ForEach(x => x.OnLogAdded(test, log)); - } - } - - private void CollectRunInfo() - { - lock (_synclock) - { - if (_testList.IsNullOrEmpty()) - return; - - ReportEndDateTime = DateTime.Now; - RefreshReportEntities(); - - foreach (var test in _testList) - { - EndTest(test); - CopyContextInfoToObservable(test); - } - } - } - - private void CopyContextInfoToObservable(Test test) - { - if (test.HasAuthor) - { - test.AuthorContext.All().ToList() - .ForEach(x => AuthorContext.AddAttributeContext((Author)x, test)); - } - if (test.HasCategory) - { - test.CategoryContext.All().ToList() - .ForEach(x => CategoryContext.AddAttributeContext((Category)x, test)); - } - if (test.HasDevice) - { - test.DeviceContext.All().ToList() - .ForEach(x => DeviceContext.AddAttributeContext((Device)x, test)); - } - if (test.HasException) - { - test.ExceptionInfoContext.All().ToList() - .ForEach(x => ExceptionInfoContext.AddAttributeContext((ExceptionInfo)x, test)); - } - if (test.HasChildren) - { - test.NodeContext.All().ToList() - .ForEach(x => CopyContextInfoToObservable(x)); - } - } - - private void EndTest(Test test) - { - lock (_synclock) - { - test.End(); - UpdateReportStatus(test.Status); - } - } - - internal void AssignAuthor(Test test, Author author) - { - StarterReporterList.ForEach(x => x.OnAuthorAssigned(test, author)); - } - - internal void AssignCategory(Test test, Category category) - { - StarterReporterList.ForEach(x => x.OnCategoryAssigned(test, category)); - } - - internal void AssignDevice(Test test, Device device) - { - StarterReporterList.ForEach(x => x.OnDeviceAssigned(test, device)); - } - - internal void AddScreenCapture(Test test, ScreenCapture screenCapture) - { - StarterReporterList.ForEach(x => x.OnScreenCaptureAdded(test, screenCapture)); - } - - internal void AddScreenCapture(Log log, ScreenCapture screenCapture) - { - StarterReporterList.ForEach(x => x.OnScreenCaptureAdded(log, screenCapture)); - } - - private void UpdateReportStatus(Status status) - { - var statusIndex = StatusHierarchy.GetStatusHierarchy().IndexOf(status); - var testStatusIndex = StatusHierarchy.GetStatusHierarchy().IndexOf(ReportStatus); - ReportStatus = statusIndex < testStatusIndex ? status : ReportStatus; - } - - protected void Flush() - { - lock (_synclock) - { - CollectRunInfo(); - NotifyReporters(); - } - } - - private void NotifyReporters() - { - if (_testList.IsNullOrEmpty()) - return; - - if (!_testList.IsNullOrEmpty() && _testList[0].IsBehaviorDrivenType) - AnalysisStrategy = AnalysisStrategy.BDD; - - lock (_synclock) - { - ReportStatusStats.Refresh(_testList); - var reportAggregates = new ReportAggregates - { - TestList = _testList, - StatusList = _statusList, - ReportStatusStats = this.ReportStatusStats, - AuthorContext = this.AuthorContext, - CategoryContext = this.CategoryContext, - DeviceContext = this.DeviceContext, - ExceptionInfoContext = this.ExceptionInfoContext, - TestRunnerLogs = this.TestRunnerLogs, - SystemAttributeContext = this.SystemAttributeContext - }; - - StarterReporterList.ForEach(x => { - x.AnalysisStrategy = AnalysisStrategy; - x.Flush(reportAggregates); - }); - } - } - - protected void End() - { - Flush(); - StarterReporterList.ForEach(x => x.Stop()); - StarterReporterList.Clear(); - } - - protected void AddSystemInfo(string name, string value) - { - var sa = new SystemAttribute(name, value); - AddSystemInfo(sa); - } - - protected void AddSystemInfo(SystemAttribute sa) - { - SystemAttributeContext.AddSystemAttribute(sa); - } - - protected void AddTestRunnerLogs(List logs) - { - TestRunnerLogs.AddRange(logs); - } - - protected void AddTestRunnerLogs(string log) - { - TestRunnerLogs.Add(log); - } - - protected void Reset() - { - _testList.Clear(); - _statusList.Clear(); - _statusMap.Clear(); - ReportStatus = Status.Pass; - ReportStatusStats = new ReportStatusStats(); - TestRunnerLogs.Clear(); - } - } -} diff --git a/extentreports-dotnet-core/Core/ReportStatusStats.cs b/extentreports-dotnet-core/Core/ReportStatusStats.cs deleted file mode 100644 index 795f5d2..0000000 --- a/extentreports-dotnet-core/Core/ReportStatusStats.cs +++ /dev/null @@ -1,478 +0,0 @@ -using AventStack.ExtentReports.Gherkin.Model; -using AventStack.ExtentReports.Model; - -using System.Collections.Generic; -using System.Linq; - -namespace AventStack.ExtentReports.Core -{ - public class ReportStatusStats - { - public int ParentCount - { - get - { - return ParentCountPass - + ParentCountFail - + ParentCountFatal - + ParentCountError - + ParentCountWarning - + ParentCountSkip; - } - private set => ParentCount = value; - } - public int ParentCountPass { get; private set; } - public int ParentCountFail { get; private set; } - public int ParentCountFatal { get; private set; } - public int ParentCountError { get; private set; } - public int ParentCountWarning { get; private set; } - public int ParentCountSkip { get; private set; } - public int ParentCountExceptions { get; private set; } - - public double ParentPercentagePass - { - get - { - var i = ParentCount > 0 ? (double)ParentCountPass / (double)ParentCount : 0; - return i * 100; - } - } - public double ParentPercentageFail - { - get - { - var i = ParentCount > 0 ? (double)(ParentCountFail + ParentCountFatal) / (double)ParentCount : 0; - return i * 100; - } - } - public double ParentPercentageSkip - { - get - { - var i = ParentCount > 0 ? (double)ParentCountSkip / (double)ParentCount : 0; - return i * 100; - } - } - public double ParentPercentageWarning - { - get - { - var i = ParentCount > 0 ? (double)ParentCountWarning / (double)ParentCount : 0; - return i * 100; - } - } - public double ParentPercentageOthers - { - get - { - var i = ParentCount > 0 ? (double)(ParentCountWarning + ParentCountError) / (double)ParentCount : 0; - return i * 100; - } - } - - public int ChildCount - { - get - { - return ChildCountPass - + ChildCountFail - + ChildCountFatal - + ChildCountError - + ChildCountWarning - + ChildCountSkip - + ChildCountInfo - + ChildCountDebug; - } - private set => ChildCount = value; - } - public int ChildCountPass { get; private set; } - public int ChildCountFail { get; private set; } - public int ChildCountFatal { get; private set; } - public int ChildCountError { get; private set; } - public int ChildCountWarning { get; private set; } - public int ChildCountSkip { get; private set; } - public int ChildCountInfo { get; private set; } - public int ChildCountDebug { get; private set; } - public int ChildCountExceptions { get; private set; } - - public double ChildPercentagePass - { - get - { - var i = ChildCount > 0 ? (double)ChildCountPass / (double)ChildCount : 0; - return i * 100; - } - } - public double ChildPercentageFail - { - get - { - var i = ChildCount > 0 ? (double)(ChildCountFail + ChildCountFatal) / (double)ChildCount : 0; - return i * 100; - } - } - public double ChildPercentageSkip - { - get - { - var i = ChildCount > 0 ? (double)ChildCountSkip / (double)ChildCount : 0; - return i * 100; - } - } - public double ChildPercentageWarning - { - get - { - var i = ChildCount > 0 ? (double)ChildCountWarning / (double)ChildCount : 0; - return i * 100; - } - } - public double ChildPercentageOthers - { - get - { - var i = ChildCount > 0 ? (double)(ChildCountWarning + ChildCountError) / (double)ChildCount : 0; - return i * 100; - } - } - - public int GrandChildCount - { - get - { - return GrandChildCountPass - + GrandChildCountFail - + GrandChildCountFatal - + GrandChildCountError - + GrandChildCountWarning - + GrandChildCountSkip - + GrandChildCountInfo - + GrandChildCountDebug; - } - private set => GrandChildCount = value; - } - public int GrandChildCountPass { get; private set; } - public int GrandChildCountFail { get; private set; } - public int GrandChildCountFatal { get; private set; } - public int GrandChildCountError { get; private set; } - public int GrandChildCountWarning { get; private set; } - public int GrandChildCountSkip { get; private set; } - public int GrandChildCountInfo { get; private set; } - public int GrandChildCountDebug { get; private set; } - public int GrandChildCountExceptions { get; private set; } - - public double GrandChildPercentagePass - { - get - { - var i = GrandChildCount > 0 ? (double)GrandChildCountPass / (double)GrandChildCount : 0; - return i * 100; - } - } - public double GrandChildPercentageFail - { - get - { - var i = GrandChildCount > 0 ? (double)(GrandChildCountFail + GrandChildCountFatal) / (double)GrandChildCount : 0; - return i * 100; - } - } - public double GrandChildPercentageSkip - { - get - { - var i = GrandChildCount > 0 ? (double)GrandChildCountSkip / (double)GrandChildCount : 0; - return i * 100; - } - } - public double GrandChildPercentageWarning - { - get - { - var i = GrandChildCount > 0 ? (double)GrandChildCountWarning / (double)GrandChildCount : 0; - return i * 100; - } - } - public double GrandChildPercentageOthers - { - get - { - var i = GrandChildCount > 0 ? (double)(GrandChildCountWarning + GrandChildCountError) / (double)GrandChildCount : 0; - return i * 100; - } - } - - private readonly AnalysisStrategy _strategy = AnalysisStrategy.Test; - private List _testList; - private readonly object _synclock = new object(); - - public ReportStatusStats() - { - } - - public ReportStatusStats(AnalysisStrategy strategy) : this() - { - _strategy = strategy; - } - - public void Refresh(List testList) - { - Reset(); - _testList = testList.ToList(); - RefreshStats(); - } - - private void Reset() - { - ParentCountPass = 0; - ParentCountFail = 0; - ParentCountFatal = 0; - ParentCountError = 0; - ParentCountWarning = 0; - ParentCountSkip = 0; - ParentCountExceptions = 0; - - ChildCountPass = 0; - ChildCountFail = 0; - ChildCountFatal = 0; - ChildCountError = 0; - ChildCountWarning = 0; - ChildCountSkip = 0; - ChildCountInfo = 0; - ChildCountDebug = 0; - ChildCountExceptions = 0; - - GrandChildCountPass = 0; - GrandChildCountFail = 0; - GrandChildCountFatal = 0; - GrandChildCountError = 0; - GrandChildCountWarning = 0; - GrandChildCountSkip = 0; - GrandChildCountInfo = 0; - GrandChildCountExceptions = 0; - } - - private void RefreshStats() - { - lock (_synclock) - { - _testList.ForEach(x => AddTestForStatusStatsUpdate(x)); - } - } - - private void AddTestForStatusStatsUpdate(Test test) - { - if (_strategy == AnalysisStrategy.BDD || test.IsBehaviorDrivenType || (test.HasChildren && test.NodeContext.FirstOrDefault().IsBehaviorDrivenType)) - { - UpdateGroupCountsBDD(test); - return; - } - - if (_strategy == AnalysisStrategy.Test || _strategy == AnalysisStrategy.Class) - { - UpdateGroupCountsTestStrategy(test); - return; - } - - throw new InvalidAnalysisStrategyException("No such strategy found: " + _strategy); - } - - private void UpdateGroupCountsBDD(Test test) - { - IncrementItemCountByStatus(ItemLevel.Parent, test.Status); - - if (test.HasChildren) - { - foreach (var child in test.NodeContext.All()) - { - if (child.BehaviorDrivenType == null) - { - throw new InvalidAnalysisStrategyException(child.Name + " is not a valid BDD test. " + - "This happens when using AnalysisStrategy.BDD without BDD-style tests or if the test was not marked " + - "with the appropriate BDD type."); - } - - if (child.BehaviorDrivenType.GetType() == typeof(Scenario)) - { - IncrementItemCountByStatus(ItemLevel.Child, child.Status); - } - - if (child.HasChildren) - { - foreach (var grandchild in child.NodeContext.All()) - { - if (grandchild.BehaviorDrivenType.GetType() == typeof(Scenario)) - { - IncrementItemCountByStatus(ItemLevel.Child, grandchild.Status); - grandchild.NodeContext.All() - .ForEach(x => IncrementItemCountByStatus(ItemLevel.GrandChild, x.Status)); - } - else - { - IncrementItemCountByStatus(ItemLevel.GrandChild, grandchild.Status); - } - } - } - else - { - IncrementItemCountByStatus(ItemLevel.GrandChild, child.Status); - } - } - } - } - - private void UpdateGroupCountsTestStrategy(Test test) - { - IncrementItemCountByStatus(ItemLevel.Parent, test.Status); - - if (test.HasChildren) - { - UpdateGroupCountsTestStrategyChildren(test); - } - } - - private void UpdateGroupCountsTestStrategyChildren(Test test) - { - if (test.HasChildren) - { - foreach (var node in test.NodeContext.All()) - { - if (node.HasChildren) - { - UpdateGroupCountsTestStrategyChildren(node); - } - else - { - IncrementItemCountByStatus(ItemLevel.Child, node.Status); - } - } - } - } - - enum ItemLevel - { - Parent, - Child, - GrandChild - } - - private void IncrementItemCountByStatus(ItemLevel item, Status status) - { - switch (item) - { - case ItemLevel.Parent: - IncrementParent(status); - break; - case ItemLevel.Child: - IncrementChild(status); - break; - case ItemLevel.GrandChild: - IncrementGrandChild(status); - break; - default: - break; - } - } - - private void IncrementParent(Status status) - { - switch (status) - { - case Status.Pass: - ParentCountPass++; - return; - case Status.Fail: - ParentCountFail++; - break; - case Status.Fatal: - ParentCountFatal++; - break; - case Status.Error: - ParentCountError++; - break; - case Status.Warning: - ParentCountWarning++; - break; - case Status.Skip: - ParentCountSkip++; - break; - default: - break; - } - - ParentCountExceptions++; - } - - private void IncrementChild(Status status) - { - switch (status) - { - case Status.Pass: - ChildCountPass++; - break; - case Status.Fail: - ChildCountFail++; - break; - case Status.Fatal: - ChildCountFatal++; - break; - case Status.Error: - ChildCountError++; - break; - case Status.Warning: - ChildCountWarning++; - break; - case Status.Skip: - ChildCountSkip++; - break; - case Status.Info: - ChildCountInfo++; - break; - case Status.Debug: - ChildCountDebug++; - break; - default: - break; - } - - if (status != Status.Pass && status != Status.Info) - ChildCountExceptions++; - } - - private void IncrementGrandChild(Status status) - { - switch (status) - { - case Status.Pass: - GrandChildCountPass++; - break; - case Status.Fail: - GrandChildCountFail++; - break; - case Status.Fatal: - GrandChildCountFatal++; - break; - case Status.Error: - GrandChildCountError++; - break; - case Status.Warning: - GrandChildCountWarning++; - break; - case Status.Skip: - GrandChildCountSkip++; - break; - case Status.Info: - GrandChildCountInfo++; - break; - case Status.Debug: - GrandChildCountDebug++; - break; - default: - break; - } - - if (status != Status.Pass && status != Status.Info) - GrandChildCountExceptions++; - } - } -} diff --git a/extentreports-dotnet-core/Core/StatusConfigurator.cs b/extentreports-dotnet-core/Core/StatusConfigurator.cs deleted file mode 100644 index 333b2ab..0000000 --- a/extentreports-dotnet-core/Core/StatusConfigurator.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace AventStack.ExtentReports.Core -{ - public class StatusConfigurator - { - private static readonly Lazy lazy = new Lazy(() => new StatusConfigurator()); - - public static StatusConfigurator I { get { return lazy.Value; } } - - private StatusConfigurator() - { - } - - public List StatusHierarchy - { - get - { - return Model.StatusHierarchy.GetStatusHierarchy(); - } - set - { - Model.StatusHierarchy.SetStatusHierarchy(value); - } - } - } -} \ No newline at end of file diff --git a/extentreports-dotnet-core/ExtentReports.cs b/extentreports-dotnet-core/ExtentReports.cs deleted file mode 100644 index ca13296..0000000 --- a/extentreports-dotnet-core/ExtentReports.cs +++ /dev/null @@ -1,156 +0,0 @@ -using AventStack.ExtentReports.Core; -using AventStack.ExtentReports.Gherkin; -using AventStack.ExtentReports.Gherkin.Model; - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace AventStack.ExtentReports -{ - public class ExtentReports : ReportObservable, IReportService - { - public ExtentReports() - { - } - - public List StartedReporterList - { - get - { - return base.StarterReporterList; - } - } - - public string GherkinDialect - { - get - { - if (string.IsNullOrEmpty(GherkinDialect)) - return GherkinDialectProvider.Language; - return GherkinDialect; - } - set - { - GherkinDialectProvider.Language = value; - } - } - - public new AnalysisStrategy AnalysisStrategy - { - get - { - return base.AnalysisStrategy; - } - set - { - base.AnalysisStrategy = value; - } - } - - public Status Status - { - get - { - return base.ReportStatus; - } - } - - public ReportStatusStats Stats - { - get - { - return ReportStatusStats; - } - } - - public ReportConfigurator Config - { - get - { - return ReportConfigurator.I; - } - } - - public void AttachReporter(params IExtentReporter[] reporter) - { - reporter.ToList().ForEach(x => Register(x)); - } - - public ExtentTest CreateTest(string name, string description = "") where T : IGherkinFormatterModel - { - Type type = typeof(T); - var obj = (IGherkinFormatterModel)Activator.CreateInstance(type); - - var test = new ExtentTest(this, obj, name, description); - base.SaveTest(test.Model); - - return test; - } - - public ExtentTest CreateTest(GherkinKeyword keyword, string name, string description = "") - { - var test = new ExtentTest(this, name, description); - test.Model.BehaviorDrivenType = keyword.Model; - base.SaveTest(test.Model); - return test; - } - - public ExtentTest CreateTest(string name, string description = "") - { - var test = new ExtentTest(this, name, description); - base.SaveTest(test.Model); - return test; - } - - public void RemoveTest(ExtentTest test) - { - base.RemoveTest(test.Model); - } - - public new void Flush() - { - base.Flush(); - } - - public new void AddSystemInfo(string name, string value) - { - base.AddSystemInfo(name, value); - } - - /// - /// Adds logs from test framework tools to the test-runner logs view (if available in the reporter) - /// - /// - public new void AddTestRunnerLogs(string log) - { - base.AddTestRunnerLogs(log); - } - - /// - /// Adds logs from test framework tools to the test-runner logs view (if available in the reporter) - /// - /// - public void AddTestRunnerLogs(string[] log) - { - base.AddTestRunnerLogs(log.ToList()); - } - - /// - /// Adds logs from test framework tools to the test-runner logs view (if available in the reporter) - /// - /// - public new void AddTestRunnerLogs(List log) - { - base.AddTestRunnerLogs(log); - } - - /// - /// Resets the current report session, and clears all logged information - /// - public void ResetSession() - { - base.Reset(); - } - } -} diff --git a/extentreports-dotnet-core/ExtentReports.csproj b/extentreports-dotnet-core/ExtentReports.csproj deleted file mode 100644 index b18eedc..0000000 --- a/extentreports-dotnet-core/ExtentReports.csproj +++ /dev/null @@ -1,148 +0,0 @@ - - - - netstandard2.0 - AventStack.ExtentReports - ExtentReports - 4.1.0 - AventStack - anshooarora - - Library - - true - https://cdn.rawgit.com/extent-framework/extent-github-cdn/d74480e/commons/img/logo.png - Extent Reporting Framework (.Net Standard), Community Edition - AventStack - https://raw.githubusercontent.com/extent-framework/extentreports-csharp/master/LICENSE - http://extentreports.com - https://github.com/extent-framework/extentreports-csharp - git - extentreports extent reporting - true - Update NewtonSoft.Json from 9.0.1 to 12.0.3 - - - - NU1603 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NU1605 - - - - - - True - True - GherkinLangs.resx - - - - - - ResXFileCodeGenerator - GherkinLangs.Designer.cs - - - - diff --git a/extentreports-dotnet-core/ExtentReports.csproj.user b/extentreports-dotnet-core/ExtentReports.csproj.user deleted file mode 100644 index 05cc1f0..0000000 --- a/extentreports-dotnet-core/ExtentReports.csproj.user +++ /dev/null @@ -1,9 +0,0 @@ - - - - ProjectDebugger - - - ExtentReports - - \ No newline at end of file diff --git a/extentreports-dotnet-core/Gherkin/GherkinDialect.cs b/extentreports-dotnet-core/Gherkin/GherkinDialect.cs deleted file mode 100644 index 733760b..0000000 --- a/extentreports-dotnet-core/Gherkin/GherkinDialect.cs +++ /dev/null @@ -1,61 +0,0 @@ -using AventStack.ExtentReports.Utils; - -using System; -using System.Linq; - -namespace AventStack.ExtentReports.Gherkin -{ - internal class GherkinDialect - { - public GherkinKeywords Keywords - { - get; private set; - } - - public string Language - { - get; private set; - } - - public GherkinDialect(string language, GherkinKeywords keywords) - { - Language = language; - Keywords = keywords; - } - - public string Match(string keyword) - { - if (Keywords.And.Contains(keyword, StringComparison.OrdinalIgnoreCase)) - return "And"; - - if (Keywords.Background.Contains(keyword, StringComparer.OrdinalIgnoreCase)) - return "Background"; - - if (Keywords.But.Contains(keyword, StringComparer.OrdinalIgnoreCase)) - return "But"; - - if (Keywords.Examples.Contains(keyword, StringComparer.OrdinalIgnoreCase)) - return "Examples"; - - if (Keywords.Feature.Contains(keyword, StringComparer.OrdinalIgnoreCase)) - return "Feature"; - - if (Keywords.Given.Contains(keyword, StringComparer.OrdinalIgnoreCase)) - return "Given"; - - if (Keywords.Scenario.Contains(keyword, StringComparer.OrdinalIgnoreCase)) - return "Scenario"; - - if (Keywords.ScenarioOutline.Contains(keyword, StringComparer.OrdinalIgnoreCase)) - return "ScenarioOutline"; - - if (Keywords.Then.Contains(keyword, StringComparer.OrdinalIgnoreCase)) - return "Then"; - - if (Keywords.When.Contains(keyword, StringComparer.OrdinalIgnoreCase)) - return "When"; - - return null; - } - } -} diff --git a/extentreports-dotnet-core/Gherkin/GherkinDialectProvider.cs b/extentreports-dotnet-core/Gherkin/GherkinDialectProvider.cs deleted file mode 100644 index 4719f65..0000000 --- a/extentreports-dotnet-core/Gherkin/GherkinDialectProvider.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Newtonsoft.Json; - -using System.Collections.Generic; - -namespace AventStack.ExtentReports.Gherkin -{ - internal static class GherkinDialectProvider - { - private static Dictionary _dialects; - private static GherkinKeywords _keywords; - private static string _dialect; - - static GherkinDialectProvider() - { - _dialect = DefaultDialect; - var json = Resources.GherkinLangs.Languages; - _dialects = JsonConvert.DeserializeObject>(json); - } - - public static string DefaultDialect { get; } = "en"; - - public static GherkinDialect Dialect { get; private set; } - - public static string Language - { - get - { - return _dialect; - } - set - { - _dialect = value; - - if (!_dialects.ContainsKey(_dialect)) - throw new InvalidGherkinLanguageException(_dialect + " is not a valid Gherkin dialect"); - - _keywords = _dialects[_dialect]; - Dialect = new GherkinDialect(_dialect, _keywords); - } - } - } -} diff --git a/extentreports-dotnet-core/Gherkin/GherkinKeywords.cs b/extentreports-dotnet-core/Gherkin/GherkinKeywords.cs deleted file mode 100644 index 7fed12d..0000000 --- a/extentreports-dotnet-core/Gherkin/GherkinKeywords.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace AventStack.ExtentReports.Gherkin -{ - internal class GherkinKeywords - { - public List And { get; set; } - public List Background { get; set; } - public List But { get; set; } - public List Examples { get; set; } - public List Feature { get; set; } - public List Given { get; set; } - public string Name { get; set; } - public string Native { get; set; } - public List Scenario { get; set; } - public List ScenarioOutline { get; set; } - public List Then { get; set; } - public List When { get; set; } - } -} diff --git a/extentreports-dotnet-core/GherkinKeyword.cs b/extentreports-dotnet-core/GherkinKeyword.cs deleted file mode 100644 index 05ce51b..0000000 --- a/extentreports-dotnet-core/GherkinKeyword.cs +++ /dev/null @@ -1,49 +0,0 @@ -using AventStack.ExtentReports.Core; -using AventStack.ExtentReports.Gherkin; -using AventStack.ExtentReports.Gherkin.Model; - -using System; -using System.Linq; -using System.Reflection; - -namespace AventStack.ExtentReports -{ - public class GherkinKeyword - { - public IGherkinFormatterModel Model { get; private set; } - - public GherkinKeyword(string keyword) - { - var type = typeof(IGherkinFormatterModel); - var language = GherkinDialectProvider.Language; - var dialect = GherkinDialectProvider.Dialect; - string apiKeyword = keyword.First().ToString().ToUpper() + keyword.Substring(1); - apiKeyword = apiKeyword.Equals("*") ? Asterisk.GherkinName : apiKeyword; - - try - { - if (!language.ToLower().Equals(GherkinDialectProvider.DefaultDialect)) - { - apiKeyword = null; - apiKeyword = dialect.Match(keyword); - } - - if (apiKeyword == null) - { - throw new GherkinKeywordNotFoundException("Keyword " + apiKeyword + " cannot be null"); - } - - var gherkinType = Assembly.GetExecutingAssembly().GetTypes() - .Where(p => p.Name.Equals(apiKeyword, StringComparison.CurrentCultureIgnoreCase)) - .First(); - - var obj = Activator.CreateInstance(gherkinType); - Model = (IGherkinFormatterModel)obj; - } - catch (InvalidOperationException e) - { - throw new InvalidOperationException("Invalid keyword specified: " + keyword, e); - } - } - } -} diff --git a/extentreports-dotnet-core/MarkupUtils/MarkupHelper.cs b/extentreports-dotnet-core/MarkupUtils/MarkupHelper.cs deleted file mode 100644 index 0f53c7a..0000000 --- a/extentreports-dotnet-core/MarkupUtils/MarkupHelper.cs +++ /dev/null @@ -1,54 +0,0 @@ -namespace AventStack.ExtentReports.MarkupUtils -{ - public class MarkupHelper - { - public static IMarkup CreateLabel(string text, ExtentColor color) - { - var label = new Label - { - Text = text, - Color = color - }; - return label; - } - - public static IMarkup CreateLabel(string text, ExtentColor color, ExtentColor textColor) - { - var label = new Label - { - Text = text, - Color = color, - TextColor = textColor - }; - return label; - } - - public static IMarkup CreateCodeBlock(string code, CodeLanguage lang = CodeLanguage.Xml) - { - var cb = new CodeBlock - { - Code = code, - CodeLang = lang - }; - return cb; - } - - public static IMarkup CreateTable(string[][] data) - { - var t = new Table - { - ArrayData = data - }; - return t; - } - - public static IMarkup CreateTable(string[,] data) - { - var t = new Table - { - Data = data - }; - return t; - } - } -} diff --git a/extentreports-dotnet-core/MarkupUtils/Table.cs b/extentreports-dotnet-core/MarkupUtils/Table.cs deleted file mode 100644 index 0b1779f..0000000 --- a/extentreports-dotnet-core/MarkupUtils/Table.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Text; - -namespace AventStack.ExtentReports.MarkupUtils -{ - internal class Table : IMarkup - { - public string[][] ArrayData { get; set; } - public string[,] Data { get; set; } - - public string GetMarkup() - { - var sb = new StringBuilder(); - sb.Append(""); - if (ArrayData != null) - { - for (int row = 0; row < ArrayData.Length; row++) - { - sb.Append(""); - for (int col = 0; col < ArrayData[row].Length; col++) - { - sb.Append(""); - } - sb.Append(""); - } - } - if (Data != null) - { - for (int row = 0; row < Data.GetLength(0); row++) - { - sb.Append(""); - for (int col = 0; col < Data.GetLength(1); col++) - { - sb.Append(""); - } - sb.Append(""); - } - } - sb.Append("
    " + ArrayData[row][col] + "
    " + Data[row,col] + "
    "); - return sb.ToString(); - } - } -} diff --git a/extentreports-dotnet-core/MediaEntityBuilder.cs b/extentreports-dotnet-core/MediaEntityBuilder.cs deleted file mode 100644 index 557274d..0000000 --- a/extentreports-dotnet-core/MediaEntityBuilder.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System.IO; -using System.Threading; - -using AventStack.ExtentReports.Model; - -namespace AventStack.ExtentReports -{ - public class MediaEntityBuilder - { - private static readonly MediaEntityBuilder _instance = new MediaEntityBuilder(); - private static ThreadLocal _media; - - public MediaEntityModelProvider Build() - { - return new MediaEntityModelProvider(_media.Value); - } - - /// - /// Adds a snapshot to the test or log with title - /// - /// Image path - /// Image title - /// A object - public static MediaEntityBuilder CreateScreenCaptureFromPath(string path, string title = null) - { - if (string.IsNullOrEmpty(path)) - throw new IOException("ScreenCapture path cannot be null or empty."); - - return CreateScreenCapture(path, title, false); - } - - /// - /// Adds a base64 snapshot to the test or log with title - /// - /// A Base64 string - /// Image title - /// A object - public static MediaEntityBuilder CreateScreenCaptureFromBase64String(string base64String, string title = null) - { - if (string.IsNullOrEmpty(base64String)) - throw new IOException("Base64 string cannot be null or empty."); - - return CreateScreenCapture(base64String, null, true); - } - - private static MediaEntityBuilder CreateScreenCapture(string pathOrBase64String, string title, bool isBase64) - { - var sc = new ScreenCapture - { - Title = title - }; - - if (isBase64) - sc.Base64String = pathOrBase64String; - else - sc.Path = pathOrBase64String; - - _media = new ThreadLocal - { - Value = sc - }; - - return _instance; - } - - } -} \ No newline at end of file diff --git a/extentreports-dotnet-core/MediaEntityModelProvider.cs b/extentreports-dotnet-core/MediaEntityModelProvider.cs deleted file mode 100644 index 446c30c..0000000 --- a/extentreports-dotnet-core/MediaEntityModelProvider.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AventStack.ExtentReports.Model; - -namespace AventStack.ExtentReports -{ - public class MediaEntityModelProvider - { - internal Media Media { get; private set; } - - internal MediaEntityModelProvider(Media media) - { - Media = media; - } - } -} diff --git a/extentreports-dotnet-core/MediaStorage/KlovHttpMediaManager.cs b/extentreports-dotnet-core/MediaStorage/KlovHttpMediaManager.cs deleted file mode 100644 index 8ad9ac0..0000000 --- a/extentreports-dotnet-core/MediaStorage/KlovHttpMediaManager.cs +++ /dev/null @@ -1,91 +0,0 @@ -using AventStack.ExtentReports.Model; - -using System; -using System.Collections.Generic; -using System.Globalization; -using System.IO; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Runtime.CompilerServices; - -namespace AventStack.ExtentReports.MediaStorage -{ - internal class KlovHttpMediaManager - { - private const string Route = "files/upload"; - - private string _host; - - public void Init(string host) - { - if (!host.Substring(host.Length - 1).Equals("/")) - { - host += "/"; - } - _host = host; - } - - [MethodImpl(MethodImplOptions.Synchronized)] - public void StoreMedia(Media m) - { - if (string.IsNullOrEmpty(m.Path) || !string.IsNullOrEmpty(m.Base64String)) - { - return; - } - - if (!File.Exists(m.Path)) - { - throw new IOException("The system cannot find the file specified " + m.Path); - } - - var uri = new Uri(_host); - var file = File.ReadAllBytes(m.Path); - var fileName = m.Sequence + Path.GetExtension(m.Path); - - using (var reader = new StreamReader(m.Path)) - { - using (var handler = new HttpClientHandler() { UseCookies = false }) - using (var client = new HttpClient(handler)) - { - client.BaseAddress = uri; - - client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); - client.DefaultRequestHeaders.Add("Accept", "application/json"); - client.DefaultRequestHeaders.Add("Connection", "keep-alive"); - client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0"); - - using (var content = new MultipartFormDataContent(DateTime.Now.ToString(CultureInfo.InvariantCulture))) - { - string logId = m.LogObjectId == null ? "" : m.LogObjectId.ToString(); - - var values = new[] - { - new KeyValuePair("name", m.Sequence + Path.GetExtension(m.Path)), - new KeyValuePair("id", m.ObjectId.ToString()), - new KeyValuePair("reportId", m.ReportObjectId.ToString()), - new KeyValuePair("testId", m.TestObjectId.ToString()), - new KeyValuePair("mediaType", "img"), - new KeyValuePair("logId", logId) - }; - - foreach (var keyValuePair in values) - { - content.Add(new StringContent(keyValuePair.Value), String.Format("\"{0}\"", keyValuePair.Key)); - } - - var imageContent = new ByteArrayContent(file); - content.Add(imageContent, "f", fileName); - - var result = client.PostAsync(_host + Route, content).Result; - - if (result.StatusCode != HttpStatusCode.OK) - { - throw new IOException("Unable to upload file to server: " + m.Path); - } - } - } - } - } - } -} diff --git a/extentreports-dotnet-core/Model/AbstractStructure.cs b/extentreports-dotnet-core/Model/AbstractStructure.cs deleted file mode 100644 index f2f309b..0000000 --- a/extentreports-dotnet-core/Model/AbstractStructure.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public class GenericStructure - { - private List _list - { - get - { - return _listv; - } - set - { - lock (_syncLock) - { - _listv = value; - } - } - } - private List _listv = new List(); - - private readonly object _syncLock = new object(); - - public bool IsEmpty - { - get - { - lock (_syncLock) - { - return Count == 0; - } - } - } - - public int Count - { - get - { - lock (_syncLock) - { - return _list == null ? 0 : _list.Count; - } - } - } - - public bool Contains(T t) - { - lock (_syncLock) - { - return _list.Contains(t); - } - } - - public void Add(T t) - { - lock (_syncLock) - { - _list.Add(t); - } - } - - public void Remove(T t) - { - lock (_syncLock) - { - _list.ToList().Remove(t); - } - } - - public T Get(int index) - { - lock (_syncLock) - { - return _list.ElementAt(index); - } - } - - public T FirstOrDefault() - { - lock (_syncLock) - { - return _list.Count == 0 ? default(T) : Get(0); - } - } - - public T LastOrDefault() - { - lock (_syncLock) - { - return _list.Count == 0 ? default(T) : Get(_list.Count - 1); - } - } - - public List All() - { - return _list; - } - - public TIterator GetEnumerator() - { - return new TIterator(_list); - } - } -} diff --git a/extentreports-dotnet-core/Model/Attribute.cs b/extentreports-dotnet-core/Model/Attribute.cs deleted file mode 100644 index 347eade..0000000 --- a/extentreports-dotnet-core/Model/Attribute.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public abstract class Attribute - { - public string Name { get; private set; } - public string Value { get; private set; } - - public Attribute(string name, string description) - { - Name = name; - Value = description; - } - - public Attribute(string name) : this(name, null) { } - } -} diff --git a/extentreports-dotnet-core/Model/Author.cs b/extentreports-dotnet-core/Model/Author.cs deleted file mode 100644 index 8658142..0000000 --- a/extentreports-dotnet-core/Model/Author.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public class Author : Attribute - { - public Author(string name) : base(name) { } - - public Author(string name, string description) : base(name, description) { } - } -} diff --git a/extentreports-dotnet-core/Model/BasicMongoReportElement.cs b/extentreports-dotnet-core/Model/BasicMongoReportElement.cs deleted file mode 100644 index 5dc41ef..0000000 --- a/extentreports-dotnet-core/Model/BasicMongoReportElement.cs +++ /dev/null @@ -1,9 +0,0 @@ -using MongoDB.Bson; - -namespace AventStack.ExtentReports.Model -{ - interface BasicMongoReportElement - { - ObjectId ObjectId { get; set; } - } -} diff --git a/extentreports-dotnet-core/Model/Category.cs b/extentreports-dotnet-core/Model/Category.cs deleted file mode 100644 index 3fb633a..0000000 --- a/extentreports-dotnet-core/Model/Category.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public class Category : Attribute - { - public Category(string name) : base(name) { } - - public Category(string name, string description) : base(name, description) { } - } -} diff --git a/extentreports-dotnet-core/Model/Context/SystemAttributeContext.cs b/extentreports-dotnet-core/Model/Context/SystemAttributeContext.cs deleted file mode 100644 index 4c51df5..0000000 --- a/extentreports-dotnet-core/Model/Context/SystemAttributeContext.cs +++ /dev/null @@ -1,34 +0,0 @@ -using AventStack.ExtentReports.Model; - -using System.Collections.Generic; - -namespace AventStack.ExtentReports.Model.Context -{ - public class SystemAttributeContext - { - public List SystemAttributeCollection { get; private set; } = new List(); - - public void AddSystemAttribute(SystemAttribute attr) - { - lock (_synclock) - { - SystemAttributeCollection.Add(attr); - } - } - - public int Count - { - get - { - return SystemAttributeCollection.Count; - } - } - - public void Clear() - { - SystemAttributeCollection.Clear(); - } - - private readonly object _synclock = new object(); - } -} diff --git a/extentreports-dotnet-core/Model/Context/TestAttributeTestContext.cs b/extentreports-dotnet-core/Model/Context/TestAttributeTestContext.cs deleted file mode 100644 index 4c1672a..0000000 --- a/extentreports-dotnet-core/Model/Context/TestAttributeTestContext.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace AventStack.ExtentReports.Model.Context -{ - [Serializable] - public class TestAttributeTestContext where T : Attribute - { - public T TestAttribute { get; private set; } - public List TestCollection { get; private set; } = new List(); - public string Name { get; private set; } - public int Passed { get; private set; } = 0; - public int Failed { get; private set; } = 0; - public int Skipped { get; private set; } = 0; - public int Others { get; private set; } = 0; - - public int Count - { - get - { - return TestCollection.Any() ? TestCollection.Count : 0; - } - } - - private readonly object _synclock = new object(); - - public TestAttributeTestContext(T testAttribute) - { - TestAttribute = testAttribute; - Name = testAttribute.Name; - } - - public void AddTest(Test test) - { - UpdateTestStatusCounts(test); - lock (_synclock) - { - TestCollection.Add(test); - } - } - - private void UpdateTestStatusCounts(Test test) - { - lock (_synclock) - { - Passed += test.Status == Status.Pass ? 1 : 0; - Failed += test.Status == Status.Fail || test.Status == Status.Fatal ? 1 : 0; - Skipped += test.Status == Status.Skip ? 1 : 0; - Others += test.Status != Status.Pass && test.Status != Status.Fail && test.Status != Status.Fatal && test.Status != Status.Skip ? 1 : 0; - } - } - - public void RefreshTestStatusCounts() - { - lock (_synclock) - { - Passed = Failed = Skipped = Others = 0; - } - TestCollection.ForEach(x => UpdateTestStatusCounts(x)); - } - } -} diff --git a/extentreports-dotnet-core/Model/Context/TestAttributeTestContextProvider.cs b/extentreports-dotnet-core/Model/Context/TestAttributeTestContextProvider.cs deleted file mode 100644 index ddc94d6..0000000 --- a/extentreports-dotnet-core/Model/Context/TestAttributeTestContextProvider.cs +++ /dev/null @@ -1,50 +0,0 @@ -using AventStack.ExtentReports.Core; - -using System.Collections.Generic; -using System.Linq; - -namespace AventStack.ExtentReports.Model.Context -{ - public class TestAttributeTestContextProvider where T : Attribute - { - public TestAttributeTestContextProvider() - { - Context = new List>(); - } - - public List> Context { get; } - - public void AddAttributeContext(T attrib, Test test) - { - var context = Context.Where(x => x.Name.Equals(attrib.Name)); - - if (context.Any()) - { - if (!context.First().TestCollection.Where(x => x.TestId == test.TestId).Any()) - { - context.First().TestCollection.Add(test); - } - context.First().RefreshTestStatusCounts(); - } - else - { - var testAttrTestContext = new TestAttributeTestContext(attrib); - testAttrTestContext.AddTest(test); - Context.Add(testAttrTestContext); - } - } - - public void RemoveTest(Test test) - { - for (int i = Context.Count - 1; i >= 0; i--) - { - var context = Context[i]; - TestRemoveService.Remove(context.TestCollection, test); - if (context.Count == 0) - { - Context.RemoveAt(i); - } - } - } - } -} diff --git a/extentreports-dotnet-core/Model/Device.cs b/extentreports-dotnet-core/Model/Device.cs deleted file mode 100644 index acb07bd..0000000 --- a/extentreports-dotnet-core/Model/Device.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public class Device : Attribute - { - public Device(string name) : base(name) { } - - public Device(string name, string description) : base(name, description) { } - } -} diff --git a/extentreports-dotnet-core/Model/Log.cs b/extentreports-dotnet-core/Model/Log.cs deleted file mode 100644 index 76a1054..0000000 --- a/extentreports-dotnet-core/Model/Log.cs +++ /dev/null @@ -1,59 +0,0 @@ -using AventStack.ExtentReports.Core; -using AventStack.ExtentReports.MarkupUtils; - -using MongoDB.Bson; - -using System; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public class Log : BasicMongoReportElement, IRunResult - { - public DateTime Timestamp { get => _timestamp; set => _timestamp = value; } - public Status Status { get; set; } - public ObjectId ObjectId { get => _objectId; set => _objectId = value; } - public Test Test { get; private set; } - public string Details { get; set; } = string.Empty; - public int Sequence = 0; - public IMarkup Markup { get; set; } - public ExceptionInfo ExceptionInfo { get; set; } - public GenericStructure ScreenCaptureContext; - - [NonSerialized] - private DateTime _timestamp = DateTime.Now; - [NonSerialized] - private ObjectId _objectId; - - public Log(Test test) - { - Test = test; - } - - public void AddScreenCapture(ScreenCapture screenCapture) - { - if (ScreenCaptureContext == null) - { - ScreenCaptureContext = new GenericStructure(); - } - ScreenCaptureContext.Add(screenCapture); - screenCapture.TestObjectId = Test.ObjectId; - } - - public bool HasException - { - get - { - return ExceptionInfo != null; - } - } - - public bool HasScreenCapture - { - get - { - return ScreenCaptureContext != null; - } - } - } -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Model/Media.cs b/extentreports-dotnet-core/Model/Media.cs deleted file mode 100644 index b3e2583..0000000 --- a/extentreports-dotnet-core/Model/Media.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.IO; -using System.Threading; - -using MongoDB.Bson; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public class Media - { - public ObjectId ObjectId { get; set; } - public ObjectId ReportObjectId { get; set; } - public ObjectId TestObjectId { get; set; } - public ObjectId LogObjectId { get; set; } - public long FileSize { get; set; } - public string Name { get; set; } - public string Description { get; set; } - public string Title { get; set; } = string.Empty; - public string Base64String { get; set; } - public int Sequence { get; private set; } = Interlocked.Increment(ref _seq); - - public string Path - { - get - { - return _path; - } - set - { - _path = value; - - Name = !string.IsNullOrEmpty(Name) ? Name : System.IO.Path.GetFileName(value); - if (File.Exists(value)) - { - FileSize = new FileInfo(value).Length; - } - } - } - - private static int _seq; - private string _path; - } -} diff --git a/extentreports-dotnet-core/Model/MediaType.cs b/extentreports-dotnet-core/Model/MediaType.cs deleted file mode 100644 index bec38de..0000000 --- a/extentreports-dotnet-core/Model/MediaType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AventStack.ExtentReports.Model -{ - public enum MediaType - { - Img - } -} diff --git a/extentreports-dotnet-core/Model/ScreenCapture.cs b/extentreports-dotnet-core/Model/ScreenCapture.cs deleted file mode 100644 index d129fd9..0000000 --- a/extentreports-dotnet-core/Model/ScreenCapture.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public class ScreenCapture : Media - { - private const string Base64StringDataType = "data:image/png;base64,"; - - public string Source - { - get - { - if (!string.IsNullOrEmpty(Base64String)) - { - return "base64-img"; - } - - return ""; - } - } - - public string SourceIcon - { - get - { - if (!string.IsNullOrEmpty(Base64String)) - { - return "base64-img"; - } - - return "" + - "img" + - ""; - } - } - - public string ScreenCapturePath - { - get - { - return !string.IsNullOrEmpty(base.Path) ? base.Path : Base64StringDataType + Base64String; - } - } - - public bool IsBase64 - { - get - { - return !string.IsNullOrEmpty(Base64String); - } - } - } -} diff --git a/extentreports-dotnet-core/Model/StatusHierarchy.cs b/extentreports-dotnet-core/Model/StatusHierarchy.cs deleted file mode 100644 index 6795874..0000000 --- a/extentreports-dotnet-core/Model/StatusHierarchy.cs +++ /dev/null @@ -1,45 +0,0 @@ -using AventStack.ExtentReports.Utils; - -using System.Collections.Generic; - -namespace AventStack.ExtentReports.Model -{ - internal static class StatusHierarchy - { - private static List _statusHierarchy = new List() { - Status.Fatal, - Status.Fail, - Status.Error, - Status.Warning, - Status.Skip, - Status.Pass, - Status.Info, - Status.Debug - }; - - public static List GetStatusHierarchy() - { - return _statusHierarchy; - } - - public static void SetStatusHierarchy(List statusHierarchy) - { - _statusHierarchy = statusHierarchy; - } - - public static Status GetHighestStatus(List list) - { - var highestStatus = Status.Pass; - if (list.IsNullOrEmpty()) - { - return highestStatus; - } - - foreach (var status in list) - { - highestStatus = GetStatusHierarchy().IndexOf(status) < GetStatusHierarchy().IndexOf(highestStatus)? status: highestStatus; - } - return highestStatus; - } - } -} diff --git a/extentreports-dotnet-core/Model/SystemAttribute.cs b/extentreports-dotnet-core/Model/SystemAttribute.cs deleted file mode 100644 index b9153b3..0000000 --- a/extentreports-dotnet-core/Model/SystemAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public class SystemAttribute : Attribute - { - public SystemAttribute(string name, string value) : base(name, value) - { - } - } -} diff --git a/extentreports-dotnet-core/Model/TIterator.cs b/extentreports-dotnet-core/Model/TIterator.cs deleted file mode 100644 index 8c2ec56..0000000 --- a/extentreports-dotnet-core/Model/TIterator.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public class TIterator : IEnumerable - { - private List _list; - - public TIterator(List list) - { - _list = list; - } - - public IEnumerator GetEnumerator() - { - for (int ix = 0; ix < _list.Count(); ix++) - { - yield return _list[ix]; - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - } -} diff --git a/extentreports-dotnet-core/Model/Test.cs b/extentreports-dotnet-core/Model/Test.cs deleted file mode 100644 index dfc2866..0000000 --- a/extentreports-dotnet-core/Model/Test.cs +++ /dev/null @@ -1,314 +0,0 @@ -using AventStack.ExtentReports.Core; -using AventStack.ExtentReports.Gherkin.Model; - -using MongoDB.Bson; - -using System; -using System.Linq; -using System.Threading; - -namespace AventStack.ExtentReports.Model -{ - [Serializable] - public class Test : BasicMongoReportElement, IRunResult - { - public string Name { get; set; } - public string Description { get; set; } = string.Empty; - public int TestId { get; } = Interlocked.Increment(ref _cntr); - public ObjectId ObjectId { get; set; } - public Status Status { get; set; } = Status.Pass; - public DateTime StartTime { get; set; } = DateTime.Now; - public DateTime EndTime { get; set; } = DateTime.Now; - public IGherkinFormatterModel BehaviorDrivenType { get; set; } - public ExtentReports Extent { get; set; } - public Test Parent { get; set; } - - public string BehaviorDrivenTypeName - { - get - { - return IsBehaviorDrivenType ? BehaviorDrivenType.ToString() : null; - } - } - - public int Level - { - get - { - return Parent == null ? 0 : Parent.Level + 1; - } - } - - public string HierarchicalName - { - get - { - var name = Name; - var parent = Parent; - while (parent != null) - { - name = parent.Name + "." + name; - parent = parent.Parent; - } - return name; - } - } - - public Test Root - { - get - { - var root = this; - while (root.Parent != null) - { - root = root.Parent; - } - return root; - } - } - - private static int _cntr; - private GenericStructure _logContext; - private GenericStructure _nodeContext; - private GenericStructure _authorContext; - private GenericStructure _categoryContext; - private GenericStructure _deviceContext; - private GenericStructure _exceptionInfoContext; - private GenericStructure _screenCaptureContext; - - private readonly object _syncLock = new object(); - - public bool IsChild - { - get - { - return Level > 0; - } - } - - public TimeSpan RunDuration - { - get - { - return EndTime.Subtract(StartTime); - } - } - - public GenericStructure NodeContext - { - get - { - if (_nodeContext == null) - _nodeContext = new GenericStructure(); - return _nodeContext; - } - } - - public bool HasChildren - { - get - { - return NodeContext != null && NodeContext.All() != null && NodeContext.Count > 0; - } - } - - public GenericStructure LogContext - { - get - { - if (_logContext == null) - _logContext = new GenericStructure(); - return _logContext; - } - } - - public bool HasLog - { - get - { - return LogContext != null && LogContext.All() != null && LogContext.Count > 0; - } - } - - public bool HasAttributes - { - get - { - return HasAuthor || HasCategory || HasDevice; - } - } - - public GenericStructure CategoryContext - { - get - { - if (_categoryContext == null) - _categoryContext = new GenericStructure(); - return _categoryContext; - } - } - - public bool HasCategory - { - get - { - return CategoryContext != null && CategoryContext.Count > 0; - } - } - - public GenericStructure ExceptionInfoContext - { - get - { - if (_exceptionInfoContext == null) - _exceptionInfoContext = new GenericStructure(); - return _exceptionInfoContext; - } - } - - public bool HasException - { - get - { - return ExceptionInfoContext != null && ExceptionInfoContext.Count > 0; - } - } - - public GenericStructure AuthorContext - { - get - { - if (_authorContext == null) - _authorContext = new GenericStructure(); - return _authorContext; - } - } - - public bool HasAuthor - { - get - { - return AuthorContext != null && AuthorContext.Count > 0; - } - } - - public GenericStructure DeviceContext - { - get - { - if (_deviceContext == null) - _deviceContext = new GenericStructure(); - return _deviceContext; - } - } - - public bool HasDevice - { - get - { - return DeviceContext != null && DeviceContext.Count > 0; - } - } - - public GenericStructure ScreenCaptureContext - { - get - { - if (_screenCaptureContext == null) - _screenCaptureContext = new GenericStructure(); - return _screenCaptureContext; - } - } - - public bool HasScreenCapture - { - get - { - return _screenCaptureContext != null && _screenCaptureContext.Count > 0; - } - } - - public bool IsBehaviorDrivenType - { - get - { - return BehaviorDrivenType != null; - } - } - - public void End() - { - UpdateTestStatusRecursive(this); - EndChildTestsRecursive(this); - lock (_syncLock) - { - Status = (Status == Status.Info || Status == Status.Debug) ? Status.Pass : Status; - } - SetEndTimeFromChildren(); - } - - private void SetEndTimeFromChildren() - { - if (HasChildren) - { - lock (_syncLock) - { - EndTime = NodeContext.LastOrDefault().EndTime; - } - } - else if (HasLog) - { - lock (_syncLock) - { - EndTime = LogContext.LastOrDefault().Timestamp; - } - } - } - - private void UpdateTestStatusRecursive(Test test) - { - if (test.HasLog) - { - test.LogContext.All().ToList().ForEach(x => UpdateStatus(x.Status)); - } - - if (test.HasChildren) - { - test.NodeContext.All().ToList().ForEach(x => UpdateTestStatusRecursive(x)); - } - - if (!test.IsBehaviorDrivenType) - { - bool hasNodeNotSkipped = test.NodeContext.All().Any(x => x.Status != Status.Skip); - if (this.Status == Status.Skip && hasNodeNotSkipped) - { - lock (_syncLock) - { - Status = Status.Pass; - } - test.NodeContext.All().ToList() - .FindAll(x => x.Status != Status.Skip) - .ForEach(x => UpdateTestStatusRecursive(x)); - } - } - } - - private void UpdateStatus(Status status) - { - var statusIndex = StatusHierarchy.GetStatusHierarchy().IndexOf(status); - var testStatusIndex = StatusHierarchy.GetStatusHierarchy().IndexOf(Status); - lock (_syncLock) - { - Status = statusIndex < testStatusIndex ? status : Status; - } - } - - private void EndChildTestsRecursive(Test test) - { - if (test.HasChildren) - { - test.NodeContext.All().ToList().ForEach(x => x.End()); - } - } - } -} diff --git a/extentreports-dotnet-core/Properties/launchSettings.json b/extentreports-dotnet-core/Properties/launchSettings.json deleted file mode 100644 index f840f8c..0000000 --- a/extentreports-dotnet-core/Properties/launchSettings.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "profiles": { - "ExtentReports": { - "commandName": "Project" - } - } -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Reporter/AbstractReporter.cs b/extentreports-dotnet-core/Reporter/AbstractReporter.cs deleted file mode 100644 index 396ab91..0000000 --- a/extentreports-dotnet-core/Reporter/AbstractReporter.cs +++ /dev/null @@ -1,38 +0,0 @@ -using AventStack.ExtentReports.Core; -using AventStack.ExtentReports.Model; - -namespace AventStack.ExtentReports.Reporter -{ - public abstract class AbstractReporter : IExtentReporter - { - public abstract string ReporterName { get; } - - public abstract AnalysisStrategy AnalysisStrategy { get; set; } - - public abstract ReportStatusStats ReportStatusStats { get; protected internal set; } - - public abstract void Flush(ReportAggregates reportAggregates); - - public abstract void OnAuthorAssigned(Test test, Author author); - - public abstract void OnCategoryAssigned(Test test, Category category); - - public abstract void OnDeviceAssigned(Test test, Device device); - - public abstract void OnLogAdded(Test test, Log log); - - public abstract void OnNodeStarted(Test node); - - public abstract void OnScreenCaptureAdded(Test test, ScreenCapture screenCapture); - - public abstract void OnScreenCaptureAdded(Log log, ScreenCapture screenCapture); - - public abstract void OnTestRemoved(Test test); - - public abstract void OnTestStarted(Test test); - - public abstract void Start(); - - public abstract void Stop(); - } -} diff --git a/extentreports-dotnet-core/Reporter/BasicFileReporter.cs b/extentreports-dotnet-core/Reporter/BasicFileReporter.cs deleted file mode 100644 index 5a33c3a..0000000 --- a/extentreports-dotnet-core/Reporter/BasicFileReporter.cs +++ /dev/null @@ -1,161 +0,0 @@ -using AventStack.ExtentReports.Configuration; -using AventStack.ExtentReports.Core; -using AventStack.ExtentReports.Model; -using AventStack.ExtentReports.Model.Context; -using AventStack.ExtentReports.Reporter.Configuration; - -using System; -using System.Collections.Generic; -using System.IO; - -namespace AventStack.ExtentReports.Reporter -{ - public abstract class BasicFileReporter : ConfigurableReporter - { - public override string ReporterName { get; } - - protected string SavePath { get; set; } - protected string FolderSavePath { get; set; } - - public override AnalysisStrategy AnalysisStrategy { get; set; } - - public override ReportStatusStats ReportStatusStats { get; protected internal set; } - - public DateTime StartTime { get; private set; } - - public DateTime EndTime { get; private set; } - - public List TestList { get; protected internal set; } - - public List StatusList { get; protected internal set; } - - public TestAttributeTestContextProvider AuthorContext { get; protected internal set; } - - public TestAttributeTestContextProvider CategoryContext { get; protected internal set; } - - public TestAttributeTestContextProvider DeviceContext { get; protected internal set; } - - public TestAttributeTestContextProvider ExceptionInfoContext { get; protected internal set; } - - public SystemAttributeContext SystemAttributeContext { get; protected internal set; } - - public List TestRunnerLogs { get; protected internal set; } - - protected BasicFileConfiguration Configuration { get; private set; } - - protected BasicFileReporter(string filePath) - { - SavePath = filePath; - FolderSavePath = Path.GetDirectoryName(filePath); - FolderSavePath = string.IsNullOrEmpty(FolderSavePath) ? "./" : FolderSavePath; - - if (!Directory.Exists(FolderSavePath)) - { - Directory.CreateDirectory(FolderSavePath); - } - } - - protected void Initialize(BasicFileConfiguration userConfig) - { - Configuration = userConfig; - /* - foreach (SettingsProperty setting in ExtentHtmlReporterSettings.Default.Properties) - { - var key = setting.Name; - var value = ExtentHtmlReporterSettings.Default.Properties[setting.Name].DefaultValue.ToString(); - - var c = new Config(key, value); - MasterConfig.AddConfig(c); - }*/ - } - - public override void Flush(ReportAggregates reportAggregates) - { - TestList = reportAggregates.TestList; - StatusList = reportAggregates.StatusList; - ReportStatusStats = reportAggregates.ReportStatusStats; - AuthorContext = reportAggregates.AuthorContext; - CategoryContext = reportAggregates.CategoryContext; - DeviceContext = reportAggregates.DeviceContext; - ExceptionInfoContext = reportAggregates.ExceptionInfoContext; - SystemAttributeContext = reportAggregates.SystemAttributeContext; - TestRunnerLogs = reportAggregates.TestRunnerLogs; - - EndTime = DateTime.Now; - - LoadUserConfig(); - } - - private void LoadUserConfig() - { - foreach (var pair in Configuration.UserConfigurationMap) - { - var key = pair.Key; - var value = pair.Value; - - var c = new Config(key, value); - MasterConfig.AddConfig(c); - } - } - - public override void OnAuthorAssigned(Test test, Author author) - { - - } - - public override void OnCategoryAssigned(Test test, Category category) - { - - } - - public override void OnDeviceAssigned(Test test, Device device) - { - - } - - public override void OnLogAdded(Test test, Log log) - { - - } - - public override void OnNodeStarted(Test node) - { - - } - - public override void OnScreenCaptureAdded(Test test, ScreenCapture screenCapture) - { - - } - - public override void OnScreenCaptureAdded(Log log, ScreenCapture screenCapture) - { - - } - - public override void OnTestRemoved(Test test) - { - - } - - public override void OnTestStarted(Test test) - { - - } - - public override void Start() - { - StartTime = DateTime.Now; - } - - public override void Stop() - { - - } - - public bool ContainsStatus(Status status) - { - return StatusList.Contains(status); - } - } -} diff --git a/extentreports-dotnet-core/Reporter/ConfigurableReporter.cs b/extentreports-dotnet-core/Reporter/ConfigurableReporter.cs deleted file mode 100644 index 3825c46..0000000 --- a/extentreports-dotnet-core/Reporter/ConfigurableReporter.cs +++ /dev/null @@ -1,39 +0,0 @@ -using AventStack.ExtentReports.Configuration; - -using System.IO; -using System.Linq; -using System.Xml.Linq; - -namespace AventStack.ExtentReports.Reporter -{ - public abstract class ConfigurableReporter : AbstractReporter - { - public ConfigurationManager MasterConfig { get; protected internal set; } = new ConfigurationManager(); - - public void LoadConfig(string filePath) - { - if (!File.Exists(filePath)) - throw new FileNotFoundException("The file " + filePath + " was not found."); - - var xdoc = XDocument.Load(filePath, LoadOptions.None); - if (xdoc == null) - { - throw new FileLoadException("Unable to configure report with the supplied configuration. Please check the input file and try again."); - } - - LoadConfigFileContents(xdoc); - } - - private void LoadConfigFileContents(XDocument xdoc) - { - foreach (var xe in xdoc.Descendants("configuration").First().Elements()) - { - var key = xe.Name.ToString(); - var value = xe.Value; - - var c = new Config(key, value); - MasterConfig.AddConfig(c); - } - } - } -} diff --git a/extentreports-dotnet-core/Reporter/Configuration/BasicConfiguration.cs b/extentreports-dotnet-core/Reporter/Configuration/BasicConfiguration.cs deleted file mode 100644 index 75e117f..0000000 --- a/extentreports-dotnet-core/Reporter/Configuration/BasicConfiguration.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Collections.Generic; - -namespace AventStack.ExtentReports.Reporter.Configuration -{ - public abstract class BasicConfiguration - { - public AbstractReporter Reporter { get; protected internal set; } - public Dictionary UserConfigurationMap = new Dictionary(); - - public string ReportName - { - get - { - return _reportName; - } - set - { - UserConfigurationMap["reportName"] = value; - _reportName = value; - } - } - - private string _reportName; - - protected BasicConfiguration(AbstractReporter reporter) - { - Reporter = reporter; - } - } -} diff --git a/extentreports-dotnet-core/Reporter/Configuration/BasicFileConfiguration.cs b/extentreports-dotnet-core/Reporter/Configuration/BasicFileConfiguration.cs deleted file mode 100644 index 8082a6b..0000000 --- a/extentreports-dotnet-core/Reporter/Configuration/BasicFileConfiguration.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace AventStack.ExtentReports.Reporter.Configuration -{ - public class BasicFileConfiguration : BasicConfiguration - { - public BasicFileConfiguration(AbstractReporter reporter) : base(reporter) - { - } - - public string Encoding - { - get - { - return _encoding; - } - set - { - _encoding = value; - UserConfigurationMap["encoding"] = _encoding; - } - } - - public string DocumentTitle - { - get - { - return _documentTitle; - } - set - { - _documentTitle = value; - UserConfigurationMap["documentTitle"] = _documentTitle; - } - } - - private string _encoding; - private string _documentTitle; - } -} diff --git a/extentreports-dotnet-core/Reporter/Configuration/ExtentHtmlReporterConfiguration.cs b/extentreports-dotnet-core/Reporter/Configuration/ExtentHtmlReporterConfiguration.cs deleted file mode 100644 index 1454f0e..0000000 --- a/extentreports-dotnet-core/Reporter/Configuration/ExtentHtmlReporterConfiguration.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AventStack.ExtentReports.Reporter.Configuration -{ - public class ExtentHtmlReporterConfiguration : RichViewReporterConfiguration - { - public ExtentHtmlReporterConfiguration(AbstractReporter reporter) : base(reporter) - { - } - } -} diff --git a/extentreports-dotnet-core/Reporter/Configuration/ExtentLoggerReporterConfiguration.cs b/extentreports-dotnet-core/Reporter/Configuration/ExtentLoggerReporterConfiguration.cs deleted file mode 100644 index 1f3be9c..0000000 --- a/extentreports-dotnet-core/Reporter/Configuration/ExtentLoggerReporterConfiguration.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AventStack.ExtentReports.Reporter.Configuration -{ - public class ExtentLoggerReporterConfiguration : RichViewReporterConfiguration - { - public ExtentLoggerReporterConfiguration(AbstractReporter reporter) : base(reporter) - { - } - } -} diff --git a/extentreports-dotnet-core/Reporter/Configuration/IReporterConfiguration.cs b/extentreports-dotnet-core/Reporter/Configuration/IReporterConfiguration.cs deleted file mode 100644 index f54f80d..0000000 --- a/extentreports-dotnet-core/Reporter/Configuration/IReporterConfiguration.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AventStack.ExtentReports.Reporter.Configuration -{ - public interface IReporterConfiguration - { - - } -} diff --git a/extentreports-dotnet-core/Reporter/Configuration/Protocol.cs b/extentreports-dotnet-core/Reporter/Configuration/Protocol.cs deleted file mode 100644 index bcc0d92..0000000 --- a/extentreports-dotnet-core/Reporter/Configuration/Protocol.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace AventStack.ExtentReports.Reporter.Configuration -{ - public enum Protocol - { - HTTP, - HTTPS - } -} diff --git a/extentreports-dotnet-core/Reporter/Configuration/RichViewReporterConfiguration.cs b/extentreports-dotnet-core/Reporter/Configuration/RichViewReporterConfiguration.cs deleted file mode 100644 index c54614e..0000000 --- a/extentreports-dotnet-core/Reporter/Configuration/RichViewReporterConfiguration.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; - -namespace AventStack.ExtentReports.Reporter.Configuration -{ - public class RichViewReporterConfiguration : BasicFileConfiguration - { - public RichViewReporterConfiguration(AbstractReporter reporter) : base(reporter) - { } - - public Theme Theme - { - get - { - return _theme; - } - set - { - _theme = value; - UserConfigurationMap["theme"] = Enum.GetName(typeof(Theme), _theme).ToLower(); - } - } - - public string CSS - { - get - { - return _css; - } - set - { - _css = value; - UserConfigurationMap["css"] = _css; - } - } - - public string JS - { - get - { - return _js; - } - set - { - _js = value; - UserConfigurationMap["js"] = _js; - } - } - - public Boolean EnableTimeline - { - get - { - return _enableTimeline; - } - set - { - _enableTimeline = value; - UserConfigurationMap["enableTimeline"] = value.ToString(); - } - } - - private Theme _theme; - private string _css; - private string _js; - private bool _enableTimeline; - } -} diff --git a/extentreports-dotnet-core/Reporter/Configuration/Theme.cs b/extentreports-dotnet-core/Reporter/Configuration/Theme.cs deleted file mode 100644 index 37e4060..0000000 --- a/extentreports-dotnet-core/Reporter/Configuration/Theme.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace AventStack.ExtentReports.Reporter.Configuration -{ - public enum Theme - { - Dark, - Standard - } -} diff --git a/extentreports-dotnet-core/Reporter/Configuration/ViewStyle.cs b/extentreports-dotnet-core/Reporter/Configuration/ViewStyle.cs deleted file mode 100644 index cf437d2..0000000 --- a/extentreports-dotnet-core/Reporter/Configuration/ViewStyle.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace AventStack.ExtentReports.Reporter.Configuration -{ - public enum ViewStyle - { - Default, - SPA - } -} diff --git a/extentreports-dotnet-core/Reporter/ExtentHtmlReporter.cs b/extentreports-dotnet-core/Reporter/ExtentHtmlReporter.cs deleted file mode 100644 index 29d03ac..0000000 --- a/extentreports-dotnet-core/Reporter/ExtentHtmlReporter.cs +++ /dev/null @@ -1,97 +0,0 @@ -using AventStack.ExtentReports.Core; -using AventStack.ExtentReports.Reporter.Configuration; -using AventStack.ExtentReports.Reporter.TemplateEngine; -using AventStack.ExtentReports.Views.Html; - -using RazorEngine.Templating; - -using System; -using System.IO; - -namespace AventStack.ExtentReports.Reporter -{ - public class ExtentHtmlReporter : BasicFileReporter - { - public new string ReporterName => "html"; - - private static readonly string TemplateFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views"); - private static readonly string HtmlTemplateFolderPath = Path.Combine(TemplateFolderPath, "Html"); - private ViewStyle _viewStyle = ViewStyle.SPA; - - public ExtentHtmlReporter(string folderPath) : base(folderPath) - { - Config = new ExtentHtmlReporterConfiguration(this); - Initialize(Config); - } - - public ExtentHtmlReporter(string folderPath, ViewStyle viewStyle) : this(folderPath) - { - _viewStyle = viewStyle; - } - - public ExtentHtmlReporterConfiguration Config { get; } - - public override void Flush(ReportAggregates reportAggregates) - { - base.Flush(reportAggregates); - - if (_viewStyle == ViewStyle.SPA) - { - var source = RazorEngineManager.Instance.Razor.RunCompile("SparkIndexSPA", typeof(ExtentHtmlReporter), this); - File.WriteAllText(Path.Combine(FolderSavePath, "index.html"), source); - } - else - { - var source = RazorEngineManager.Instance.Razor.RunCompile("Index", typeof(ExtentHtmlReporter), this); - File.WriteAllText(Path.Combine(FolderSavePath, "index.html"), source); - source = RazorEngineManager.Instance.Razor.RunCompile("Dashboard", typeof(ExtentHtmlReporter), this); - File.WriteAllText(Path.Combine(FolderSavePath, "dashboard.html"), source); - if (CategoryContext.Context.Count > 0) - { - source = RazorEngineManager.Instance.Razor.RunCompile("Tag", typeof(ExtentHtmlReporter), this); - File.WriteAllText(Path.Combine(FolderSavePath, "tag.html"), source); - } - if (ExceptionInfoContext.Context.Count > 0) - { - source = RazorEngineManager.Instance.Razor.RunCompile("Exception", typeof(ExtentHtmlReporter), this); - File.WriteAllText(Path.Combine(FolderSavePath, "exception.html"), source); - } - } - } - - public override void Start() - { - base.Start(); - AddTemplates(); - } - - private void AddTemplates() - { - string[] templates = new string[] - { - "Dashboard", - "Exception", - "Index", - "Tag", - "Partials.Attributes", - "Partials.AttributesView", - "Partials.Head", - "Partials.Log", - "Partials.Navbar", - "Partials.RecurseNodes", - "Partials.Scripts", - "Partials.Sidenav", - "Partials.SparkBDD", - "Partials.SparkStandard", - "Partials.SparkStepDetails", - "SparkIndexSPA", - "Partials.SparkTestSPA", - "Partials.SparkTagSPA", - "Partials.SparkExceptionSPA", - "Partials.SparkDashboardSPA" - }; - - TemplateLoadService.LoadTemplate(templates); - } - } -} diff --git a/extentreports-dotnet-core/Reporter/ExtentKlovReporter.cs b/extentreports-dotnet-core/Reporter/ExtentKlovReporter.cs deleted file mode 100644 index b8be1ec..0000000 --- a/extentreports-dotnet-core/Reporter/ExtentKlovReporter.cs +++ /dev/null @@ -1,451 +0,0 @@ -using AventStack.ExtentReports.Core; -using AventStack.ExtentReports.MediaStorage; -using AventStack.ExtentReports.Model; - -using MongoDB.Bson; -using MongoDB.Driver; - -using System; -using System.Collections.Generic; -using System.Linq; - -namespace AventStack.ExtentReports.Reporter -{ - public class ExtentKlovReporter : AbstractReporter - { - public override string ReporterName => "klov"; - - public override AnalysisStrategy AnalysisStrategy { get; set; } - - public override ReportStatusStats ReportStatusStats { get; protected internal set; } - - public string ReportName { get; set; } - public ObjectId ReportId { get; private set; } - public string ProjectName { get; set; } - public ObjectId ProjectId { get; private set; } - - private const string DefaultProjectName = "Default"; - private const string DefaultKlovServerName = "klov"; - private const string DatabaseName = "klov"; - - public ExtentKlovReporter() - { - _startTime = DateTime.Now; - } - - public ExtentKlovReporter(string projectName) : this(projectName, null) - {} - - public ExtentKlovReporter(string projectName, string reportName) : this() - { - ProjectName = string.IsNullOrEmpty(projectName) ? DefaultProjectName : projectName; - ReportName = string.IsNullOrEmpty(reportName) ? "Build " + DateTime.Now : reportName; - } - - /// - /// Connects to MongoDB default settings, localhost:27017 - /// - public void InitMongoDbConnection() - { - _mongoClient = new MongoClient(); - } - - public void InitMongoDbConnection(string host, int port = -1) - { - var conn = "mongodb://" + host; - conn += port > -1 ? ":" + port : ""; - _mongoClient = new MongoClient(conn); - } - - /// - /// Connects to MongoDB using a connection string. - /// Example: mongodb://host:27017,host2:27017/?replicaSet=rs0 - /// - /// - public void InitMongoDbConnection(string connectionString) - { - _mongoClient = new MongoClient(connectionString); - } - - public void InitMongoDbConnection(MongoClientSettings settings) - { - _mongoClient = new MongoClient(settings); - } - - public void InitKlovServerConnection(string url) - { - _url = url; - } - - public override void Start() - { - var db = _mongoClient.GetDatabase(DatabaseName); - InitializeCollections(db); - SetupProject(); - } - - private void InitializeCollections(IMongoDatabase db) - { - _projectCollection = db.GetCollection("project"); - _reportCollection = db.GetCollection("report"); - _testCollection = db.GetCollection("test"); - _logCollection = db.GetCollection("log"); - _exceptionCollection = db.GetCollection("exception"); - _mediaCollection = db.GetCollection("media"); - _categoryCollection = db.GetCollection("category"); - _authorCollection = db.GetCollection("author"); - _deviceCollection = db.GetCollection("device"); - _environmentCollection = db.GetCollection("environment"); - } - - private void SetupProject() - { - ProjectName = string.IsNullOrEmpty(ProjectName) ? DefaultProjectName : ProjectName; - var document = new BsonDocument - { - { "name", ProjectName } - }; - - var bsonProject = _projectCollection.Find(document).FirstOrDefault(); - if (bsonProject != null) - { - ProjectId = bsonProject["_id"].AsObjectId; - } - else - { - document.Add("createdAt", DateTime.Now); - _projectCollection.InsertOne(document); - ProjectId = document["_id"].AsObjectId; - } - - SetupReport(); - } - - private void SetupReport() - { - ReportName = string.IsNullOrEmpty(ReportName) ? "Build " + DateTime.Now : ReportName; - - var document = new BsonDocument - { - { "name", ReportName }, - { "project", ProjectId }, - { "projectName", ProjectName }, - { "startTime", DateTime.Now } - }; - - _reportCollection.InsertOne(document); - ReportId = document["_id"].AsObjectId; - } - - public override void Stop() { } - - public override void Flush(ReportAggregates reportAggregates) - { - if (reportAggregates.TestList == null || reportAggregates.TestList.Count == 0) - { - return; - } - this._reportAggregates = reportAggregates; - - var filter = Builders.Filter.Eq("_id", ReportId); - var update = Builders.Update - .Set("endTime", DateTime.Now) - .Set("duration", (DateTime.Now - _startTime).Milliseconds) - .Set("status", StatusHierarchy.GetHighestStatus(reportAggregates.StatusList).ToString().ToLower()) - .Set("parentLength", reportAggregates.ReportStatusStats.ParentCount) - .Set("passParentLength", reportAggregates.ReportStatusStats.ParentCountPass) - .Set("failParentLength", reportAggregates.ReportStatusStats.ParentCountFail) - .Set("fatalParentLength", reportAggregates.ReportStatusStats.ParentCountFatal) - .Set("errorParentLength", reportAggregates.ReportStatusStats.ParentCountError) - .Set("warningParentLength", reportAggregates.ReportStatusStats.ParentCountWarning) - .Set("skipParentLength", reportAggregates.ReportStatusStats.ParentCountSkip) - .Set("exceptionsParentLength", reportAggregates.ReportStatusStats.ParentCountExceptions) - .Set("childLength", reportAggregates.ReportStatusStats.ChildCount) - .Set("passChildLength", reportAggregates.ReportStatusStats.ChildCountPass) - .Set("failChildLength", reportAggregates.ReportStatusStats.ChildCountFail) - .Set("fatalChildLength", reportAggregates.ReportStatusStats.ChildCountFatal) - .Set("errorChildLength", reportAggregates.ReportStatusStats.ChildCountError) - .Set("warningChildLength", reportAggregates.ReportStatusStats.ChildCountWarning) - .Set("skipChildLength", reportAggregates.ReportStatusStats.ChildCountSkip) - .Set("infoChildLength", reportAggregates.ReportStatusStats.ChildCountInfo) - .Set("exceptionsChildLength", reportAggregates.ReportStatusStats.ChildCountExceptions) - .Set("grandChildLength", reportAggregates.ReportStatusStats.GrandChildCount) - .Set("passGrandChildLength", reportAggregates.ReportStatusStats.GrandChildCountPass) - .Set("failGrandChildLength", reportAggregates.ReportStatusStats.GrandChildCountFail) - .Set("fatalGrandChildLength", reportAggregates.ReportStatusStats.GrandChildCountFatal) - .Set("errorGrandChildLength", reportAggregates.ReportStatusStats.GrandChildCountError) - .Set("warningGrandChildLength", reportAggregates.ReportStatusStats.GrandChildCountWarning) - .Set("skipGrandChildLength", reportAggregates.ReportStatusStats.GrandChildCountSkip) - .Set("exceptionsGrandChildLength", reportAggregates.ReportStatusStats.GrandChildCountExceptions) - .Set("analysisStrategy", AnalysisStrategy.ToString().ToUpper()); - - _reportCollection.UpdateOne(filter, update); - InsertUpdateSystemAttribute(); - } - - private void InsertUpdateSystemAttribute() - { - List systemAttrList = _reportAggregates.SystemAttributeContext.SystemAttributeCollection; - - foreach (SystemAttribute sysAttr in systemAttrList) - { - var document = new BsonDocument - { - { "project", ProjectId }, - { "report", ReportId }, - { "name", sysAttr.Name } - }; - - BsonDocument envSingle = _environmentCollection.Find(document).FirstOrDefault(); - - if (envSingle == null) - { - document.Add("value", sysAttr.Value); - _environmentCollection.InsertOne(document); - } - else - { - ObjectId id = envSingle["_id"].AsObjectId; - - document = new BsonDocument - { - { "_id", id }, - { "value", sysAttr.Value } - }; - - _environmentCollection.UpdateOne( - new BsonDocument("_id", id), - new BsonDocument("$set", document)); - } - } - } - - public override void OnAuthorAssigned(Test test, Author author) - { - } - - public override void OnCategoryAssigned(Test test, Category category) - { - } - - public override void OnDeviceAssigned(Test test, Device device) - { - } - - public override void OnLogAdded(Test test, Log log) - { - var document = new BsonDocument - { - { "test", test.ObjectId }, - { "project", ProjectId }, - { "report", ReportId }, - { "testName", test.Name }, - { "sequence", log.Sequence }, - { "status", log.Status.ToString().ToLower() }, - { "timestamp", log.Timestamp }, - { "details", log.Details } - }; - - if (log.HasScreenCapture && log.ScreenCaptureContext.FirstOrDefault().IsBase64) - { - document["details"] = log.Details + log.ScreenCaptureContext.FirstOrDefault().Source; - } - - _logCollection.InsertOne(document); - - var id = document["_id"].AsObjectId; - log.ObjectId = id; - - if (test.HasException) - { - if (_exceptionNameObjectIdCollection == null) - _exceptionNameObjectIdCollection = new Dictionary(); - - var ex = test.ExceptionInfoContext.FirstOrDefault(); - - document = new BsonDocument - { - { "report", ReportId }, - { "project", ProjectId }, - { "name", ex.Name } - }; - - var findResult = _exceptionCollection.Find(document).FirstOrDefault(); - - if (!_exceptionNameObjectIdCollection.ContainsKey(ex.Name)) - { - if (findResult != null) - { - _exceptionNameObjectIdCollection.Add(ex.Name, findResult["_id"].AsObjectId); - } - else - { - document = new BsonDocument - { - { "project", ProjectId }, - { "report", ReportId }, - { "name", ex.Name }, - { "stacktrace", ((ExceptionInfo)ex).Exception.StackTrace }, - { "testCount", 0 } - }; - - _exceptionCollection.InsertOne(document); - - var exId = document["_id"].AsObjectId; - - document = new BsonDocument - { - { "_id", exId } - }; - findResult = _exceptionCollection.Find(document).FirstOrDefault(); - - _exceptionNameObjectIdCollection.Add(ex.Name, exId); - } - } - - var testCount = ((int)(findResult["testCount"])) + 1; - var filter = Builders.Filter.Eq("_id", findResult["_id"].AsObjectId); - var update = Builders.Update.Set("testCount", testCount); - _exceptionCollection.UpdateOne(filter, update); - - filter = Builders.Filter.Eq("_id", test.ObjectId); - update = Builders.Update.Set("exception", _exceptionNameObjectIdCollection[ex.Name]); - _testCollection.UpdateOne(filter, update); - } - - EndTestRecursive(test); - } - - private void EndTestRecursive(Test test) - { - var filter = Builders.Filter.Eq("_id", test.ObjectId); - var update = Builders.Update - .Set("status", test.Status.ToString().ToLower()) - .Set("endTime", test.EndTime) - .Set("duration", test.RunDuration.Milliseconds) - .Set("leaf", test.HasChildren) - .Set("childNodesLength", test.NodeContext.Count) - .Set("categorized", test.HasCategory) - .Set("description", test.Description); - - _testCollection.FindOneAndUpdate(filter, update); - - if (test.Level > 0) - { - EndTestRecursive(test.Parent); - } - } - - public override void OnScreenCaptureAdded(Test test, ScreenCapture screenCapture) - { - SaveScreenCapture(test, screenCapture); - } - - public override void OnScreenCaptureAdded(Log log, ScreenCapture screenCapture) - { - SaveScreenCapture(log, screenCapture); - } - - private void SaveScreenCapture(BasicMongoReportElement el, ScreenCapture screenCapture) - { - if (_mediaStorageHandler == null) - { - KlovMedia klovMedia = new KlovMedia() - { - ProjectId = ProjectId, - ReportId = ReportId, - MediaCollection = _mediaCollection - }; - _mediaStorageHandler = new KlovMediaStorageHandler(_url, klovMedia); - } - - _mediaStorageHandler.SaveScreenCapture(el, screenCapture); - } - - public override void OnTestRemoved(Test test) - { - } - - public override void OnTestStarted(Test test) - { - OnTestStartedHelper(test); - } - - public override void OnNodeStarted(Test node) - { - OnTestStartedHelper(node); - } - - private void OnTestStartedHelper(Test test) - { - var document = new BsonDocument - { - { "project", ProjectId }, - { "report", ReportId }, - { "reportName", ReportName }, - { "level", test.Level }, - { "name", test.Name }, - { "status", test.Status.ToString().ToLower() }, - { "description", test.Description }, - { "startTime", test.StartTime }, - { "endTime", test.EndTime }, - { "bdd", test.IsBehaviorDrivenType }, - { "leaf", test.HasChildren }, - { "childNodesLength", test.NodeContext.Count } - }; - - if (test.IsBehaviorDrivenType) - { - document.Add("bddType", test.BehaviorDrivenType.GetType().Name); - } - - if (test.Parent != null) - { - document.Add("parent", test.Parent.ObjectId); - document.Add("parentName", test.Parent.Name); - UpdateTestChildrenCount(test.Parent); - UpdateTestDescription(test.Parent); - } - - _testCollection.InsertOne(document); - test.ObjectId = document["_id"].AsObjectId; - } - - private void UpdateTestChildrenCount(Test test) - { - var filter = Builders.Filter.Eq("_id", test.ObjectId); - var update = Builders.Update - .Set("childNodesLength", test.NodeContext.Count); - _testCollection.FindOneAndUpdate(filter, update); - } - - private void UpdateTestDescription(Test test) - { - var filter = Builders.Filter.Eq("_id", test.ObjectId); - var update = Builders.Update - .Set("description", test.Description); - _testCollection.FindOneAndUpdate(filter, update); - } - - private string _url; - - private KlovMediaStorageHandler _mediaStorageHandler; - - private ReportAggregates _reportAggregates; - - private DateTime _startTime; - private MongoClient _mongoClient; - private IMongoCollection _projectCollection; - private IMongoCollection _reportCollection; - private IMongoCollection _testCollection; - private IMongoCollection _logCollection; - private IMongoCollection _exceptionCollection; - private IMongoCollection _mediaCollection; - private IMongoCollection _categoryCollection; - private IMongoCollection _authorCollection; - private IMongoCollection _deviceCollection; - private IMongoCollection _environmentCollection; - - private Dictionary _exceptionNameObjectIdCollection; - } -} diff --git a/extentreports-dotnet-core/Reporter/ExtentLoggerReporter.cs b/extentreports-dotnet-core/Reporter/ExtentLoggerReporter.cs deleted file mode 100644 index b7bdb14..0000000 --- a/extentreports-dotnet-core/Reporter/ExtentLoggerReporter.cs +++ /dev/null @@ -1,82 +0,0 @@ -using AventStack.ExtentReports.Core; -using AventStack.ExtentReports.Reporter.Configuration; -using AventStack.ExtentReports.Reporter.TemplateEngine; -using AventStack.ExtentReports.Views.Commons; -using AventStack.ExtentReports.Views.Logger; - -using RazorEngine.Templating; - -using System; -using System.IO; - -namespace AventStack.ExtentReports.Reporter -{ - [Obsolete("ExtentLoggerReporter has been deprecated and will be removed in a future release")] - public class ExtentLoggerReporter : BasicFileReporter - { - public new string ReporterName => "logger"; - - private static readonly string TemplateFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views"); - private static readonly string LoggerTemplateFolderPath = Path.Combine(TemplateFolderPath, "Logger"); - - public ExtentLoggerReporter(string folderPath) : base(folderPath) - { - Config = new ExtentLoggerReporterConfiguration(this); - Initialize(Config); - } - - public ExtentLoggerReporterConfiguration Config { get; } - - public override void Flush(ReportAggregates reportAggregates) - { - base.Flush(reportAggregates); - - var source = RazorEngineManager.Instance.Razor.RunCompile("LoggerTest", typeof(ExtentLoggerReporter), this); - File.WriteAllText(SavePath + "Index.html", source); - source = RazorEngineManager.Instance.Razor.RunCompile("CommonsDashboard", typeof(ExtentLoggerReporter), this); - File.WriteAllText(SavePath + "Dashboard.html", source); - if (CategoryContext.Context.Count > 0) - { - source = RazorEngineManager.Instance.Razor.RunCompile("CommonsTag", typeof(ExtentLoggerReporter), this); - File.WriteAllText(SavePath + "Tag.html", source); - } - if (ExceptionInfoContext.Context.Count > 0) - { - source = RazorEngineManager.Instance.Razor.RunCompile("CommonsException", typeof(ExtentLoggerReporter), this); - File.WriteAllText(SavePath + "Exception.html", source); - } - } - - public override void Start() - { - base.Start(); - AddTemplates(); - } - - private static void AddTemplates() - { - string[] templates = new string[] - { - "LoggerTest", - "LoggerMacro" - }; - TemplateLoadService.LoadTemplate(templates); - - templates = new string[] - { - "CommonsAttributes", - "CommonsDashboard", - "CommonsException", - "CommonsHead", - "CommonsInjectCss", - "CommonsInjectJs", - "CommonsMedia", - "CommonsNav", - "CommonsNavRight", - "CommonsRow", - "CommonsTag" - }; - TemplateLoadService.LoadTemplate(templates); - } - } -} diff --git a/extentreports-dotnet-core/Reporter/ExtentV3HtmlReporter.cs b/extentreports-dotnet-core/Reporter/ExtentV3HtmlReporter.cs deleted file mode 100644 index e7c0665..0000000 --- a/extentreports-dotnet-core/Reporter/ExtentV3HtmlReporter.cs +++ /dev/null @@ -1,65 +0,0 @@ -using AventStack.ExtentReports.Core; -using AventStack.ExtentReports.Views.V3Html; -using AventStack.ExtentReports.Reporter.Configuration; -using AventStack.ExtentReports.Reporter.TemplateEngine; - -using RazorEngine.Templating; - -using System; -using System.IO; - -namespace AventStack.ExtentReports.Reporter -{ - [Obsolete("ExtentV3HtmlReporter has been deprecated and will be removed in a future release")] - /// - /// The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options - /// via the Configuration() method. - /// - public class ExtentV3HtmlReporter : BasicFileReporter - { - public new string ReporterName => "html"; - - private static readonly string TemplateFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views"); - private static readonly string HtmlTemplateFolderPath = Path.Combine(TemplateFolderPath, "V3Html"); - - public ExtentV3HtmlReporter(string filePath) : base(filePath) - { - Config = new ExtentHtmlReporterConfiguration(this); - Initialize(Config); - } - - public ExtentHtmlReporterConfiguration Config { get; } - - public override void Flush(ReportAggregates reportAggregates) - { - base.Flush(reportAggregates); - var source = RazorEngineManager.Instance.Razor.RunCompile("V3Index", typeof(ExtentV3HtmlReporter), this); - File.WriteAllText(SavePath, source); - } - - public override void Start() - { - base.Start(); - AddTemplates(); - } - - private void AddTemplates() - { - string[] templates = new string[] - { - "V3Index", - "V3Head", - "V3Nav", - "Test.V3Test", - "Test.V3Charts", - "Author.V3Author", - "Category.V3Category", - "Dashboard.V3Dashboard", - "Exception.V3Exception", - "TestRunner.V3Logs" - }; - - TemplateLoadService.LoadTemplate(templates); - } - } -} diff --git a/extentreports-dotnet-core/Reporter/TemplateInfo.cs b/extentreports-dotnet-core/Reporter/TemplateInfo.cs deleted file mode 100644 index 680a605..0000000 --- a/extentreports-dotnet-core/Reporter/TemplateInfo.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace AventStack.ExtentReports.Reporter -{ - internal class TemplateInfo - { - public string Key { get; set; } - public string FileName { get; set; } - public string ResourceName { get; set; } - } -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Resources/GherkinLangs.Designer.cs b/extentreports-dotnet-core/Resources/GherkinLangs.Designer.cs deleted file mode 100644 index 3525285..0000000 --- a/extentreports-dotnet-core/Resources/GherkinLangs.Designer.cs +++ /dev/null @@ -1,104 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace AventStack.ExtentReports.Resources { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class GherkinLangs { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal GherkinLangs() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AventStack.ExtentReports.Resources.GherkinLangs", typeof(GherkinLangs).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to { - /// "af": { - /// "and": [ - /// "* ", - /// "En " - /// ], - /// "background": [ - /// "Agtergrond" - /// ], - /// "but": [ - /// "* ", - /// "Maar " - /// ], - /// "examples": [ - /// "Voorbeelde" - /// ], - /// "feature": [ - /// "Funksie", - /// "Besigheid Behoefte", - /// "Vermoë" - /// ], - /// "given": [ - /// "* ", - /// "Gegewe " - /// ], - /// "name": "Afrikaans", - /// "native": "Afrikaans", - /// "scenario": [ - /// "Situasie" - /// ], - /// "scenarioOutline": [ - /// "Situasie Uiteensetting" - /// [rest of string was truncated]";. - /// - internal static string Languages { - get { - return ResourceManager.GetString("Languages", resourceCulture); - } - } - } -} diff --git a/extentreports-dotnet-core/Resources/GherkinLangs.resx b/extentreports-dotnet-core/Resources/GherkinLangs.resx deleted file mode 100644 index e97f3fe..0000000 --- a/extentreports-dotnet-core/Resources/GherkinLangs.resx +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Languages.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 - - \ No newline at end of file diff --git a/extentreports-dotnet-core/Resources/Languages.txt b/extentreports-dotnet-core/Resources/Languages.txt deleted file mode 100644 index 00caa44..0000000 --- a/extentreports-dotnet-core/Resources/Languages.txt +++ /dev/null @@ -1,3191 +0,0 @@ -{ - "af": { - "and": [ - "* ", - "En " - ], - "background": [ - "Agtergrond" - ], - "but": [ - "* ", - "Maar " - ], - "examples": [ - "Voorbeelde" - ], - "feature": [ - "Funksie", - "Besigheid Behoefte", - "Vermo" - ], - "given": [ - "* ", - "Gegewe " - ], - "name": "Afrikaans", - "native": "Afrikaans", - "scenario": [ - "Situasie" - ], - "scenarioOutline": [ - "Situasie Uiteensetting" - ], - "then": [ - "* ", - "Dan " - ], - "when": [ - "* ", - "Wanneer " - ] - }, - "am": { - "and": [ - "* ", - "?? " - ], - "background": [ - "????????" - ], - "but": [ - "* ", - "???? " - ], - "examples": [ - "?????????" - ], - "feature": [ - "??????????????????", - "???????????" - ], - "given": [ - "* ", - "?????? " - ], - "name": "Armenian", - "native": "???????", - "scenario": [ - "??????" - ], - "scenarioOutline": [ - "??????? ???????????" - ], - "then": [ - "* ", - "??? " - ], - "when": [ - "* ", - "??? ", - "??? " - ] - }, - "ar": { - "and": [ - "* ", - "? " - ], - "background": [ - "???????" - ], - "but": [ - "* ", - "??? " - ], - "examples": [ - "?????" - ], - "feature": [ - "?????" - ], - "given": [ - "* ", - "???? " - ], - "name": "Arabic", - "native": "???????", - "scenario": [ - "???????" - ], - "scenarioOutline": [ - "??????? ????" - ], - "then": [ - "* ", - "???? ", - "?? " - ], - "when": [ - "* ", - "??? ", - "????? " - ] - }, - "ast": { - "and": [ - "* ", - "Y ", - "Ya " - ], - "background": [ - "Antecedentes" - ], - "but": [ - "* ", - "Peru " - ], - "examples": [ - "Exemplos" - ], - "feature": [ - "Carauterstica" - ], - "given": [ - "* ", - "Du ", - "Dada ", - "Daos ", - "Daes " - ], - "name": "Asturian", - "native": "asturianu", - "scenario": [ - "Casu" - ], - "scenarioOutline": [ - "Esbozu del casu" - ], - "then": [ - "* ", - "Ents " - ], - "when": [ - "* ", - "Cuando " - ] - }, - "az": { - "and": [ - "* ", - "V? ", - "H?m " - ], - "background": [ - "Kemis", - "Kontekst" - ], - "but": [ - "* ", - "Amma ", - "Ancaq " - ], - "examples": [ - "Nmun?l?r" - ], - "feature": [ - "z?llik" - ], - "given": [ - "* ", - "Tutaq ki ", - "Verilir " - ], - "name": "Azerbaijani", - "native": "Az?rbaycanca", - "scenario": [ - "Ssenari" - ], - "scenarioOutline": [ - "Ssenarinin strukturu" - ], - "then": [ - "* ", - "O halda " - ], - "when": [ - "* ", - "?g?r ", - "N? vaxt ki " - ] - }, - "bg": { - "and": [ - "* ", - "? " - ], - "background": [ - "???????????" - ], - "but": [ - "* ", - "?? " - ], - "examples": [ - "???????" - ], - "feature": [ - "??????????????" - ], - "given": [ - "* ", - "?????? " - ], - "name": "Bulgarian", - "native": "?????????", - "scenario": [ - "????????" - ], - "scenarioOutline": [ - "????? ?? ????????" - ], - "then": [ - "* ", - "?? " - ], - "when": [ - "* ", - "?????? " - ] - }, - "bm": { - "and": [ - "* ", - "Dan " - ], - "background": [ - "Latar Belakang" - ], - "but": [ - "* ", - "Tetapi ", - "Tapi " - ], - "examples": [ - "Contoh" - ], - "feature": [ - "Fungsi" - ], - "given": [ - "* ", - "Diberi ", - "Bagi " - ], - "name": "Malay", - "native": "Bahasa Melayu", - "scenario": [ - "Senario", - "Situasi", - "Keadaan" - ], - "scenarioOutline": [ - "Kerangka Senario", - "Kerangka Situasi", - "Kerangka Keadaan", - "Garis Panduan Senario" - ], - "then": [ - "* ", - "Maka ", - "Kemudian " - ], - "when": [ - "* ", - "Apabila " - ] - }, - "bs": { - "and": [ - "* ", - "I ", - "A " - ], - "background": [ - "Pozadina" - ], - "but": [ - "* ", - "Ali " - ], - "examples": [ - "Primjeri" - ], - "feature": [ - "Karakteristika" - ], - "given": [ - "* ", - "Dato " - ], - "name": "Bosnian", - "native": "Bosanski", - "scenario": [ - "Scenariju", - "Scenario" - ], - "scenarioOutline": [ - "Scenariju-obris", - "Scenario-outline" - ], - "then": [ - "* ", - "Zatim " - ], - "when": [ - "* ", - "Kada " - ] - }, - "ca": { - "and": [ - "* ", - "I " - ], - "background": [ - "Rerefons", - "Antecedents" - ], - "but": [ - "* ", - "Per " - ], - "examples": [ - "Exemples" - ], - "feature": [ - "Caracterstica", - "Funcionalitat" - ], - "given": [ - "* ", - "Donat ", - "Donada ", - "Ats ", - "Atesa " - ], - "name": "Catalan", - "native": "catal", - "scenario": [ - "Escenari" - ], - "scenarioOutline": [ - "Esquema de l'escenari" - ], - "then": [ - "* ", - "Aleshores ", - "Cal " - ], - "when": [ - "* ", - "Quan " - ] - }, - "cs": { - "and": [ - "* ", - "A tak ", - "A " - ], - "background": [ - "Pozad", - "Kontext" - ], - "but": [ - "* ", - "Ale " - ], - "examples": [ - "Prklady" - ], - "feature": [ - "Poadavek" - ], - "given": [ - "* ", - "Pokud ", - "Za predpokladu " - ], - "name": "Czech", - "native": "Cesky", - "scenario": [ - "Scnr" - ], - "scenarioOutline": [ - "Ncrt Scnre", - "Osnova scnre" - ], - "then": [ - "* ", - "Pak " - ], - "when": [ - "* ", - "Kdy " - ] - }, - "cy-GB": { - "and": [ - "* ", - "A " - ], - "background": [ - "Cefndir" - ], - "but": [ - "* ", - "Ond " - ], - "examples": [ - "Enghreifftiau" - ], - "feature": [ - "Arwedd" - ], - "given": [ - "* ", - "Anrhegedig a " - ], - "name": "Welsh", - "native": "Cymraeg", - "scenario": [ - "Scenario" - ], - "scenarioOutline": [ - "Scenario Amlinellol" - ], - "then": [ - "* ", - "Yna " - ], - "when": [ - "* ", - "Pryd " - ] - }, - "da": { - "and": [ - "* ", - "Og " - ], - "background": [ - "Baggrund" - ], - "but": [ - "* ", - "Men " - ], - "examples": [ - "Eksempler" - ], - "feature": [ - "Egenskab" - ], - "given": [ - "* ", - "Givet " - ], - "name": "Danish", - "native": "dansk", - "scenario": [ - "Scenarie" - ], - "scenarioOutline": [ - "Abstrakt Scenario" - ], - "then": [ - "* ", - "S " - ], - "when": [ - "* ", - "Nr " - ] - }, - "de": { - "and": [ - "* ", - "Und " - ], - "background": [ - "Grundlage" - ], - "but": [ - "* ", - "Aber " - ], - "examples": [ - "Beispiele" - ], - "feature": [ - "Funktionalitt" - ], - "given": [ - "* ", - "Angenommen ", - "Gegeben sei ", - "Gegeben seien " - ], - "name": "German", - "native": "Deutsch", - "scenario": [ - "Szenario" - ], - "scenarioOutline": [ - "Szenariogrundriss" - ], - "then": [ - "* ", - "Dann " - ], - "when": [ - "* ", - "Wenn " - ] - }, - "el": { - "and": [ - "* ", - "?a? " - ], - "background": [ - "?p?a???" - ], - "but": [ - "* ", - "???? " - ], - "examples": [ - "?a?ade??ata", - "Se????a" - ], - "feature": [ - "???at?t?ta", - "?e?t?????a" - ], - "given": [ - "* ", - "?ed????? " - ], - "name": "Greek", - "native": "????????", - "scenario": [ - "Se?????" - ], - "scenarioOutline": [ - "?e????af? Se?a????" - ], - "then": [ - "* ", - "??te " - ], - "when": [ - "* ", - "?ta? " - ] - }, - "em": { - "and": [ - "* ", - "??" - ], - "background": [ - "??" - ], - "but": [ - "* ", - "??" - ], - "examples": [ - "??" - ], - "feature": [ - "??" - ], - "given": [ - "* ", - "??" - ], - "name": "Emoji", - "native": "??", - "scenario": [ - "??" - ], - "scenarioOutline": [ - "??" - ], - "then": [ - "* ", - "??" - ], - "when": [ - "* ", - "??" - ] - }, - "en": { - "and": [ - "* ", - "And " - ], - "background": [ - "Background" - ], - "but": [ - "* ", - "But " - ], - "examples": [ - "Examples", - "Scenarios" - ], - "feature": [ - "Feature", - "Business Need", - "Ability" - ], - "given": [ - "* ", - "Given " - ], - "name": "English", - "native": "English", - "scenario": [ - "Scenario" - ], - "scenarioOutline": [ - "Scenario Outline", - "Scenario Template" - ], - "then": [ - "* ", - "Then " - ], - "when": [ - "* ", - "When " - ] - }, - "en-Scouse": { - "and": [ - "* ", - "An " - ], - "background": [ - "Dis is what went down" - ], - "but": [ - "* ", - "Buh " - ], - "examples": [ - "Examples" - ], - "feature": [ - "Feature" - ], - "given": [ - "* ", - "Givun ", - "Youse know when youse got " - ], - "name": "Scouse", - "native": "Scouse", - "scenario": [ - "The thing of it is" - ], - "scenarioOutline": [ - "Wharrimean is" - ], - "then": [ - "* ", - "Dun ", - "Den youse gotta " - ], - "when": [ - "* ", - "Wun ", - "Youse know like when " - ] - }, - "en-au": { - "and": [ - "* ", - "Too right " - ], - "background": [ - "First off" - ], - "but": [ - "* ", - "Yeah nah " - ], - "examples": [ - "You'll wanna" - ], - "feature": [ - "Pretty much" - ], - "given": [ - "* ", - "Y'know " - ], - "name": "Australian", - "native": "Australian", - "scenario": [ - "Awww, look mate" - ], - "scenarioOutline": [ - "Reckon it's like" - ], - "then": [ - "* ", - "But at the end of the day I reckon " - ], - "when": [ - "* ", - "It's just unbelievable " - ] - }, - "en-lol": { - "and": [ - "* ", - "AN " - ], - "background": [ - "B4" - ], - "but": [ - "* ", - "BUT " - ], - "examples": [ - "EXAMPLZ" - ], - "feature": [ - "OH HAI" - ], - "given": [ - "* ", - "I CAN HAZ " - ], - "name": "LOLCAT", - "native": "LOLCAT", - "scenario": [ - "MISHUN" - ], - "scenarioOutline": [ - "MISHUN SRSLY" - ], - "then": [ - "* ", - "DEN " - ], - "when": [ - "* ", - "WEN " - ] - }, - "en-old": { - "and": [ - "* ", - "Ond ", - "7 " - ], - "background": [ - "Aer", - "r" - ], - "but": [ - "* ", - "Ac " - ], - "examples": [ - "Se the", - "Se e", - "Se e" - ], - "feature": [ - "Hwaet", - "Hwt" - ], - "given": [ - "* ", - "Thurh ", - "urh ", - "urh " - ], - "name": "Old English", - "native": "Englisc", - "scenario": [ - "Swa" - ], - "scenarioOutline": [ - "Swa hwaer swa", - "Swa hwr swa" - ], - "then": [ - "* ", - "Tha ", - "a ", - "a ", - "Tha the ", - "a e ", - "a e " - ], - "when": [ - "* ", - "Tha ", - "a ", - "a " - ] - }, - "en-pirate": { - "and": [ - "* ", - "Aye " - ], - "background": [ - "Yo-ho-ho" - ], - "but": [ - "* ", - "Avast! " - ], - "examples": [ - "Dead men tell no tales" - ], - "feature": [ - "Ahoy matey!" - ], - "given": [ - "* ", - "Gangway! " - ], - "name": "Pirate", - "native": "Pirate", - "scenario": [ - "Heave to" - ], - "scenarioOutline": [ - "Shiver me timbers" - ], - "then": [ - "* ", - "Let go and haul " - ], - "when": [ - "* ", - "Blimey! " - ] - }, - "eo": { - "and": [ - "* ", - "Kaj " - ], - "background": [ - "Fono" - ], - "but": [ - "* ", - "Sed " - ], - "examples": [ - "Ekzemploj" - ], - "feature": [ - "Trajto" - ], - "given": [ - "* ", - "Donitajo ", - "Komence " - ], - "name": "Esperanto", - "native": "Esperanto", - "scenario": [ - "Scenaro", - "Kazo" - ], - "scenarioOutline": [ - "Konturo de la scenaro", - "Skizo", - "Kazo-skizo" - ], - "then": [ - "* ", - "Do " - ], - "when": [ - "* ", - "Se " - ] - }, - "es": { - "and": [ - "* ", - "Y ", - "E " - ], - "background": [ - "Antecedentes" - ], - "but": [ - "* ", - "Pero " - ], - "examples": [ - "Ejemplos" - ], - "feature": [ - "Caracterstica" - ], - "given": [ - "* ", - "Dado ", - "Dada ", - "Dados ", - "Dadas " - ], - "name": "Spanish", - "native": "espaol", - "scenario": [ - "Escenario" - ], - "scenarioOutline": [ - "Esquema del escenario" - ], - "then": [ - "* ", - "Entonces " - ], - "when": [ - "* ", - "Cuando " - ] - }, - "et": { - "and": [ - "* ", - "Ja " - ], - "background": [ - "Taust" - ], - "but": [ - "* ", - "Kuid " - ], - "examples": [ - "Juhtumid" - ], - "feature": [ - "Omadus" - ], - "given": [ - "* ", - "Eeldades " - ], - "name": "Estonian", - "native": "eesti keel", - "scenario": [ - "Stsenaarium" - ], - "scenarioOutline": [ - "Raamstsenaarium" - ], - "then": [ - "* ", - "Siis " - ], - "when": [ - "* ", - "Kui " - ] - }, - "fa": { - "and": [ - "* ", - "? " - ], - "background": [ - "?????" - ], - "but": [ - "* ", - "??? " - ], - "examples": [ - "????? ??" - ], - "feature": [ - "??????" - ], - "given": [ - "* ", - "?? ??? " - ], - "name": "Persian", - "native": "?????", - "scenario": [ - "??????" - ], - "scenarioOutline": [ - "????? ??????" - ], - "then": [ - "* ", - "????? " - ], - "when": [ - "* ", - "?????? " - ] - }, - "fi": { - "and": [ - "* ", - "Ja " - ], - "background": [ - "Tausta" - ], - "but": [ - "* ", - "Mutta " - ], - "examples": [ - "Tapaukset" - ], - "feature": [ - "Ominaisuus" - ], - "given": [ - "* ", - "Oletetaan " - ], - "name": "Finnish", - "native": "suomi", - "scenario": [ - "Tapaus" - ], - "scenarioOutline": [ - "Tapausaihio" - ], - "then": [ - "* ", - "Niin " - ], - "when": [ - "* ", - "Kun " - ] - }, - "fr": { - "and": [ - "* ", - "Et que ", - "Et qu'", - "Et " - ], - "background": [ - "Contexte" - ], - "but": [ - "* ", - "Mais que ", - "Mais qu'", - "Mais " - ], - "examples": [ - "Exemples" - ], - "feature": [ - "Fonctionnalit" - ], - "given": [ - "* ", - "Soit ", - "Etant donn que ", - "Etant donn qu'", - "Etant donn ", - "Etant donne ", - "Etant donns ", - "Etant donnes ", - "tant donn que ", - "tant donn qu'", - "tant donn ", - "tant donne ", - "tant donns ", - "tant donnes " - ], - "name": "French", - "native": "franais", - "scenario": [ - "Scnario" - ], - "scenarioOutline": [ - "Plan du scnario", - "Plan du Scnario" - ], - "then": [ - "* ", - "Alors " - ], - "when": [ - "* ", - "Quand ", - "Lorsque ", - "Lorsqu'" - ] - }, - "ga": { - "and": [ - "* ", - "Agus" - ], - "background": [ - "Clra" - ], - "but": [ - "* ", - "Ach" - ], - "examples": [ - "Sampla" - ], - "feature": [ - "Gn" - ], - "given": [ - "* ", - "Cuir i gcs go", - "Cuir i gcs nach", - "Cuir i gcs gur", - "Cuir i gcs nr" - ], - "name": "Irish", - "native": "Gaeilge", - "scenario": [ - "Cs" - ], - "scenarioOutline": [ - "Cs Achomair" - ], - "then": [ - "* ", - "Ansin" - ], - "when": [ - "* ", - "Nuair a", - "Nuair nach", - "Nuair ba", - "Nuair nr" - ] - }, - "gj": { - "and": [ - "* ", - "??? " - ], - "background": [ - "???????????" - ], - "but": [ - "* ", - "?? " - ], - "examples": [ - "???????" - ], - "feature": [ - "?????", - "??????? ????", - "??????" - ], - "given": [ - "* ", - "???? ?? " - ], - "name": "Gujarati", - "native": "???????", - "scenario": [ - "??????" - ], - "scenarioOutline": [ - "????????? ???????", - "????????? ?????" - ], - "then": [ - "* ", - "??? " - ], - "when": [ - "* ", - "?????? " - ] - }, - "gl": { - "and": [ - "* ", - "E " - ], - "background": [ - "Contexto" - ], - "but": [ - "* ", - "Mais ", - "Pero " - ], - "examples": [ - "Exemplos" - ], - "feature": [ - "Caracterstica" - ], - "given": [ - "* ", - "Dado ", - "Dada ", - "Dados ", - "Dadas " - ], - "name": "Galician", - "native": "galego", - "scenario": [ - "Escenario" - ], - "scenarioOutline": [ - "Esbozo do escenario" - ], - "then": [ - "* ", - "Entn ", - "Logo " - ], - "when": [ - "* ", - "Cando " - ] - }, - "he": { - "and": [ - "* ", - "??? " - ], - "background": [ - "???" - ], - "but": [ - "* ", - "??? " - ], - "examples": [ - "???????" - ], - "feature": [ - "?????" - ], - "given": [ - "* ", - "?????? " - ], - "name": "Hebrew", - "native": "?????", - "scenario": [ - "?????" - ], - "scenarioOutline": [ - "????? ?????" - ], - "then": [ - "* ", - "?? ", - "??? " - ], - "when": [ - "* ", - "???? " - ] - }, - "hi": { - "and": [ - "* ", - "?? ", - "??? " - ], - "background": [ - "?????????" - ], - "but": [ - "* ", - "?? ", - "?????? ", - "?????? " - ], - "examples": [ - "??????" - ], - "feature": [ - "??? ???" - ], - "given": [ - "* ", - "??? ", - "??? ", - "????? " - ], - "name": "Hindi", - "native": "?????", - "scenario": [ - "????????" - ], - "scenarioOutline": [ - "???????? ???????" - ], - "then": [ - "* ", - "?? ", - "??? " - ], - "when": [ - "* ", - "?? ", - "??? " - ] - }, - "hr": { - "and": [ - "* ", - "I " - ], - "background": [ - "Pozadina" - ], - "but": [ - "* ", - "Ali " - ], - "examples": [ - "Primjeri", - "Scenariji" - ], - "feature": [ - "Osobina", - "Mogucnost", - "Mogucnost" - ], - "given": [ - "* ", - "Zadan ", - "Zadani ", - "Zadano " - ], - "name": "Croatian", - "native": "hrvatski", - "scenario": [ - "Scenarij" - ], - "scenarioOutline": [ - "Skica", - "Koncept" - ], - "then": [ - "* ", - "Onda " - ], - "when": [ - "* ", - "Kada ", - "Kad " - ] - }, - "ht": { - "and": [ - "* ", - "Ak ", - "Epi ", - "E " - ], - "background": [ - "Kontks", - "Istorik" - ], - "but": [ - "* ", - "Men " - ], - "examples": [ - "Egzanp" - ], - "feature": [ - "Karakteristik", - "Mak", - "Fonksyonalite" - ], - "given": [ - "* ", - "Sipoze ", - "Sipoze ke ", - "Sipoze Ke " - ], - "name": "Creole", - "native": "kreyl", - "scenario": [ - "Senaryo" - ], - "scenarioOutline": [ - "Plan senaryo", - "Plan Senaryo", - "Senaryo deskripsyon", - "Senaryo Deskripsyon", - "Dyagram senaryo", - "Dyagram Senaryo" - ], - "then": [ - "* ", - "L sa a ", - "Le sa a " - ], - "when": [ - "* ", - "L ", - "Le " - ] - }, - "hu": { - "and": [ - "* ", - "s " - ], - "background": [ - "Httr" - ], - "but": [ - "* ", - "De " - ], - "examples": [ - "Pldk" - ], - "feature": [ - "Jellemzo" - ], - "given": [ - "* ", - "Amennyiben ", - "Adott " - ], - "name": "Hungarian", - "native": "magyar", - "scenario": [ - "Forgatknyv" - ], - "scenarioOutline": [ - "Forgatknyv vzlat" - ], - "then": [ - "* ", - "Akkor " - ], - "when": [ - "* ", - "Majd ", - "Ha ", - "Amikor " - ] - }, - "id": { - "and": [ - "* ", - "Dan " - ], - "background": [ - "Dasar" - ], - "but": [ - "* ", - "Tapi " - ], - "examples": [ - "Contoh" - ], - "feature": [ - "Fitur" - ], - "given": [ - "* ", - "Dengan " - ], - "name": "Indonesian", - "native": "Bahasa Indonesia", - "scenario": [ - "Skenario" - ], - "scenarioOutline": [ - "Skenario konsep" - ], - "then": [ - "* ", - "Maka " - ], - "when": [ - "* ", - "Ketika " - ] - }, - "is": { - "and": [ - "* ", - "Og " - ], - "background": [ - "Bakgrunnur" - ], - "but": [ - "* ", - "En " - ], - "examples": [ - "Dmi", - "Atburarsir" - ], - "feature": [ - "Eiginleiki" - ], - "given": [ - "* ", - "Ef " - ], - "name": "Icelandic", - "native": "slenska", - "scenario": [ - "Atburars" - ], - "scenarioOutline": [ - "Lsing Atburarsar", - "Lsing Dma" - ], - "then": [ - "* ", - " " - ], - "when": [ - "* ", - "egar " - ] - }, - "it": { - "and": [ - "* ", - "E " - ], - "background": [ - "Contesto" - ], - "but": [ - "* ", - "Ma " - ], - "examples": [ - "Esempi" - ], - "feature": [ - "Funzionalit" - ], - "given": [ - "* ", - "Dato ", - "Data ", - "Dati ", - "Date " - ], - "name": "Italian", - "native": "italiano", - "scenario": [ - "Scenario" - ], - "scenarioOutline": [ - "Schema dello scenario" - ], - "then": [ - "* ", - "Allora " - ], - "when": [ - "* ", - "Quando " - ] - }, - "ja": { - "and": [ - "* ", - "??" - ], - "background": [ - "??" - ], - "but": [ - "* ", - "???", - "??", - "???" - ], - "examples": [ - "?", - "????" - ], - "feature": [ - "?????", - "??" - ], - "given": [ - "* ", - "??" - ], - "name": "Japanese", - "native": "???", - "scenario": [ - "????" - ], - "scenarioOutline": [ - "??????????", - "??????????", - "????", - "????????" - ], - "then": [ - "* ", - "???" - ], - "when": [ - "* ", - "??" - ] - }, - "jv": { - "and": [ - "* ", - "Lan " - ], - "background": [ - "Dasar" - ], - "but": [ - "* ", - "Tapi ", - "Nanging ", - "Ananging " - ], - "examples": [ - "Conto", - "Contone" - ], - "feature": [ - "Fitur" - ], - "given": [ - "* ", - "Nalika ", - "Nalikaning " - ], - "name": "Javanese", - "native": "Basa Jawa", - "scenario": [ - "Skenario" - ], - "scenarioOutline": [ - "Konsep skenario" - ], - "then": [ - "* ", - "Njuk ", - "Banjur " - ], - "when": [ - "* ", - "Manawa ", - "Menawa " - ] - }, - "ka": { - "and": [ - "* ", - "??" - ], - "background": [ - "?????????" - ], - "but": [ - "* ", - "??????" - ], - "examples": [ - "??????????" - ], - "feature": [ - "???????" - ], - "given": [ - "* ", - "????????" - ], - "name": "Georgian", - "native": "????????", - "scenario": [ - "????????" - ], - "scenarioOutline": [ - "???????? ??????" - ], - "then": [ - "* ", - "?????" - ], - "when": [ - "* ", - "???????" - ] - }, - "kn": { - "and": [ - "* ", - "????? " - ], - "background": [ - "????????" - ], - "but": [ - "* ", - "???? " - ], - "examples": [ - "??????????" - ], - "feature": [ - "??????" - ], - "given": [ - "* ", - "?????? " - ], - "name": "Kannada", - "native": "?????", - "scenario": [ - "?????????" - ], - "scenarioOutline": [ - "??????" - ], - "then": [ - "* ", - "???? " - ], - "when": [ - "* ", - "??????????? " - ] - }, - "ko": { - "and": [ - "* ", - "???" - ], - "background": [ - "??" - ], - "but": [ - "* ", - "???", - "?" - ], - "examples": [ - "?" - ], - "feature": [ - "??" - ], - "given": [ - "* ", - "??", - "??" - ], - "name": "Korean", - "native": "???", - "scenario": [ - "????" - ], - "scenarioOutline": [ - "???? ??" - ], - "then": [ - "* ", - "???" - ], - "when": [ - "* ", - "??", - "??" - ] - }, - "lt": { - "and": [ - "* ", - "Ir " - ], - "background": [ - "Kontekstas" - ], - "but": [ - "* ", - "Bet " - ], - "examples": [ - "Pavyzdiai", - "Scenarijai", - "Variantai" - ], - "feature": [ - "Savybe" - ], - "given": [ - "* ", - "Duota " - ], - "name": "Lithuanian", - "native": "lietuviu kalba", - "scenario": [ - "Scenarijus" - ], - "scenarioOutline": [ - "Scenarijaus ablonas" - ], - "then": [ - "* ", - "Tada " - ], - "when": [ - "* ", - "Kai " - ] - }, - "lu": { - "and": [ - "* ", - "an ", - "a " - ], - "background": [ - "Hannergrond" - ], - "but": [ - "* ", - "awer ", - "m " - ], - "examples": [ - "Beispiller" - ], - "feature": [ - "Funktionalitit" - ], - "given": [ - "* ", - "ugeholl " - ], - "name": "Luxemburgish", - "native": "Ltzebuergesch", - "scenario": [ - "Szenario" - ], - "scenarioOutline": [ - "Plang vum Szenario" - ], - "then": [ - "* ", - "dann " - ], - "when": [ - "* ", - "wann " - ] - }, - "lv": { - "and": [ - "* ", - "Un " - ], - "background": [ - "Konteksts", - "Situacija" - ], - "but": [ - "* ", - "Bet " - ], - "examples": [ - "Piemeri", - "Paraugs" - ], - "feature": [ - "Funkcionalitate", - "Fica" - ], - "given": [ - "* ", - "Kad " - ], - "name": "Latvian", - "native": "latvieu", - "scenario": [ - "Scenarijs" - ], - "scenarioOutline": [ - "Scenarijs pec parauga" - ], - "then": [ - "* ", - "Tad " - ], - "when": [ - "* ", - "Ja " - ] - }, - "mk-Cyrl": { - "and": [ - "* ", - "? " - ], - "background": [ - "????????", - "????????" - ], - "but": [ - "* ", - "?? " - ], - "examples": [ - "???????", - "?????????" - ], - "feature": [ - "??????????????", - "?????? ???????", - "???????" - ], - "given": [ - "* ", - "?????? ", - "?????? " - ], - "name": "Macedonian", - "native": "??????????", - "scenario": [ - "????????", - "?? ??????" - ], - "scenarioOutline": [ - "??????? ?? ?????????", - "?????", - "???????" - ], - "then": [ - "* ", - "????? " - ], - "when": [ - "* ", - "???? " - ] - }, - "mk-Latn": { - "and": [ - "* ", - "I " - ], - "background": [ - "Kontekst", - "Sodrzhina" - ], - "but": [ - "* ", - "No " - ], - "examples": [ - "Primeri", - "Scenaria" - ], - "feature": [ - "Funkcionalnost", - "Biznis potreba", - "Mozhnost" - ], - "given": [ - "* ", - "Dadeno ", - "Dadena " - ], - "name": "Macedonian (Latin)", - "native": "Makedonski (Latinica)", - "scenario": [ - "Scenario", - "Na primer" - ], - "scenarioOutline": [ - "Pregled na scenarija", - "Skica", - "Koncept" - ], - "then": [ - "* ", - "Togash " - ], - "when": [ - "* ", - "Koga " - ] - }, - "mn": { - "and": [ - "* ", - "??? ", - "?????? " - ], - "background": [ - "???????" - ], - "but": [ - "* ", - "?????? ", - "????? " - ], - "examples": [ - "?????????" - ], - "feature": [ - "?????", - "??????????" - ], - "given": [ - "* ", - "???????? ?? ", - "??? " - ], - "name": "Mongolian", - "native": "??????", - "scenario": [ - "??????" - ], - "scenarioOutline": [ - "???????? ??????????" - ], - "then": [ - "* ", - "??????? ", - "????? ????? " - ], - "when": [ - "* ", - "????? " - ] - }, - "nl": { - "and": [ - "* ", - "En " - ], - "background": [ - "Achtergrond" - ], - "but": [ - "* ", - "Maar " - ], - "examples": [ - "Voorbeelden" - ], - "feature": [ - "Functionaliteit" - ], - "given": [ - "* ", - "Gegeven ", - "Stel " - ], - "name": "Dutch", - "native": "Nederlands", - "scenario": [ - "Scenario" - ], - "scenarioOutline": [ - "Abstract Scenario" - ], - "then": [ - "* ", - "Dan " - ], - "when": [ - "* ", - "Als ", - "Wanneer " - ] - }, - "no": { - "and": [ - "* ", - "Og " - ], - "background": [ - "Bakgrunn" - ], - "but": [ - "* ", - "Men " - ], - "examples": [ - "Eksempler" - ], - "feature": [ - "Egenskap" - ], - "given": [ - "* ", - "Gitt " - ], - "name": "Norwegian", - "native": "norsk", - "scenario": [ - "Scenario" - ], - "scenarioOutline": [ - "Scenariomal", - "Abstrakt Scenario" - ], - "then": [ - "* ", - "S " - ], - "when": [ - "* ", - "Nr " - ] - }, - "pa": { - "and": [ - "* ", - "??? " - ], - "background": [ - "??????" - ], - "but": [ - "* ", - "?? " - ], - "examples": [ - "????????" - ], - "feature": [ - "??????", - "????????", - "??? ?????" - ], - "given": [ - "* ", - "???? ", - "????? ?? " - ], - "name": "Panjabi", - "native": "??????", - "scenario": [ - "?????" - ], - "scenarioOutline": [ - "????? ?????", - "????? ??? ????" - ], - "then": [ - "* ", - "?? " - ], - "when": [ - "* ", - "???? " - ] - }, - "pl": { - "and": [ - "* ", - "Oraz ", - "I " - ], - "background": [ - "Zalozenia" - ], - "but": [ - "* ", - "Ale " - ], - "examples": [ - "Przyklady" - ], - "feature": [ - "Wlasciwosc", - "Funkcja", - "Aspekt", - "Potrzeba biznesowa" - ], - "given": [ - "* ", - "Zakladajac ", - "Majac ", - "Zakladajac, ze " - ], - "name": "Polish", - "native": "polski", - "scenario": [ - "Scenariusz" - ], - "scenarioOutline": [ - "Szablon scenariusza" - ], - "then": [ - "* ", - "Wtedy " - ], - "when": [ - "* ", - "Jezeli ", - "Jesli ", - "Gdy ", - "Kiedy " - ] - }, - "pt": { - "and": [ - "* ", - "E " - ], - "background": [ - "Contexto", - "Cenrio de Fundo", - "Cenario de Fundo", - "Fundo" - ], - "but": [ - "* ", - "Mas " - ], - "examples": [ - "Exemplos", - "Cenrios", - "Cenarios" - ], - "feature": [ - "Funcionalidade", - "Caracterstica", - "Caracteristica" - ], - "given": [ - "* ", - "Dado ", - "Dada ", - "Dados ", - "Dadas " - ], - "name": "Portuguese", - "native": "portugus", - "scenario": [ - "Cenrio", - "Cenario" - ], - "scenarioOutline": [ - "Esquema do Cenrio", - "Esquema do Cenario", - "Delineao do Cenrio", - "Delineacao do Cenario" - ], - "then": [ - "* ", - "Ento ", - "Entao " - ], - "when": [ - "* ", - "Quando " - ] - }, - "ro": { - "and": [ - "* ", - "Si ", - "?i ", - "Si " - ], - "background": [ - "Context" - ], - "but": [ - "* ", - "Dar " - ], - "examples": [ - "Exemple" - ], - "feature": [ - "Functionalitate", - "Func?ionalitate", - "Functionalitate" - ], - "given": [ - "* ", - "Date fiind ", - "Dat fiind ", - "Dati fiind ", - "Da?i fiind ", - "Dati fiind " - ], - "name": "Romanian", - "native": "romna", - "scenario": [ - "Scenariu" - ], - "scenarioOutline": [ - "Structura scenariu", - "Structura scenariu" - ], - "then": [ - "* ", - "Atunci " - ], - "when": [ - "* ", - "Cand ", - "Cnd " - ] - }, - "ru": { - "and": [ - "* ", - "? ", - "? ???? ?? ", - "????? " - ], - "background": [ - "???????????", - "????????" - ], - "but": [ - "* ", - "?? ", - "? " - ], - "examples": [ - "???????" - ], - "feature": [ - "???????", - "????????????????", - "??????????", - "????????" - ], - "given": [ - "* ", - "???????? ", - "???? ", - "????? ", - "???? " - ], - "name": "Russian", - "native": "???????", - "scenario": [ - "????????" - ], - "scenarioOutline": [ - "????????? ????????" - ], - "then": [ - "* ", - "?? ", - "????? ", - "????? " - ], - "when": [ - "* ", - "????? " - ] - }, - "sk": { - "and": [ - "* ", - "A ", - "A tie ", - "A taktie ", - "A zroven " - ], - "background": [ - "Pozadie" - ], - "but": [ - "* ", - "Ale " - ], - "examples": [ - "Prklady" - ], - "feature": [ - "Poiadavka", - "Funkcia", - "Vlastnost" - ], - "given": [ - "* ", - "Pokial ", - "Za predpokladu " - ], - "name": "Slovak", - "native": "Slovensky", - "scenario": [ - "Scenr" - ], - "scenarioOutline": [ - "Ncrt Scenru", - "Ncrt Scenra", - "Osnova Scenra" - ], - "then": [ - "* ", - "Tak ", - "Potom " - ], - "when": [ - "* ", - "Ked ", - "Ak " - ] - }, - "sl": { - "and": [ - "In ", - "Ter " - ], - "background": [ - "Kontekst", - "Osnova", - "Ozadje" - ], - "but": [ - "Toda ", - "Ampak ", - "Vendar " - ], - "examples": [ - "Primeri", - "Scenariji" - ], - "feature": [ - "Funkcionalnost", - "Funkcija", - "Monosti", - "Moznosti", - "Lastnost", - "Znacilnost" - ], - "given": [ - "Dano ", - "Podano ", - "Zaradi ", - "Privzeto " - ], - "name": "Slovenian", - "native": "Slovenski", - "scenario": [ - "Scenarij", - "Primer" - ], - "scenarioOutline": [ - "Struktura scenarija", - "Skica", - "Koncept", - "Oris scenarija", - "Osnutek" - ], - "then": [ - "Nato ", - "Potem ", - "Takrat " - ], - "when": [ - "Ko ", - "Ce ", - "Ce ", - "Kadar " - ] - }, - "sr-Cyrl": { - "and": [ - "* ", - "? " - ], - "background": [ - "????????", - "??????", - "????????" - ], - "but": [ - "* ", - "??? " - ], - "examples": [ - "???????", - "?????????" - ], - "feature": [ - "??????????????", - "?????????", - "???????" - ], - "given": [ - "* ", - "?? ???? ", - "?? ???? ", - "?? ???? " - ], - "name": "Serbian", - "native": "??????", - "scenario": [ - "????????", - "??????" - ], - "scenarioOutline": [ - "????????? ?????????", - "?????", - "???????" - ], - "then": [ - "* ", - "???? " - ], - "when": [ - "* ", - "???? ", - "??? " - ] - }, - "sr-Latn": { - "and": [ - "* ", - "I " - ], - "background": [ - "Kontekst", - "Osnova", - "Pozadina" - ], - "but": [ - "* ", - "Ali " - ], - "examples": [ - "Primeri", - "Scenariji" - ], - "feature": [ - "Funkcionalnost", - "Mogucnost", - "Mogucnost", - "Osobina" - ], - "given": [ - "* ", - "Za dato ", - "Za date ", - "Za dati " - ], - "name": "Serbian (Latin)", - "native": "Srpski (Latinica)", - "scenario": [ - "Scenario", - "Primer" - ], - "scenarioOutline": [ - "Struktura scenarija", - "Skica", - "Koncept" - ], - "then": [ - "* ", - "Onda " - ], - "when": [ - "* ", - "Kada ", - "Kad " - ] - }, - "sv": { - "and": [ - "* ", - "Och " - ], - "background": [ - "Bakgrund" - ], - "but": [ - "* ", - "Men " - ], - "examples": [ - "Exempel" - ], - "feature": [ - "Egenskap" - ], - "given": [ - "* ", - "Givet " - ], - "name": "Swedish", - "native": "Svenska", - "scenario": [ - "Scenario" - ], - "scenarioOutline": [ - "Abstrakt Scenario", - "Scenariomall" - ], - "then": [ - "* ", - "S " - ], - "when": [ - "* ", - "Nr " - ] - }, - "ta": { - "and": [ - "* ", - "?????? ", - "??????? " - ], - "background": [ - "???????" - ], - "but": [ - "* ", - "????? " - ], - "examples": [ - "??????????????????", - "?????????", - " ???????????" - ], - "feature": [ - "??????", - "???? ????", - "?????" - ], - "given": [ - "* ", - "?????????????? " - ], - "name": "Tamil", - "native": "?????", - "scenario": [ - "??????" - ], - "scenarioOutline": [ - "?????? ?????????", - "?????? ??????????" - ], - "then": [ - "* ", - "?????????? " - ], - "when": [ - "* ", - "???????? " - ] - }, - "th": { - "and": [ - "* ", - "??? " - ], - "background": [ - "??????" - ], - "but": [ - "* ", - "??? " - ], - "examples": [ - "??????????????", - "???????????????" - ], - "feature": [ - "????????", - "????????????????????", - "??????????" - ], - "given": [ - "* ", - "???????? " - ], - "name": "Thai", - "native": "???", - "scenario": [ - "?????????" - ], - "scenarioOutline": [ - "?????????????", - "?????????????????????" - ], - "then": [ - "* ", - "??????? " - ], - "when": [ - "* ", - "????? " - ] - }, - "tl": { - "and": [ - "* ", - "????? " - ], - "background": [ - "???????" - ], - "but": [ - "* ", - "???? " - ], - "examples": [ - "????????" - ], - "feature": [ - "?????" - ], - "given": [ - "* ", - "??????????? " - ], - "name": "Telugu", - "native": "??????", - "scenario": [ - "?????????" - ], - "scenarioOutline": [ - "????" - ], - "then": [ - "* ", - "??????? " - ], - "when": [ - "* ", - "? ??????????? " - ] - }, - "tlh": { - "and": [ - "* ", - "'ej ", - "latlh " - ], - "background": [ - "mo'" - ], - "but": [ - "* ", - "'ach ", - "'a " - ], - "examples": [ - "ghantoH", - "lutmey" - ], - "feature": [ - "Qap", - "Qu'meH 'ut", - "perbogh", - "poQbogh malja'", - "laH" - ], - "given": [ - "* ", - "ghu' noblu' ", - "DaH ghu' bejlu' " - ], - "name": "Klingon", - "native": "tlhIngan", - "scenario": [ - "lut" - ], - "scenarioOutline": [ - "lut chovnatlh" - ], - "then": [ - "* ", - "vaj " - ], - "when": [ - "* ", - "qaSDI' " - ] - }, - "tr": { - "and": [ - "* ", - "Ve " - ], - "background": [ - "Gemis" - ], - "but": [ - "* ", - "Fakat ", - "Ama " - ], - "examples": [ - "rnekler" - ], - "feature": [ - "zellik" - ], - "given": [ - "* ", - "Diyelim ki " - ], - "name": "Turkish", - "native": "Trke", - "scenario": [ - "Senaryo" - ], - "scenarioOutline": [ - "Senaryo taslagi" - ], - "then": [ - "* ", - "O zaman " - ], - "when": [ - "* ", - "Eger ki " - ] - }, - "tt": { - "and": [ - "* ", - "??? ", - "?? " - ], - "background": [ - "?????" - ], - "but": [ - "* ", - "????? ", - "???? " - ], - "examples": [ - "????????", - "????????" - ], - "feature": [ - "?????????", - "??????????????" - ], - "given": [ - "* ", - "????? " - ], - "name": "Tatar", - "native": "???????", - "scenario": [ - "????????" - ], - "scenarioOutline": [ - "??????????? ????????" - ], - "then": [ - "* ", - "???????? " - ], - "when": [ - "* ", - "???? " - ] - }, - "uk": { - "and": [ - "* ", - "? ", - "? ????? ", - "?? " - ], - "background": [ - "??????????" - ], - "but": [ - "* ", - "??? " - ], - "examples": [ - "????????" - ], - "feature": [ - "??????????" - ], - "given": [ - "* ", - "?????????? ", - "??????????, ?? ", - "????? ", - "???? " - ], - "name": "Ukrainian", - "native": "??????????", - "scenario": [ - "????????" - ], - "scenarioOutline": [ - "????????? ????????" - ], - "then": [ - "* ", - "?? ", - "???? " - ], - "when": [ - "* ", - "???? ", - "???? " - ] - }, - "ur": { - "and": [ - "* ", - "??? " - ], - "background": [ - "?? ????" - ], - "but": [ - "* ", - "???? " - ], - "examples": [ - "??????" - ], - "feature": [ - "??????", - "??????? ?? ?????", - "??????" - ], - "given": [ - "* ", - "??? ", - "?????? ", - "??? ??? " - ], - "name": "Urdu", - "native": "????", - "scenario": [ - "????????" - ], - "scenarioOutline": [ - "???? ???? ?? ????" - ], - "then": [ - "* ", - "??? ", - "?? " - ], - "when": [ - "* ", - "?? " - ] - }, - "uz": { - "and": [ - "* ", - "?? " - ], - "background": [ - "?????" - ], - "but": [ - "* ", - "????? ", - "????? ", - "???? " - ], - "examples": [ - "????????" - ], - "feature": [ - "??????????" - ], - "given": [ - "* ", - "???? " - ], - "name": "Uzbek", - "native": "???????", - "scenario": [ - "????????" - ], - "scenarioOutline": [ - "???????? ???????????" - ], - "then": [ - "* ", - "???? " - ], - "when": [ - "* ", - "???? " - ] - }, - "vi": { - "and": [ - "* ", - "V " - ], - "background": [ - "B?i c?nh" - ], - "but": [ - "* ", - "Nhung " - ], - "examples": [ - "D? li?u" - ], - "feature": [ - "Tnh nang" - ], - "given": [ - "* ", - "Bi?t ", - "Cho " - ], - "name": "Vietnamese", - "native": "Ti?ng Vi?t", - "scenario": [ - "Tnh hu?ng", - "K?ch b?n" - ], - "scenarioOutline": [ - "Khung tnh hu?ng", - "Khung k?ch b?n" - ], - "then": [ - "* ", - "Th " - ], - "when": [ - "* ", - "Khi " - ] - }, - "zh-CN": { - "and": [ - "* ", - "??", - "??", - "??" - ], - "background": [ - "??" - ], - "but": [ - "* ", - "??" - ], - "examples": [ - "??" - ], - "feature": [ - "??" - ], - "given": [ - "* ", - "??", - "??", - "??" - ], - "name": "Chinese simplified", - "native": "????", - "scenario": [ - "??", - "??" - ], - "scenarioOutline": [ - "????", - "????" - ], - "then": [ - "* ", - "??" - ], - "when": [ - "* ", - "?" - ] - }, - "zh-TW": { - "and": [ - "* ", - "??", - "??", - "??" - ], - "background": [ - "??" - ], - "but": [ - "* ", - "??" - ], - "examples": [ - "??" - ], - "feature": [ - "??" - ], - "given": [ - "* ", - "??", - "??", - "??" - ], - "name": "Chinese traditional", - "native": "????", - "scenario": [ - "??", - "??" - ], - "scenarioOutline": [ - "????", - "????" - ], - "then": [ - "* ", - "??" - ], - "when": [ - "* ", - "?" - ] - } -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Service/TestRemoveService.cs b/extentreports-dotnet-core/Service/TestRemoveService.cs deleted file mode 100644 index 60e9162..0000000 --- a/extentreports-dotnet-core/Service/TestRemoveService.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Linq; -using System.Collections.Generic; - -using AventStack.ExtentReports.Model; - -namespace AventStack.ExtentReports.Core -{ - internal class TestRemoveService - { - private static bool _removed = false; - - public static void Remove(List testList, Test test) - { - _removed = false; - FindAndRemoveTest(testList, test); - } - - private static void FindAndRemoveTest(List testList, Test test) - { - var filteredTestList = testList.Where(x => x.TestId == test.TestId).ToList(); - - if (filteredTestList.Count == 1) - { - RemoveTest(testList, test); - _removed = true; - return; - } - - foreach (var t in filteredTestList) - { - if (_removed) - return; - FindAndRemoveTest(t.NodeContext.All(), test); - } - } - - private static void RemoveTest(List testList, Test test) - { - testList.Remove(test); - } - } -} diff --git a/extentreports-dotnet-core/Status.cs b/extentreports-dotnet-core/Status.cs deleted file mode 100644 index 8cbacd6..0000000 --- a/extentreports-dotnet-core/Status.cs +++ /dev/null @@ -1,22 +0,0 @@ -using AventStack.ExtentReports.Model; - -using System; - -namespace AventStack.ExtentReports -{ - /// - /// List of allowed status for - /// - [Serializable] - public enum Status - { - Pass, - Fail, - Fatal, - Error, - Warning, - Info, - Skip, - Debug - } -} diff --git a/extentreports-dotnet-core/Utils/ExceptionUtil.cs b/extentreports-dotnet-core/Utils/ExceptionUtil.cs deleted file mode 100644 index 3cd8443..0000000 --- a/extentreports-dotnet-core/Utils/ExceptionUtil.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.Text.RegularExpressions; - -namespace AventStack.ExtentReports.Utils -{ - public static class ExceptionUtil - { - public static string GetExceptionHeadline(Exception ex) - { - var regex = new Regex("([\\w\\.]+)"); - var match = regex.Match(ex.ToString()); - - if (match.Success) - { - return match.Value; - } - - return null; - } - } -} diff --git a/extentreports-dotnet-core/Utils/ListUtil.cs b/extentreports-dotnet-core/Utils/ListUtil.cs deleted file mode 100644 index e34639a..0000000 --- a/extentreports-dotnet-core/Utils/ListUtil.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace AventStack.ExtentReports.Utils -{ - public static class ListUtil - { - public static bool IsNullOrEmpty(this IEnumerable enumerable) - { - if (enumerable == null) - { - return true; - } - - var collection = enumerable as ICollection; - if (collection != null) - return collection.Count < 1; - - return !enumerable.Any(); - } - - public static bool Contains(this List list, string keyword, StringComparison comp) - { - return list.FindIndex(x => (string.Compare(x.Trim().ToLower(), keyword, comp) == 0)) != -1; - } - } -} diff --git a/extentreports-dotnet-core/Utils/ResourceUtils.cs b/extentreports-dotnet-core/Utils/ResourceUtils.cs deleted file mode 100644 index 60671f7..0000000 --- a/extentreports-dotnet-core/Utils/ResourceUtils.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.IO; -using System.Reflection; - -namespace AventStack.ExtentReports.Utils -{ - internal class ResourceUtils - { - public static string GetResource(string folder, string fileName) - { - string result = string.Empty; - - using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(folder + "." + fileName)) - { - using (StreamReader sr = new StreamReader(stream)) - { - result = sr.ReadToEnd(); - } - } - - return result; - } - - public void WriteResourceToFile(string resourceName, string fileName) - { - using (var resource = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) - { - using (var file = new FileStream(fileName, FileMode.Create, FileAccess.Write)) - { - resource.CopyTo(file); - } - } - } - } -} diff --git a/extentreports-dotnet-core/ViewDefs/MaterialIcon.cs b/extentreports-dotnet-core/ViewDefs/MaterialIcon.cs deleted file mode 100644 index e717c76..0000000 --- a/extentreports-dotnet-core/ViewDefs/MaterialIcon.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace AventStack.ExtentReports.ViewDefs -{ - public static class MaterialIcon - { - private static Dictionary _dic = new Dictionary(); - - public static void Override(Status status, string icon) - { - _dic.Add(status, icon); - } - - public static string GetIcon(Status status) - { - if (_dic.ContainsKey(status)) - return _dic[status]; - - switch (status) - { - case Status.Fail: - return "cancel"; - case Status.Fatal: - return "cancel"; - case Status.Error: - return "error"; - case Status.Warning: - return"warning"; - case Status.Skip: - return "redo"; - case Status.Pass: - return "check_circle"; - case Status.Debug: - return "low_priority"; - case Status.Info: - return "info_outline"; - default: - return "help"; - } - } - } -} diff --git a/extentreports-dotnet-core/ViewDefs/TWBSIcon.cs b/extentreports-dotnet-core/ViewDefs/TWBSIcon.cs deleted file mode 100644 index bea764b..0000000 --- a/extentreports-dotnet-core/ViewDefs/TWBSIcon.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Collections.Generic; - -namespace AventStack.ExtentReports.ViewDefs -{ - public static class TWBSIcon - { - private static Dictionary _dic = new Dictionary(); - - public static void Override(Status status, string icon) - { - _dic.Add(status, icon); - } - - public static string GetIcon(Status status) - { - if (_dic.ContainsKey(status)) - return _dic[status]; - - switch (status) - { - case Status.Fail: - return "times"; - case Status.Fatal: - return "times"; - case Status.Error: - return "exclamation"; - case Status.Warning: - return"warning"; - case Status.Skip: - return "long-arrow-right"; - case Status.Pass: - return "check"; - case Status.Debug: - return "low_priority"; - case Status.Info: - return "info"; - default: - return "help"; - } - } - } -} diff --git a/extentreports-dotnet-core/Views/Html/Dashboard.cshtml b/extentreports-dotnet-core/Views/Html/Dashboard.cshtml deleted file mode 100644 index e9e2f15..0000000 --- a/extentreports-dotnet-core/Views/Html/Dashboard.cshtml +++ /dev/null @@ -1,61 +0,0 @@ -@using AventStack.ExtentReports - -@{ - var bdd = Model.TestList[0].IsBehaviorDrivenType; - - var boxSize = "col-md-12"; - if (Model.ReportStatusStats.ChildCount > 0) { - boxSize = "col-sm-12 col-md-6"; - } - if (bdd || Model.ReportStatusStats.GrandChildCount > 0) { - boxSize = "col-sm-12 col-md-4"; - } - - var chartWidth="115"; - var chartHeight="90"; - var chartBoxHeight="94px"; - - var parentHeading="Classes"; - var childHeading="Tests"; - var grandChildHeading="Steps"; - var parentLabel="class(es)"; - var childLabel = "test(s)"; - var grandchildLabel="step(s)"; - - if (bdd) { - parentHeading="Features"; - childHeading="Scenarios"; - grandChildHeading="Steps"; - parentLabel="feature(s)"; - childLabel="scenario(s)"; - } else { - if (Model.AnalysisStrategy == AnalysisStrategy.Test) { - parentHeading="Tests"; - childHeading="Steps"; - grandChildHeading=""; - parentLabel="test(s)"; - childLabel=grandchildLabel; - } - } - - var runDuration = DateTime.Now - Model.StartTime; -} - - - - @Include("Head") - -
    -
    - @Include("Navbar") - @Include("Sidenav") -
    -
    - @Include("SparkDashboardSPA") -
    -
    -
    -
    - @Include("Scripts") - - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Exception.cshtml b/extentreports-dotnet-core/Views/Html/Exception.cshtml deleted file mode 100644 index a23e50d..0000000 --- a/extentreports-dotnet-core/Views/Html/Exception.cshtml +++ /dev/null @@ -1,21 +0,0 @@ -@using RazorEngine -@using RazorEngine.Templating - - - -@Include("Head") - -
    -
    - @Include("Navbar") - @Include("Sidenav") -
    -
    - @Include("SparkExceptionSPA") -
    -
    -
    -
    - @Include("Scripts") - - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/IHtml2Marker.cs b/extentreports-dotnet-core/Views/Html/IHtml2Marker.cs deleted file mode 100644 index 2889c62..0000000 --- a/extentreports-dotnet-core/Views/Html/IHtml2Marker.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AventStack.ExtentReports.Views.Html -{ - internal interface IHtmlMarker : IViewsMarker - { - } -} diff --git a/extentreports-dotnet-core/Views/Html/Index.cshtml b/extentreports-dotnet-core/Views/Html/Index.cshtml deleted file mode 100644 index ebb655c..0000000 --- a/extentreports-dotnet-core/Views/Html/Index.cshtml +++ /dev/null @@ -1,36 +0,0 @@ -@using AventStack.ExtentReports -@using AventStack.ExtentReports.ViewDefs -@using RazorEngine -@using RazorEngine.Templating - - - -@Include("Head") - - -@{ - var isbdd = false; - var cls = ""; - if (Model.TestList.Count > 0 && Model.TestList[0].IsBehaviorDrivenType) - { - isbdd = true; - cls = "bdd-report"; - } -} - - -
    -
    - @Include("Navbar") - @Include("Sidenav") -
    -
    - @Include("SparkTestSPA") -
    -
    -
    -
    - @Include("Scripts") - - - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Partials/Attributes.cshtml b/extentreports-dotnet-core/Views/Html/Partials/Attributes.cshtml deleted file mode 100644 index eeee68c..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/Attributes.cshtml +++ /dev/null @@ -1,26 +0,0 @@ -@if (Model.HasAttributes) -{ -
    - @if (Model.HasAuthor) - { - foreach (var author in Model.AuthorContext.All()) - { - @author.Name - } - } - @if (Model.HasCategory) - { - foreach (var category in Model.CategoryContext.All()) - { - @category.Name - } - } - @if (Model.HasDevice) - { - foreach (var device in Model.DeviceContext.All()) - { - @device.Name - } - } -
    -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Partials/AttributesView.cshtml b/extentreports-dotnet-core/Views/Html/Partials/AttributesView.cshtml deleted file mode 100644 index 3fb44d9..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/AttributesView.cshtml +++ /dev/null @@ -1,50 +0,0 @@ -@using AventStack.ExtentReports.ViewDefs - -
  • -
    -
    -

    @Model.Name

    -

    @Model.Count tests

    - - @if (Model.Passed > 0) { @Model.Passed } - @if (Model.Failed > 0) { @Model.Failed } - @if (Model.Skipped > 0) { @Model.Skipped } - @if (Model.Others > 0) { @Model.Others } - -
    -
    -
    -
    -

    @Model.Name

    - @if (Model.Passed > 0) { @Model.Passed passed } - @if (Model.Failed > 0) { @Model.Failed failed } - @if (Model.Skipped > 0) { @Model.Skipped skipped } - @if (Model.Others > 0) { @Model.Others others } -
    - - - - - - - - - - @foreach (var test in Model.TestCollection) - { - - - - - - } - -
    StatusTimestampTestName
    -
    - -
    -
    @test.StartTime.ToString("HH:mm:ss") - @test.HierarchicalName -
    -
    -
  • \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Partials/Head.cshtml b/extentreports-dotnet-core/Views/Html/Partials/Head.cshtml deleted file mode 100644 index 26a5c3f..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/Head.cshtml +++ /dev/null @@ -1,10 +0,0 @@ - - - - @Model.MasterConfig.GetValue("documentTitle") - - - - - - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Partials/Navbar.cshtml b/extentreports-dotnet-core/Views/Html/Partials/Navbar.cshtml deleted file mode 100644 index f614665..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/Navbar.cshtml +++ /dev/null @@ -1,41 +0,0 @@ - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Partials/RecurseNodes.cshtml b/extentreports-dotnet-core/Views/Html/Partials/RecurseNodes.cshtml deleted file mode 100644 index b353692..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/RecurseNodes.cshtml +++ /dev/null @@ -1,37 +0,0 @@ -@using AventStack.ExtentReports.ViewDefs - -@if (Model.HasChildren) -{ -
    - @foreach (var node in Model.NodeContext.All()) - { -
    - -
    -
    - @if (!string.IsNullOrEmpty(node.Description)) - { -
    @node.Description
    - } - @if (node.HasLog) - { - @Include("Log", node) - } - @if (node.HasScreenCapture) { @foreach (var sc in node.ScreenCaptureContext.All()) { @sc.Source } } -
    -
    - @if (node.HasChildren) - { - @Include("RecurseNodes", node) - } -
    - } -
    -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Partials/Scripts.cshtml b/extentreports-dotnet-core/Views/Html/Partials/Scripts.cshtml deleted file mode 100644 index 65ba942..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/Scripts.cshtml +++ /dev/null @@ -1,4 +0,0 @@ - - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Partials/Sidenav.cshtml b/extentreports-dotnet-core/Views/Html/Partials/Sidenav.cshtml deleted file mode 100644 index e3c86ca..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/Sidenav.cshtml +++ /dev/null @@ -1,52 +0,0 @@ -
    -
    - -
    -
    - -
    -
    diff --git a/extentreports-dotnet-core/Views/Html/Partials/SparkBDD.cshtml b/extentreports-dotnet-core/Views/Html/Partials/SparkBDD.cshtml deleted file mode 100644 index 301ce3c..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/SparkBDD.cshtml +++ /dev/null @@ -1,74 +0,0 @@ -@using AventStack.ExtentReports.ViewDefs - -@if (Model.HasChildren) -{ -
    - @foreach (var node in Model.NodeContext.All()) - { -
    - - @if (node.HasChildren) - { - if (node.BehaviorDrivenTypeName.Equals("Scenario Outline")) - { -
    - @foreach (var child in node.NodeContext.All()) - { -
    - -
    - @if (child.HasScreenCapture) { foreach (var sc in child.ScreenCaptureContext.All()) { @sc.Source } } - @foreach (var step in child.NodeContext.All()) - { -
    - - - - @step.BehaviorDrivenTypeName @step.Name -
    - @Include("SparkStepDetails", step) - @if (step.HasScreenCapture) { foreach (var sc in step.ScreenCaptureContext.All()) { @sc.Source } } - } -
    -
    - } -
    - } - else - { -
    -
    - @if (node.HasScreenCapture) { foreach (var sc in node.ScreenCaptureContext.All()) { @sc.Source } } - @foreach (var child in node.NodeContext.All()) - { -
    - - - - @child.BehaviorDrivenTypeName @child.Name -
    - @Include("SparkStepDetails", child) - @if (child.HasScreenCapture) { foreach (var sc in child.ScreenCaptureContext.All()) { @sc.Source } } - } -
    -
    - } - } -
    - } -
    -} diff --git a/extentreports-dotnet-core/Views/Html/Partials/SparkDashboardSPA.cshtml b/extentreports-dotnet-core/Views/Html/Partials/SparkDashboardSPA.cshtml deleted file mode 100644 index e2cfcec..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/SparkDashboardSPA.cshtml +++ /dev/null @@ -1,405 +0,0 @@ -@using AventStack.ExtentReports -@{ - var bdd = Model.TestList[0].IsBehaviorDrivenType; - - var boxSize = "col-md-12"; - if (Model.ReportStatusStats.ChildCount > 0) { - boxSize = "col-sm-12 col-md-6"; - } - if (bdd || Model.ReportStatusStats.GrandChildCount > 0) { - boxSize = "col-sm-12 col-md-4"; - } - - var chartWidth="115"; - var chartHeight="90"; - var chartBoxHeight="94px"; - - var parentHeading="Classes"; - var childHeading="Tests"; - var grandChildHeading="Steps"; - var parentLabel="class(es)"; - var childLabel = "test(s)"; - var grandchildLabel="step(s)"; - - if (bdd) { - parentHeading="Features"; - childHeading="Scenarios"; - grandChildHeading="Steps"; - parentLabel="feature(s)"; - childLabel="scenario(s)"; - } else { - if (Model.AnalysisStrategy == AnalysisStrategy.Test) { - parentHeading="Tests"; - childHeading="Steps"; - grandChildHeading=""; - parentLabel="test(s)"; - childLabel=grandchildLabel; - } - } - - var runDuration = DateTime.Now - Model.StartTime; -} -
    -
    -
    -
    -
    -
    @parentHeading
    -
    -
    -
    - -
    -
    - -
    -
    - @if (Model.ReportStatusStats.ChildCount > 0) - { -
    -
    -
    -
    @childHeading
    -
    -
    -
    - -
    -
    - -
    -
    - } - @if (Model.ReportStatusStats.GrandChildCount > 0) - { -
    -
    -
    -
    @grandChildHeading
    -
    -
    -
    - -
    -
    - -
    -
    - } -
    -
    -
    -
    -
    -
    -
    -
    @parentHeading
    -

    @Model.ReportStatusStats.ParentCount

    - - - @Math.Round(Model.ReportStatusStats.ParentPercentagePass, 2)% - -
    -
    - -
    -
    -
    -
    -
    - @if (Model.ReportStatusStats.ChildCount > 0) - { -
    -
    -
    -
    -
    -
    @childHeading
    -

    @Model.ReportStatusStats.ChildCount

    - - - @Math.Round(Model.ReportStatusStats.ChildPercentagePass, 2)% - -
    -
    - -
    -
    -
    -
    -
    - } -
    -
    -
    -
    -
    -
    Start
    -
    @Model.StartTime
    - -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    Duration
    -
    @Model.EndTime.Subtract(Model.StartTime)
    - -
    -
    - -
    -
    -
    -
    -
    - @if (Model.ReportStatusStats.ChildCount == 0) - { -
    -
    -
    -
    -
    -

    Duration

    -
    @runDuration
    - -
    -
    - -
    -
    -
    -
    -
    - } -
    - @if (Model.MasterConfig.GetValue("enableTimeline") == "true") - { -
    -
    -
    -
    -
    Timeline
    -
    -
    -
    - -
    -
    -
    -
    -
    - } -
    - @if (Model.AuthorContext.Context.Count > 0) - { -
    -
    -
    -
    Author
    -
    -
    - - - - - - - - - - - - @foreach(var context in Model.AuthorContext.Context) - { - - - - - - - - } - -
    NamePassedFailedOthersPassed %
    @context.Name@context.Passed@context.Failed@context.Others@(Math.Round(((double)context.Passed/(double)context.Count)*100, 2))%
    -
    -
    -
    - } - @if (Model.CategoryContext.Context.Count > 0) - { -
    -
    -
    -
    Tags
    -
    -
    - - - - - - - - - - - - @foreach(var context in Model.CategoryContext.Context) - { - - - - - - - - } - -
    NamePassedFailedOthersPassed %
    @context.Name@context.Passed@context.Failed@context.Others@(Math.Round(((double)context.Passed/(double)context.Count)*100, 2))%
    -
    -
    -
    - } - @if (Model.DeviceContext.Context.Count > 0) - { -
    -
    -
    -
    Device
    -
    -
    - - - - - - - - - - - - @foreach(var context in Model.DeviceContext.Context) - { - - - - - - - - } - -
    NamePassedFailedOthersPassed %
    @context.Name@context.Passed@context.Failed@context.Others@(Math.Round(((double)context.Passed/(double)context.Count)*100, 2))%
    -
    -
    -
    - } - @if (Model.SystemAttributeContext.Count > 0) - { -
    -
    -
    -
    Environment
    -
    -
    - - - - - - - - - @foreach (var attr in Model.SystemAttributeContext.SystemAttributeCollection) - { - - - - - } - -
    NameValue
    @attr.Name@attr.Value
    -
    -
    -
    - } -
    -
    - -@if (Model.MasterConfig.GetValue("enableTimeline") == "true") -{ - var json = ""; - for (int ix = 0; ix < Model.TestList.Count; ix++) { - json += "\"" + Model.TestList[ix].Name + "\"" + ":" + Model.TestList[ix].RunDuration.TotalSeconds; - if (ix != Model.TestList.Count-1) { - json += ","; - } - } - -} diff --git a/extentreports-dotnet-core/Views/Html/Partials/SparkExceptionSPA.cshtml b/extentreports-dotnet-core/Views/Html/Partials/SparkExceptionSPA.cshtml deleted file mode 100644 index 899f6fd..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/SparkExceptionSPA.cshtml +++ /dev/null @@ -1,45 +0,0 @@ -@using AventStack.ExtentReports -@using RazorEngine -@using RazorEngine.Templating -
    -
    - -
    -
      - @foreach (var context in Model.ExceptionInfoContext.Context) - { - @Include("AttributesView", context) - } -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Partials/SparkStandard.cshtml b/extentreports-dotnet-core/Views/Html/Partials/SparkStandard.cshtml deleted file mode 100644 index 6b2cef9..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/SparkStandard.cshtml +++ /dev/null @@ -1,13 +0,0 @@ -@if (Model.HasLog) -{ -
    - @Include("Log", Model) -
    -} -@if (Model.HasScreenCapture) { @foreach (var sc in Model.ScreenCaptureContext.All()) { @sc.Source } } -@if (Model.HasChildren) -{ -
    - @Include("RecurseNodes", Model) -
    -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Partials/SparkTagSPA.cshtml b/extentreports-dotnet-core/Views/Html/Partials/SparkTagSPA.cshtml deleted file mode 100644 index 755ce66..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/SparkTagSPA.cshtml +++ /dev/null @@ -1,45 +0,0 @@ -@using AventStack.ExtentReports -@using RazorEngine -@using RazorEngine.Templating -
    -
    - -
    -
      - @foreach (var category in Model.CategoryContext.Context) - { - @Include("AttributesView", category) - } -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Partials/SparkTestSPA.cshtml b/extentreports-dotnet-core/Views/Html/Partials/SparkTestSPA.cshtml deleted file mode 100644 index 647ccec..0000000 --- a/extentreports-dotnet-core/Views/Html/Partials/SparkTestSPA.cshtml +++ /dev/null @@ -1,163 +0,0 @@ -@using AventStack.ExtentReports -@using AventStack.ExtentReports.ViewDefs -@using RazorEngine -@using RazorEngine.Templating -@{ - var isbdd = false; - var cls = ""; - if (Model.TestList.Count > 0 && Model.TestList[0].IsBehaviorDrivenType) - { - isbdd = true; - cls = "bdd-report"; - } -} -
    -
    -
    - -
      - - @if (Model.AuthorContext.Context.Count > 0) - { - - } - @if (Model.CategoryContext.Context.Count > 0) - { - - } - @if (Model.DeviceContext.Context.Count > 0) - { - - } -
    -
    -
    -
      - @foreach (var test in Model.TestList) - { - string authors = "", devices = "", tags = ""; - foreach (var author in test.AuthorContext.All()) - { - authors += author.Name + " "; - } - foreach (var device in test.DeviceContext.All()) - { - devices += device.Name + " "; - } - foreach (var tag in test.CategoryContext.All()) - { - tags += tag.Name + " "; - } -
    • -
      - -
      -
      -
      -

      @test.Name

      -

      @test.RunDuration.ToString("''h'h:'m'm:'s's+'fff'ms'")

      - @test.StartTime.ToString("HH:mm:ss tt") -
      -
      -
      -
      -
      -
      -
      @test.Name
      - @test.StartTime - @test.EndTime - @test.RunDuration.ToString("''h'h:'m'm:'s's+'fff'ms'") -
      - @if (test.HasAttributes) - { -
      - @Include("Attributes", test) -
      - } - @if (!string.IsNullOrEmpty(test.Description)) - { -
      - @test.Description -
      - } -
      -
      - @if (!isbdd) - { - @Include("SparkStandard", test) - } - else - { - @Include("SparkBDD", test) - } -
      -
    • - } -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/SparkIndexSPA.cshtml b/extentreports-dotnet-core/Views/Html/SparkIndexSPA.cshtml deleted file mode 100644 index c872f2a..0000000 --- a/extentreports-dotnet-core/Views/Html/SparkIndexSPA.cshtml +++ /dev/null @@ -1,42 +0,0 @@ -@using AventStack.ExtentReports -@using AventStack.ExtentReports.ViewDefs -@using RazorEngine -@using RazorEngine.Templating -@{ - var isbdd = false; - var cls = ""; - if (Model.TestList.Count > 0 && Model.TestList[0].IsBehaviorDrivenType) - { - isbdd = true; - cls = "bdd-report"; - } -} - - -@Include("Head") - - -
    -
    - @Include("Navbar") - @Include("Sidenav") -
    -
    - @Include("SparkTestSPA") - @if (Model.CategoryContext.Context.Count > 0) - { - @Include("SparkTagSPA") - } - @if (Model.ExceptionInfoContext.Context.Count > 0) - { - @Include("SparkExceptionSPA") - } - @Include("SparkDashboardSPA") -
    -
    -
    -
    - @Include("Scripts") - - - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Html/Tag.cshtml b/extentreports-dotnet-core/Views/Html/Tag.cshtml deleted file mode 100644 index 214d09f..0000000 --- a/extentreports-dotnet-core/Views/Html/Tag.cshtml +++ /dev/null @@ -1,21 +0,0 @@ -@using RazorEngine -@using RazorEngine.Templating - - - -@Include("Head") - -
    -
    - @Include("Navbar") - @Include("Sidenav") -
    -
    - @Include("SparkTagSPA") -
    -
    -
    -
    - @Include("Scripts") - - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Logger/ILoggerMarker.cs b/extentreports-dotnet-core/Views/Logger/ILoggerMarker.cs deleted file mode 100644 index e0ec7b7..0000000 --- a/extentreports-dotnet-core/Views/Logger/ILoggerMarker.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AventStack.ExtentReports.Views.Logger -{ - internal interface ILoggerMarker : IViewsMarker - { - } -} diff --git a/extentreports-dotnet-core/Views/Logger/LoggerMacro.cshtml b/extentreports-dotnet-core/Views/Logger/LoggerMacro.cshtml deleted file mode 100644 index 6f5a17c..0000000 --- a/extentreports-dotnet-core/Views/Logger/LoggerMacro.cshtml +++ /dev/null @@ -1,40 +0,0 @@ -@{ - var spacer = ""; - var level = Model.Level; - - if (level >= 1) - { - for (var ix = 2; ix <= level; ix++) - { - spacer = "    "; - } - spacer += "|---"; - } - - string categories = "", devices = ""; - foreach (var category in Model.CategoryContext.All()) {categories+=category.Name;} - foreach (var device in Model.DeviceContext.All()) {devices+=device.Name;} -} - -
    - @Model.StartTime  - @Model.Status.ToString().Replace("ing", "")@for (var ix = Model.Status.ToString().Length; ix <= 5; ix++) {@Raw(" ")} - @(spacer)[@Model.Name] started - - @Include("CommonsAttributes", Model) - - @foreach (var log in Model.LogContext.All()) - { -
    - @log.Timestamp  - @log.Status.ToString().Replace("ing", "")@for (var ix = log.Status.ToString().Length; ix <= 5; ix++) {@Raw(" ")} - @(spacer)[@Model.Name] - @if (log.HasScreenCapture) {@log.ScreenCaptureContext.LastOrDefault().Source} - @if (log.HasException) { } else { @Raw(log.Details) } -
    - } -
    - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/Logger/LoggerTest.cshtml b/extentreports-dotnet-core/Views/Logger/LoggerTest.cshtml deleted file mode 100644 index 1e34332..0000000 --- a/extentreports-dotnet-core/Views/Logger/LoggerTest.cshtml +++ /dev/null @@ -1,124 +0,0 @@ -@using AventStack.ExtentReports - - - - @Include("CommonsHead") - - -
    - @Include("CommonsNav") -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    Test Logs
    - @foreach (var test in Model.TestList) - { -
    - @Include("LoggerMacro", test) - @foreach (var node in test.NodeContext.All()) - { - @Include("LoggerMacro", node) - foreach (var child in node.NodeContext.All()) - { - @Include("LoggerMacro", child) - foreach (var grandchild in child.NodeContext.All()) - { - @Include("LoggerMacro", grandchild) - } - } - } -
    - } -
    -
    -
    -
    -
    -
    -
    -
    - @{ - var p = "https://cdn.rawgit.com/extent-framework/extent-github-cdn/d74480e/logger/js/"; - } - - @Include("CommonsInjectJs", Model) - - diff --git a/extentreports-dotnet-core/Views/V3Html/Author/V3Author.cshtml b/extentreports-dotnet-core/Views/V3Html/Author/V3Author.cshtml deleted file mode 100644 index 2a8a5ff..0000000 --- a/extentreports-dotnet-core/Views/V3Html/Author/V3Author.cshtml +++ /dev/null @@ -1,80 +0,0 @@ -@if (Model.AuthorContext.Context.Count > 0) -{ -
    -
    -
    - - - -
    -
    -
    -
    -
      - @foreach (var author in Model.AuthorContext.Context) - { -
    • -
      - @author.Name - - @if (author.Passed > 0) - { - @author.Passed - } - @if (author.Failed > 0) - { - @author.Failed - } - @if (author.Others > 0) - { - @author.Others - } - -
      -
      -
      - @if (author.Passed > 0) { Passed: @author.Passed } - @if (author.Failed > 0) { Failed: @author.Failed } - @if (author.Others > 0) { Others: @author.Others } -
      -
      - - - - - - - - - - @foreach (var test in author.TestCollection) - { - - - - - - } - -
      TimestampTestNameStatus
      @test.StartTime@test.HierarchicalName@test.Status
      -
      -
      -
    • - } -
    -
    -
    -
    -
    -
    -
    -
    -
    -} \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/V3Html/Category/V3Category.cshtml b/extentreports-dotnet-core/Views/V3Html/Category/V3Category.cshtml deleted file mode 100644 index 53ae9a5..0000000 --- a/extentreports-dotnet-core/Views/V3Html/Category/V3Category.cshtml +++ /dev/null @@ -1,74 +0,0 @@ -@if (Model.CategoryContext.Context.Count > 0) -{ -
    -
    -
    - - - -
    -
    -
    -
    -
      - @foreach (var category in Model.CategoryContext.Context) - { -
    • -
      - @category.Name - - @if (category.Passed > 0) { @category.Passed } - @if (category.Failed > 0) { @category.Failed } - @if (category.Skipped > 0) { @category.Skipped } - @if (category.Others > 0) { @category.Others } - -
      -
      -
      - @if (category.Passed > 0) { Passed: @category.Passed } - @if (category.Failed > 0) { Failed: @category.Failed } - @if (category.Skipped > 0) { Skipped: @category.Skipped } - @if (category.Others > 0) { Others: @category.Others } -
      -
      - - - - - - - - - - @foreach (var test in category.TestCollection) - { - - - - - - } - -
      TimestampTestNameStatus
      @test.StartTime@test.HierarchicalName@test.Status
      -
      -
      -
    • - } -
    -
    -
    -
    -
    -
    -
    -
    -
    -} - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/V3Html/Dashboard/V3Dashboard.cshtml b/extentreports-dotnet-core/Views/V3Html/Dashboard/V3Dashboard.cshtml deleted file mode 100644 index ef27b88..0000000 --- a/extentreports-dotnet-core/Views/V3Html/Dashboard/V3Dashboard.cshtml +++ /dev/null @@ -1,132 +0,0 @@ -@using AventStack.ExtentReports - -@{ - var bdd = Model.TestList[0].IsBehaviorDrivenType; - - var parentViewChartsHeading="Classes"; - var childViewChartsHeading="Tests"; - var grandChildViewChartsHeading="Steps"; - var parentLabel="class(es)"; - var childLabel = "test(s)"; - var grandchildLabel="step(s)"; - - if (bdd) { - parentViewChartsHeading="Features"; - childViewChartsHeading="Scenarios"; - grandChildViewChartsHeading="Steps"; - parentLabel="feature(s)"; - childLabel="scenario(s)"; - } else { - if (Model.AnalysisStrategy == AnalysisStrategy.Test) { - parentViewChartsHeading="Tests"; - childViewChartsHeading="Steps"; - grandChildViewChartsHeading=""; - parentLabel="test(s)"; - childLabel=grandchildLabel; - } - } - - var runDuration = DateTime.Now - Model.StartTime; -} - -
    -
    -
    Dashboard
    - -
    -
    -
    - @parentViewChartsHeading -
    @Model.ReportStatusStats.ParentCount
    -
    -
    -
    -
    - @childViewChartsHeading -
    @Model.ReportStatusStats.ChildCount
    -
    -
    - @if (!string.IsNullOrEmpty(grandChildViewChartsHeading)) - { -
    -
    - @grandChildViewChartsHeading -
    @Model.ReportStatusStats.GrandChildCount
    -
    -
    - } -
    -
    - Start -
    @Model.StartTime
    -
    -
    -
    -
    - End -
    @Model.EndTime
    -
    -
    -
    -
    - Time Taken -
    @runDuration
    -
    -
    - @if (Model.SystemAttributeContext.Count > 0) - { -
    -
    - Environment

     

    - - - - - - @foreach (var attr in Model.SystemAttributeContext.SystemAttributeCollection) - { - - - - - } -
    NameValue
    @attr.Name@attr.Value
    -
    -
    - } - @if (Model.CategoryContext.Context.Count > 0) - { -
    -
    - Categories

     

    - - - - - - - - - - - @foreach(var context in Model.CategoryContext.Context) - { - - - - - - - - - } -
    NamePassedFailedSkippedOthersPassed %
    @context.Name@context.Passed@context.Failed@context.Skipped@context.Others - @((context.Passed / context.Count)*100)% -
    -
    -
    - } -
    -
    -
    - diff --git a/extentreports-dotnet-core/Views/V3Html/Exception/V3Exception.cshtml b/extentreports-dotnet-core/Views/V3Html/Exception/V3Exception.cshtml deleted file mode 100644 index ba73d3e..0000000 --- a/extentreports-dotnet-core/Views/V3Html/Exception/V3Exception.cshtml +++ /dev/null @@ -1,67 +0,0 @@ -@using AventStack.ExtentReports.Model - -@if (Model.ExceptionInfoContext.Context.Count > 0) -{ -
    -
    -
    - - - -
    -
    -
    -
    -
      - @foreach (var exception in Model.ExceptionInfoContext.Context) - { -
    • -
      - @exception.Name - @exception.Count -
      -
      -
      - - - - - - - - - - @foreach (var test in exception.TestCollection) - { - - - - - - } - -
      TimestampTestNameStatus
      @test.StartTime@test.HierarchicalName - -
      -
      -
      -
    • - } -
    -
    -
    -
    -
    -
    -
    -
    -
    -} - diff --git a/extentreports-dotnet-core/Views/V3Html/IV3HtmlMarker.cs b/extentreports-dotnet-core/Views/V3Html/IV3HtmlMarker.cs deleted file mode 100644 index 866ea99..0000000 --- a/extentreports-dotnet-core/Views/V3Html/IV3HtmlMarker.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace AventStack.ExtentReports.Views.V3Html -{ - internal interface IV3HtmlMarker : IViewsMarker - { - } -} diff --git a/extentreports-dotnet-core/Views/V3Html/Test/V3Charts.cshtml b/extentreports-dotnet-core/Views/V3Html/Test/V3Charts.cshtml deleted file mode 100644 index 8461db9..0000000 --- a/extentreports-dotnet-core/Views/V3Html/Test/V3Charts.cshtml +++ /dev/null @@ -1,115 +0,0 @@ -@using AventStack.ExtentReports - -@{ - var bdd = Model.TestList[0].IsBehaviorDrivenType; - - var boxSize = "s12 m12 l12"; - if (Model.ReportStatusStats.ChildCount > 0) { - boxSize = "s12 m6 l6"; - } - if (bdd || Model.ReportStatusStats.GrandChildCount > 0) { - boxSize = "s12 m4 l4"; - } - - var chartWidth="90"; - var chartHeight="80"; - var chartBoxHeight="94px"; - - var pluralES = Model.TestList.Count > 1 ? "es" : ""; - var pluralS = Model.TestList.Count > 1 ? "s" : ""; - - var parentViewChartsHeading="Classes"; - var childViewChartsHeading="Tests"; - var grandChildViewChartsHeading="Steps"; - var parentLabel="class" + pluralES; - var childLabel = "test" + pluralS; - var grandchildLabel="step" + pluralS; - - if (bdd) { - parentViewChartsHeading="Features"; - childViewChartsHeading="Scenarios"; - grandChildViewChartsHeading="Steps"; - parentLabel="feature" + pluralS; - childLabel="scenario" + pluralS; - } else { - if (Model.AnalysisStrategy == AnalysisStrategy.Test) { - parentViewChartsHeading="Tests"; - childViewChartsHeading="Steps"; - grandChildViewChartsHeading=""; - parentLabel="test" + pluralS; - childLabel=grandchildLabel; - } - } -} - -
    -
    -
    -
    -
    @parentViewChartsHeading
    -
    - -
    -
    - @Model.ReportStatusStats.ParentCountPass @parentLabel passed -
    -
    - @(Model.ReportStatusStats.ParentCountFail+Model.ReportStatusStats.ParentCountFatal) failed, - @(Model.ReportStatusStats.ParentCountSkip) skipped, - @(Model.ReportStatusStats.ParentCountError+Model.ReportStatusStats.ParentCountWarning) others -
    -
    -
    - @if (Model.ReportStatusStats.ChildCount > 0) - { -
    -
    -
    @childViewChartsHeading
    -
    - -
    -
    - @Model.ReportStatusStats.ChildCountPass @childLabel passed -
    -
    - @(Model.ReportStatusStats.ChildCountFail+Model.ReportStatusStats.ChildCountFatal) failed, - @(Model.ReportStatusStats.ChildCountSkip) skipped, - @(Model.ReportStatusStats.ChildCountError+Model.ReportStatusStats.ChildCountWarning) others -
    -
    -
    - } - @if (Model.ReportStatusStats.GrandChildCount > 0) - { -
    -
    -
    @grandChildViewChartsHeading
    -
    - -
    -
    - @Model.ReportStatusStats.GrandChildCountPass @grandchildLabel passed -
    -
    - @(Model.ReportStatusStats.GrandChildCountFail+Model.ReportStatusStats.GrandChildCountFatal) failed, - @(Model.ReportStatusStats.GrandChildCountSkip) skipped, - @(Model.ReportStatusStats.GrandChildCountError+Model.ReportStatusStats.GrandChildCountWarning) others -
    -
    -
    - } -
    - @if (Model.MasterConfig.GetValue("enableTimeline") == "true") - { -
    -
    -
    -
    Timeline (seconds)
    -
    - -
    -
    -
    -
    - } -
    \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/V3Html/Test/V3Test.cshtml b/extentreports-dotnet-core/Views/V3Html/Test/V3Test.cshtml deleted file mode 100644 index 165601f..0000000 --- a/extentreports-dotnet-core/Views/V3Html/Test/V3Test.cshtml +++ /dev/null @@ -1,650 +0,0 @@ -@using AventStack.ExtentReports -@using AventStack.ExtentReports.ViewDefs -@{ - var bdd = false; - if (Model.TestList.Count > 0) - { - bdd = Model.TestList[0].IsBehaviorDrivenType || (Model.TestList[0].HasChildren && Model.TestList[0].NodeContext.FirstOrDefault().IsBehaviorDrivenType); - } -} -
    -
    -
    - -
    - - warning Status - - -
    - - - @if (Model.CategoryContext.Context.Count > 0) - { -
    - - local_offer Category - - -
    - } - - - - - -
    - @{ - var dashboardEnabledClass = ""; - if (Model.MasterConfig.GetValue("chartVisibleOnOpen") == "true") { - dashboardEnabledClass = "pink-text"; - } - } - - track_changes Dashboard - -
    - - - - -
    -
    - @Include("V3Charts") -
    -
    -
      - @foreach (var test in Model.TestList) - { - var hasChildrenClass = test.HasChildren ? "has-leaf" : ""; -
    • -
      - @test.Name - @test.StartTime - @test.Status -
      -
      - @if (bdd) - { - - if (!string.IsNullOrEmpty(test.Description)) - { -
      @test.Description
      - } - foreach (var node in test.NodeContext.All()) - { -
      - @if (node.HasCategory) - { -
      - @foreach (var category in node.CategoryContext.All()) - { - @category.Name - } -
      - } - @node.RunDuration -
      -
      - - @MaterialIcon.GetIcon(node.Status) - @node.BehaviorDrivenTypeName: @node.Name -
      - @if (node.HasScreenCapture) - { -
        - @foreach (var sc in node.ScreenCaptureContext.All()) - { -
      • - - panorama - -
      • - } -
      - } - @if (!string.IsNullOrEmpty(node.Description)) - { - @node.Description - } -
      - @if (node.HasChildren) - { -
        - @foreach (var child in node.NodeContext.All()) - { -
      • -
        - - @MaterialIcon.GetIcon(child.Status) - @child.Name -
        - @if (child.HasScreenCapture) - { -
          - @foreach (var sc in child.ScreenCaptureContext.All()) - { -
        • - - panorama - -
        • - } -
        - } - @if (!string.IsNullOrEmpty(child.Description)) - { - @child.Description - } - @foreach (var log in child.LogContext.All()) - { - if (log.HasException) - { - - } - else - { -
        @Raw(log.Details)
        - } - if (log.HasScreenCapture) - { -
        @Raw(log.ScreenCaptureContext.FirstOrDefault().Source)
        - } - } - @if (child.HasChildren) - { -
          - @foreach (var gc in child.NodeContext.All()) - { -
        • -
          - - @MaterialIcon.GetIcon(gc.Status) - @gc.Name -
          - @if (gc.HasScreenCapture) - { -
            - @foreach (var sc in gc.ScreenCaptureContext.All()) - { -
          • - - panorama - -
          • - } -
          - } - @if (!string.IsNullOrEmpty(gc.Description)) - { - @gc.Description - } - @foreach (var log in gc.LogContext.All()) - { - if (log.HasException) - { - - } - else - { -
          @Raw(log.Details)
          - } - if (log.HasScreenCapture) - { -
          @Raw(log.ScreenCaptureContext.FirstOrDefault().Source)
          - } - } -
        • - } -
        - } -
      • - } -
      - } -
      - } - } - else - { -
      - @test.StartTime - @test.EndTime - @test.RunDuration.ToString("''h'h:'m'm:'s's.'fff'ms'") -
      - if (!string.IsNullOrEmpty(test.Description)) - { -
      @test.Description
      - } - if (test.HasAuthor || test.HasCategory || test.HasDevice) - { -
      - @if (test.HasCategory) - { -
      - @foreach (var c in test.CategoryContext.All()) { @c.Name } -
      - } - @if (test.HasAuthor) - { -
      - @foreach (var a in test.AuthorContext.All()) { @a.Name } -
      - } - @if (test.HasDevice) - { -
      - @foreach (var d in test.DeviceContext.All()) { @d.Name } -
      - } -
      - } - if (test.HasLog) - { -
      - - - - - - - - - - @foreach (var log in test.LogContext.All()) - { - - - - - - } - -
      StatusTimestampDetails
      - @MaterialIcon.GetIcon(log.Status) - @log.Timestamp.ToString("HH:mm:ss") - @if (log.HasException) - { - - } - else - { - @Raw(log.Details) - } - @if (log.HasScreenCapture) - { - @Raw(log.ScreenCaptureContext.FirstOrDefault().Source) - } -
      -
      - } - if (test.HasChildren) - { -
        - @{var leaf = "";} - @foreach (var node in test.NodeContext.All()) - { - leaf = (node.HasChildren) ? "" : "leaf"; -
      • -
        -
        @node.Name
        - @node.StartTime - · @node.RunDuration.ToString("''h'h:'m'm:'s's.'fff'ms'") - @node.Status - @if (node.HasCategory) - { -
        - @foreach (var category in node.CategoryContext.All()) - { - @category.Name - } -
        - } -
        - @if (node.HasLog) - { -
        - @if (!string.IsNullOrEmpty(node.Description)) - { -
        @node.Description
        - } - @if (node.HasAuthor) - { -
        - @foreach (var author in node.AuthorContext.All()) - { - @author.Name - } -
        - } -
        - - - - - - - - - - @foreach (var log in node.LogContext.All()) - { - - - - - - } - -
        StatusTimestampDetails
        - @MaterialIcon.GetIcon(log.Status) - @log.Timestamp.ToString("HH:mm:ss") - @if (log.HasException) - { - - } - else - { - @Raw(log.Details) - } - @if (log.HasScreenCapture) - { - @Raw(log.ScreenCaptureContext.FirstOrDefault().Source) - } -
        -
        -
        - } - @if (@node.HasScreenCapture) - { -
          - @foreach (var sc in node.ScreenCaptureContext.All()) - { -
        • @sc.Source
        • - } -
        - } - @if (node.HasChildren) - { -
          - @foreach (var child in node.NodeContext.All()) - { - leaf = (child.HasChildren) ? "" : "leaf"; -
        • -
          -
          @child.Name
          - @child.StartTime - · @child.RunDuration.ToString("''h'h:'m'm:'s's.'fff'ms'") - @child.Status - @if (child.HasCategory) - { -
          - @foreach (var category in child.CategoryContext.All()) - { - @category.Name - } -
          - } -
          - @if (child.HasLog) - { -
          - @if (!string.IsNullOrEmpty(child.Description)) - { -
          @child.Description
          - } - @if (child.HasAuthor) - { -
          - @foreach (var author in child.AuthorContext.All()) - { - @author.Name - } -
          - } -
          - - - - - - - - - - @foreach (var log in child.LogContext.All()) - { - - - - - - } - -
          StatusTimestampDetails
          - @MaterialIcon.GetIcon(log.Status) - @log.Timestamp.ToString("HH:mm:ss") - @if (log.HasException) - { - - } - else - { - @Raw(log.Details) - } - @if (log.HasScreenCapture) - { - @Raw(log.ScreenCaptureContext.FirstOrDefault().Source) - } -
          -
          -
          - } - @if (@child.HasScreenCapture) - { -
            - @foreach (var sc in child.ScreenCaptureContext.All()) - { -
          • @sc.Source
          • - } -
          - } - @if (child.HasChildren) - { -
            - @foreach (var grandchild in child.NodeContext.All()) - { - leaf = (grandchild.HasChildren) ? "" : "leaf"; -
          • -
            -
            @grandchild.Name
            - @grandchild.StartTime - · @grandchild.RunDuration.ToString("''h'h:'m'm:'s's.'fff'ms'") - @grandchild.Status - @if (grandchild.HasCategory) - { -
            - @foreach (var category in grandchild.CategoryContext.All()) - { - @category.Name - } -
            - } -
            - @if (grandchild.HasLog) - { -
            - @if (!string.IsNullOrEmpty(grandchild.Description)) - { -
            @grandchild.Description
            - } - @if (grandchild.HasAuthor) - { -
            - @foreach (var author in grandchild.AuthorContext.All()) - { - @author.Name - } -
            - } -
            - - - - - - - - - - @foreach (var log in grandchild.LogContext.All()) - { - - - - - - } - -
            StatusTimestampDetails
            - @MaterialIcon.GetIcon(log.Status) - @log.Timestamp.ToString("HH:mm:ss") - @if (log.HasException) - { - - } - else - { - @Raw(log.Details) - } - @if (log.HasScreenCapture) - { - @Raw(log.ScreenCaptureContext.FirstOrDefault().Source) - } -
            - @if (@grandchild.HasScreenCapture) - { -
              - @foreach (var sc in grandchild.ScreenCaptureContext.All()) - { -
            • @sc.Source
            • - } -
            - } -
            -
            - } - @if (grandchild.HasChildren) - { -
              - -
            - } -
          • - } -
          - } -
        • - } -
        - } -
      • - } -
      - } - if (test.HasScreenCapture) - { -
        - @foreach (var sc in test.ScreenCaptureContext.All()) - { -
      • - @Raw(sc.Source) -
      • - } -
      - } - } -
      -
    • - } -
    -
    -
    - -
    -
    - @if (!bdd) - { - - } -
    -
    -
    - -
    - diff --git a/extentreports-dotnet-core/Views/V3Html/TestRunner/V3Logs.cshtml b/extentreports-dotnet-core/Views/V3Html/TestRunner/V3Logs.cshtml deleted file mode 100644 index 631e485..0000000 --- a/extentreports-dotnet-core/Views/V3Html/TestRunner/V3Logs.cshtml +++ /dev/null @@ -1,16 +0,0 @@ -@if (Model.TestRunnerLogs.Count > 0) -{ -
    -
    -
    TestRunner Logs
    - -
    - @foreach (var log in Model.TestRunnerLogs) - { - @Raw(log) - } -
    -
    -
    -} - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/V3Html/V3Head.cshtml b/extentreports-dotnet-core/Views/V3Html/V3Head.cshtml deleted file mode 100644 index a6ef984..0000000 --- a/extentreports-dotnet-core/Views/V3Html/V3Head.cshtml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - @Model.MasterConfig.GetValue("documentTitle") - - - - - diff --git a/extentreports-dotnet-core/Views/V3Html/V3Index.cshtml b/extentreports-dotnet-core/Views/V3Html/V3Index.cshtml deleted file mode 100644 index 07427b1..0000000 --- a/extentreports-dotnet-core/Views/V3Html/V3Index.cshtml +++ /dev/null @@ -1,94 +0,0 @@ -@using RazorEngine -@using RazorEngine.Templating - - @{ - var isbdd = false; - var cls = ""; - if (Model.TestList.Count > 0 && Model.TestList[0].IsBehaviorDrivenType) - { - isbdd = true; - cls = "bdd-report"; - } -} - - - - - @Include("V3Head") - - -
    - desktop_windows -
    - - @Include("V3Nav") - - -
    - @Include("V3Test") - @Include("V3Author") - @Include("V3Category") - @Include("V3Exception") - @Include("V3Dashboard") - @Include("V3Logs") -
    - - - @if (Model.MasterConfig.GetValue("enableTimeline") == "true") - { - var json = ""; - for (int ix = 0; ix < Model.TestList.Count; ix++) { - json += "\"" + Model.TestList[ix].Name + "\"" + ":" + Model.TestList[ix].RunDuration.TotalSeconds; - if (ix != Model.TestList.Count-1) { - json += ","; - } - } - - } - - @if (Model.MasterConfig.GetValue("chartVisibleOnOpen") == "false") - { - - } - - - \ No newline at end of file diff --git a/extentreports-dotnet-core/Views/V3Html/V3Nav.cshtml b/extentreports-dotnet-core/Views/V3Html/V3Nav.cshtml deleted file mode 100644 index 14d32e5..0000000 --- a/extentreports-dotnet-core/Views/V3Html/V3Nav.cshtml +++ /dev/null @@ -1,46 +0,0 @@ - \ No newline at end of file