├── .gitignore
├── LICENSE
├── README.md
├── bin
├── application
│ └── linux
└── pnunit
│ ├── agent
│ ├── agent.conf
│ ├── agent.log.conf
│ ├── launcher
│ ├── launcher.log.conf
│ ├── linuxtest.conf
│ ├── mactest.conf
│ └── wintest.conf
├── img
├── gui-testing-in-action-linux.gif
├── gui-testing-in-action-macos.gif
├── gui-testing-in-action-windows.gif
├── multiplatform-gui.png
└── windows-application.png
├── lib
├── log4net
│ └── log4net.dll
├── mono
│ └── Mono.Posix.dll
├── nunit
│ ├── nunit.core.dll
│ ├── nunit.core.interfaces.dll
│ ├── nunit.framework.dll
│ └── nunit.util.dll
└── pnunit
│ ├── agent
│ ├── AgentConfig.cs
│ ├── App.ico
│ ├── AssemblyPreload.cs
│ ├── ConfigureRemoting.cs
│ ├── OSProcessKillerCmd.cs
│ ├── PNUnitAgent.cs
│ ├── PlatformIdentifier.cs
│ ├── ProcessInfo.cs
│ ├── ProcessPool.cs
│ ├── Shell.cs
│ ├── TestConsoleAccess.cs
│ ├── agent.conf
│ ├── agent.cs
│ └── agent.csproj
│ ├── guitest
│ └── GuiTestRunner.cs
│ ├── launcher
│ ├── App.ico
│ ├── Barrier.cs
│ ├── CliArgsReader.cs
│ ├── Configurator.cs
│ ├── Launcher.cs
│ ├── LauncherArgs.cs
│ ├── LauncherStatus.cs
│ ├── LogWriter.cs
│ ├── MessageQueue.cs
│ ├── NUnitResultCollector.cs
│ ├── PNUnitService.cs
│ ├── Program.cs
│ ├── Runner.cs
│ ├── TestConf.cs
│ ├── TestsRun.cs
│ ├── automation
│ │ ├── LauncherService.cs
│ │ └── PNUnitAutomatedLauncher.cs
│ ├── filereport
│ │ ├── StatusReport.cs
│ │ └── TestLogReport.cs
│ ├── launcher.csproj
│ ├── launcherautomation
│ │ ├── FileReportConstants.cs
│ │ ├── ILauncher.cs
│ │ ├── TestRange.cs
│ │ ├── TestSuiteLoggerParams.cs
│ │ └── launcherautomation.csproj
│ ├── test.conf
│ └── testlogger
│ │ ├── TestSuiteEntry.cs
│ │ └── TestSuiteLogger.cs
│ ├── pnunit.framework
│ ├── Interfaces.cs
│ ├── PNUnitServices.cs
│ ├── ProcessNameSetter.cs
│ └── pnunit.framework.csproj
│ ├── pnunit.sln
│ ├── pnunittestrunner
│ ├── InitServices.cs
│ ├── NUnitTestRunner.cs
│ ├── PNUnitTestRunner.cs
│ ├── Program.cs
│ ├── TestInfoReader.cs
│ └── pnunittestrunner.csproj
│ └── testloggerinterface
│ ├── ITestLogger.cs
│ ├── TestLoggerClient.cs
│ └── testloggerinterface.csproj
└── src
├── application
├── gui
│ ├── linux
│ │ ├── ApplicationWindow.cs
│ │ ├── ErrorDialog.cs
│ │ ├── ExceptionsHandler.cs
│ │ ├── GtkGuiMessage.cs
│ │ ├── ProcessNameSetter.cs
│ │ ├── Program.cs
│ │ ├── WindowHandler.cs
│ │ ├── linux.csproj
│ │ ├── linux.sln
│ │ ├── testing
│ │ │ ├── TestHelper.cs
│ │ │ ├── TesteableApplicationWindow.cs
│ │ │ └── TesteableErrorDialog.cs
│ │ ├── threading
│ │ │ └── GtkApplicationTimer.cs
│ │ └── ui
│ │ │ ├── AlignmentBuilder.cs
│ │ │ ├── BaseDialog.cs
│ │ │ ├── CellContentRenderer.cs
│ │ │ ├── ControlBuilder.cs
│ │ │ ├── ControlPacker.cs
│ │ │ ├── GtkListView.cs
│ │ │ ├── Keyboard.cs
│ │ │ ├── Mouse.cs
│ │ │ ├── ProgressControls.cs
│ │ │ └── TreeBuilder.cs
│ ├── macos
│ │ ├── AppDelegate.cs
│ │ ├── ApplicationWindow.cs
│ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── AppIcon-128.png
│ │ │ │ ├── AppIcon-128@2x.png
│ │ │ │ ├── AppIcon-16.png
│ │ │ │ ├── AppIcon-16@2x.png
│ │ │ │ ├── AppIcon-256.png
│ │ │ │ ├── AppIcon-256@2x.png
│ │ │ │ ├── AppIcon-32.png
│ │ │ │ ├── AppIcon-32@2x.png
│ │ │ │ ├── AppIcon-512.png
│ │ │ │ ├── AppIcon-512@2x.png
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Entitlements.plist
│ │ ├── ExceptionsHandler.cs
│ │ ├── Info.plist
│ │ ├── MacOsGuiMessage.cs
│ │ ├── Main.cs
│ │ ├── Main.storyboard
│ │ ├── RemotingHack.cs
│ │ ├── ViewController.cs
│ │ ├── ViewController.designer.cs
│ │ ├── WindowHandler.cs
│ │ ├── macos.csproj
│ │ ├── macos.sln
│ │ ├── testing
│ │ │ ├── TestHelper.cs
│ │ │ ├── TesteableApplicationWindow.cs
│ │ │ └── TesteableErrorDialog.cs
│ │ ├── threading
│ │ │ └── MacApplicationTimer.cs
│ │ └── ui
│ │ │ ├── NSBuilder.cs
│ │ │ ├── NSColors.cs
│ │ │ ├── NSViewPacker.cs
│ │ │ └── ProgressControls.cs
│ └── windows
│ │ ├── App.config
│ │ ├── ApplicationWindow.cs
│ │ ├── ErrorDialog.cs
│ │ ├── ExceptionsHandler.cs
│ │ ├── Program.cs
│ │ ├── WindowHandler.cs
│ │ ├── WindowsGuiMessage.cs
│ │ ├── testing
│ │ ├── TestHelper.cs
│ │ ├── TesteableApplicationWindow.cs
│ │ └── TesteableErrorDialog.cs
│ │ ├── threading
│ │ └── WinApplicationTimer.cs
│ │ ├── ui
│ │ ├── ControlBuilder.cs
│ │ ├── ControlPacker.cs
│ │ └── ProgressControls.cs
│ │ ├── windows.csproj
│ │ └── windows.sln
└── lib
│ ├── ApplicationArgs.cs
│ ├── ApplicationOperations.cs
│ ├── IGuiMessage.cs
│ ├── Localization.cs
│ ├── interfaces
│ ├── IApplicationWindow.cs
│ └── IProgressControls.cs
│ ├── lib.csproj
│ └── threading
│ ├── ApplicationThread.cs
│ └── ApplicationThreadWaiter.cs
└── testing
├── guitest
├── ApplicationWindowTests.cs
├── OSVersionName.cs
├── PlatformUtils.cs
├── TestOperations.cs
├── WaitingAssert.cs
└── guitest.csproj
└── guitestinterfaces
├── GuiTesteableServices.cs
├── ITesteableApplicationWindow.cs
├── ITesteableErrorDialog.cs
└── guitestinterfaces.csproj
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Códice Software S.L.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/bin/application/linux:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
3 |
4 | mono $DIR/linux.exe "$@"
5 |
--------------------------------------------------------------------------------
/bin/pnunit/agent:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
3 |
4 | mono $DIR/agent.exe "$@"
5 |
--------------------------------------------------------------------------------
/bin/pnunit/agent.conf:
--------------------------------------------------------------------------------
1 |
2 | 8080
3 | .
4 |
5 |
--------------------------------------------------------------------------------
/bin/pnunit/agent.log.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/bin/pnunit/launcher:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
3 |
4 | mono $DIR/launcher.exe "$@"
5 |
--------------------------------------------------------------------------------
/bin/pnunit/launcher.log.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/bin/pnunit/linuxtest.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | BasicApplicationWindowTest
11 |
12 |
13 | linux:BasicApplicationWindowTest
14 | guitest.dll
15 | linux:GuiTest.ApplicationWindowTests.BasicApplicationWindowTest
16 | $host:$port
17 |
18 | ..\application
19 | --testing
20 |
21 |
22 |
23 |
24 |
25 |
26 | AddExistingElementTest
27 |
28 |
29 | linux:AddExistingElementTest
30 | guitest.dll
31 | linux:GuiTest.ApplicationWindowTests.AddExistingElementTest
32 | $host:$port
33 |
34 | ..\application
35 | --testing
36 |
37 |
38 |
39 |
40 |
41 |
42 | RemoveUnexistingElementTest
43 |
44 |
45 | linux:RemoveUnexistingElementTest
46 | guitest.dll
47 | linux:GuiTest.ApplicationWindowTests.RemoveUnexistingElementTest
48 | $host:$port
49 |
50 | ..\application
51 | --testing
52 |
53 |
54 |
55 |
56 |
57 |
58 | ThisTestWillFailAtTheEndTest
59 |
60 |
61 | linux:ThisTestWillFailAtTheEndTest
62 | guitest.dll
63 | linux:GuiTest.ApplicationWindowTests.ThisTestWillFailAtTheEndTest
64 | $host:$port
65 |
66 | ..\application
67 | --testing
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/bin/pnunit/mactest.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | BasicApplicationWindowTest
11 |
12 |
13 | mac:BasicApplicationWindowTest
14 | guitest.dll
15 | mac:GuiTest.ApplicationWindowTests.BasicApplicationWindowTest
16 | $host:$port
17 |
18 | ..\application
19 | --testing
20 |
21 |
22 |
23 |
24 |
25 |
26 | AddExistingElementTest
27 |
28 |
29 | mac:AddExistingElementTest
30 | guitest.dll
31 | mac:GuiTest.ApplicationWindowTests.AddExistingElementTest
32 | $host:$port
33 |
34 | ..\application
35 | --testing
36 |
37 |
38 |
39 |
40 |
41 |
42 | RemoveUnexistingElementTest
43 |
44 |
45 | mac:RemoveUnexistingElementTest
46 | guitest.dll
47 | mac:GuiTest.ApplicationWindowTests.RemoveUnexistingElementTest
48 | $host:$port
49 |
50 | ..\application
51 | --testing
52 |
53 |
54 |
55 |
56 |
57 |
58 | ThisTestWillFailAtTheEndTest
59 |
60 |
61 | mac:ThisTestWillFailAtTheEndTest
62 | guitest.dll
63 | mac:GuiTest.ApplicationWindowTests.ThisTestWillFailAtTheEndTest
64 | $host:$port
65 |
66 | ..\application
67 | --testing
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/bin/pnunit/wintest.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | BasicApplicationWindowTest
11 |
12 |
13 | windows:BasicApplicationWindowTest
14 | guitest.dll
15 | windows:GuiTest.ApplicationWindowTests.BasicApplicationWindowTest
16 | $host:$port
17 |
18 | ..\application
19 | --testing
20 |
21 |
22 |
23 |
24 |
25 |
26 | AddExistingElementTest
27 |
28 |
29 | windows:AddExistingElementTest
30 | guitest.dll
31 | windows:GuiTest.ApplicationWindowTests.AddExistingElementTest
32 | $host:$port
33 |
34 | ..\application
35 | --testing
36 |
37 |
38 |
39 |
40 |
41 |
42 | RemoveUnexistingElementTest
43 |
44 |
45 | windows:RemoveUnexistingElementTest
46 | guitest.dll
47 | windows:GuiTest.ApplicationWindowTests.RemoveUnexistingElementTest
48 | $host:$port
49 |
50 | ..\application
51 | --testing
52 |
53 |
54 |
55 |
56 |
57 |
58 | ThisTestWillFailAtTheEndTest
59 |
60 |
61 | windows:ThisTestWillFailAtTheEndTest
62 | guitest.dll
63 | windows:GuiTest.ApplicationWindowTests.ThisTestWillFailAtTheEndTest
64 | $host:$port
65 |
66 | ..\application
67 | --testing
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/img/gui-testing-in-action-linux.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/img/gui-testing-in-action-linux.gif
--------------------------------------------------------------------------------
/img/gui-testing-in-action-macos.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/img/gui-testing-in-action-macos.gif
--------------------------------------------------------------------------------
/img/gui-testing-in-action-windows.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/img/gui-testing-in-action-windows.gif
--------------------------------------------------------------------------------
/img/multiplatform-gui.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/img/multiplatform-gui.png
--------------------------------------------------------------------------------
/img/windows-application.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/img/windows-application.png
--------------------------------------------------------------------------------
/lib/log4net/log4net.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/lib/log4net/log4net.dll
--------------------------------------------------------------------------------
/lib/mono/Mono.Posix.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/lib/mono/Mono.Posix.dll
--------------------------------------------------------------------------------
/lib/nunit/nunit.core.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/lib/nunit/nunit.core.dll
--------------------------------------------------------------------------------
/lib/nunit/nunit.core.interfaces.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/lib/nunit/nunit.core.interfaces.dll
--------------------------------------------------------------------------------
/lib/nunit/nunit.framework.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/lib/nunit/nunit.framework.dll
--------------------------------------------------------------------------------
/lib/nunit/nunit.util.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/lib/nunit/nunit.util.dll
--------------------------------------------------------------------------------
/lib/pnunit/agent/AgentConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Xml.Serialization;
4 |
5 |
6 | namespace PNUnit.Agent
7 | {
8 | [Serializable]
9 | public class AgentConfig
10 | {
11 | public int Port;
12 | public string PathToAssemblies;
13 | public bool NoTimeout;
14 | }
15 |
16 | public class AgentConfigLoader
17 | {
18 | public static AgentConfig LoadFromFile(string file)
19 | {
20 | using (FileStream reader = new FileStream(file, FileMode.Open, FileAccess.Read))
21 | {
22 | XmlSerializer ser= new XmlSerializer(typeof(AgentConfig));
23 | return (AgentConfig) ser.Deserialize(reader);
24 | }
25 | }
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/lib/pnunit/agent/App.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/lib/pnunit/agent/App.ico
--------------------------------------------------------------------------------
/lib/pnunit/agent/AssemblyPreload.cs:
--------------------------------------------------------------------------------
1 | namespace PNUnit.Agent
2 | {
3 | public static class AssemblyPreload
4 | {
5 | public const string PRELOADED_ASSEMBLY = "cmtest.dll";
6 |
7 | public const string PRELOADED_PROCESS_FILE_PREFIX = "pnunit_";
8 |
9 | public static bool CanUsePreload(string assembly)
10 | {
11 | return assembly == PRELOADED_ASSEMBLY;
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/lib/pnunit/agent/ConfigureRemoting.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Collections;
4 | using System.Runtime.Remoting;
5 | using System.Runtime.Remoting.Channels;
6 | using System.Runtime.Remoting.Channels.Tcp;
7 | using System.Runtime.Serialization.Formatters;
8 |
9 | using log4net;
10 |
11 | namespace PNUnit.Agent
12 | {
13 | class ConfigureRemoting
14 | {
15 | internal static void Configure(int port)
16 | {
17 | mLog.InfoFormat("Registering channel");
18 |
19 | if (File.Exists("agent.remoting.conf"))
20 | {
21 | mLog.Info("Using agent.remoting.conf");
22 | RemotingConfiguration.Configure("agent.remoting.conf", false);
23 | return;
24 | }
25 |
26 | // init remoting
27 | BinaryClientFormatterSinkProvider clientProvider =
28 | new BinaryClientFormatterSinkProvider();
29 | BinaryServerFormatterSinkProvider serverProvider =
30 | new BinaryServerFormatterSinkProvider();
31 | serverProvider.TypeFilterLevel =
32 | System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
33 |
34 | IDictionary props = new Hashtable();
35 | props["port"] = port;
36 | string s = System.Guid.NewGuid().ToString();
37 | props["name"] = s;
38 | props["typeFilterLevel"] = TypeFilterLevel.Full;
39 | try
40 | {
41 | TcpChannel chan = new TcpChannel(
42 | props, clientProvider, serverProvider);
43 |
44 | mLog.InfoFormat("Registering channel on port {0}", port);
45 | ChannelServices.RegisterChannel(chan, false);
46 | //RemotingConfiguration.CustomErrorsMode = CustomErrorsModes.Off;
47 | }
48 | catch (Exception e)
49 | {
50 | mLog.InfoFormat("Can't register channel.\n{0}", e.Message);
51 | Console.WriteLine("Can't register channel.\n{0}", e.Message);
52 | throw;
53 | }
54 | }
55 |
56 | static readonly ILog mLog = LogManager.GetLogger("ConfigureRemoting");
57 | }
58 | }
--------------------------------------------------------------------------------
/lib/pnunit/agent/OSProcessKillerCmd.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Diagnostics;
3 |
4 | using log4net;
5 |
6 | namespace Codice.Test
7 | {
8 | public static class OSProcessKillerCmd
9 | {
10 | public static void KillProcessTree(string pid)
11 | {
12 | if (PlatformIdentifier.IsWindows())
13 | {
14 | KillProcessForcedWindows(pid, true);
15 | return;
16 | }
17 |
18 | KillProcessTreeUnix(pid);
19 | }
20 |
21 | public static void KillProcess(string pid)
22 | {
23 | if (PlatformIdentifier.IsWindows())
24 | {
25 | KillProcessForcedWindows(pid, false);
26 | return;
27 | }
28 |
29 | KillProcessForcedUnix(pid);
30 | }
31 |
32 | static void KillProcessForcedWindows(string pid, bool bHasToKillProcessTree)
33 | {
34 | string processName = "taskkill";
35 | string killTreeArg = bHasToKillProcessTree ? "/T" : string.Empty;
36 |
37 | string args = string.Format("/F {0} /PID {1}", killTreeArg, pid);
38 |
39 | mLog.DebugFormat("executing [{0} {1}]", processName, args);
40 |
41 | using (Process taskKill = new Process())
42 | {
43 | taskKill.StartInfo.FileName = processName;
44 | taskKill.StartInfo.Arguments = args;
45 | taskKill.StartInfo.CreateNoWindow = true;
46 | taskKill.StartInfo.UseShellExecute = false;
47 | taskKill.Start();
48 | taskKill.WaitForExit(PROCESS_MAX_WAIT_EXIT_MILLIS);
49 | }
50 | }
51 |
52 | static void KillProcessTreeUnix(string pid)
53 | {
54 | List pids = new List();
55 | GetChildProcesses(pid, pids);
56 |
57 | string args = string.Join(" ", pids.ToArray());
58 | KillProcessForcedUnix(args);
59 | }
60 |
61 | static void KillProcessForcedUnix(string pidsArg)
62 | {
63 | mLog.DebugFormat("executing [{0} {1}]", "kill -9", pidsArg);
64 |
65 | using (Process kill = Process.Start("kill", "-9 " + pidsArg))
66 | {
67 | kill.WaitForExit(PROCESS_MAX_WAIT_EXIT_MILLIS);
68 | }
69 | }
70 |
71 | static void GetChildProcesses(string requestedPid, List outChildPids)
72 | {
73 | outChildPids.Add(requestedPid);
74 |
75 | foreach (string childPid in ProcessInfo.UnixGetChildrenPids(requestedPid))
76 | GetChildProcesses(childPid, outChildPids);
77 | }
78 |
79 | const int PROCESS_MAX_WAIT_EXIT_MILLIS = 2000;
80 |
81 | static readonly ILog mLog = LogManager.GetLogger("ProcessKiller");
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/lib/pnunit/agent/PlatformIdentifier.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Codice.Test
4 | {
5 | public class PlatformIdentifier
6 | {
7 | private static bool bIsWindowsInitialized = false;
8 | private static bool bIsWindows = false;
9 | public static bool IsWindows()
10 | {
11 | if( !bIsWindowsInitialized )
12 | {
13 | switch (Environment.OSVersion.Platform)
14 | {
15 | case PlatformID.Win32Windows:
16 | case PlatformID.Win32NT:
17 | bIsWindows = true;
18 | break;
19 | }
20 | bIsWindowsInitialized = true;
21 | }
22 | return bIsWindows;
23 | }
24 |
25 | private static bool bIsMacInitialized = false;
26 | private static bool bIsMac = false;
27 | public static bool IsMac()
28 | {
29 | if (!bIsMacInitialized)
30 | {
31 | if (!IsWindows())
32 | {
33 | // The first versions of the framework (1.0 and 1.1)
34 | // didn't include any PlatformID value for Unix,
35 | // so Mono used the value 128. The newer framework 2.0
36 | // added Unix to the PlatformID enum but,
37 | // sadly, with a different value: 4 and newer versions of
38 | // .NET distinguished between Unix and MacOS X,
39 | // introducing yet another value 6 for MacOS X.
40 |
41 | System.Version v = Environment.Version;
42 | int p = (int) Environment.OSVersion.Platform;
43 |
44 | if( (v.Major >= 3 && v.Minor >= 5) ||
45 | (IsRunningUnderMono() && v.Major >= 2 && v.Minor >= 2))
46 | {
47 | //MacOs X exist in the enumeration
48 | bIsMac = p == 6;
49 | }
50 | else
51 | {
52 | if ((p == 4) || (p == 128))
53 | {
54 | int major = Environment.OSVersion.Version.Major;
55 | //18.x.x macOS 10.14.x Mojave
56 | //17.x.x macOS 10.13.x High Sierra
57 | //16.x.x macOS 10.12.x Sierra
58 | //15.x.x OS X 10.11.x El Capitan
59 | //14.x.x OS X 10.10.x Yosemite
60 | //13.x.x OS X 10.9.x Mavericks
61 | //12.x.x OS X 10.8.x Mountain Lion
62 | //11.x.x OS X 10.7.x Lion
63 | //10.x.x OS X 10.6.x Snow Leopard
64 | //9.x.x OS X 10.5.x Leopard
65 | //8.x.x OS X 10.4.x Tiger
66 | // DAVE: this is not very nice, as it may conflict
67 | // on other OS like solaris or aix.
68 | bIsMac = major >= 8;
69 | }
70 | }
71 | }
72 |
73 | bIsMacInitialized = true;
74 | }
75 |
76 | return bIsMac;
77 | }
78 |
79 |
80 | private static bool IsRunningUnderMono()
81 | {
82 | Type t = Type.GetType("Mono.Runtime");
83 |
84 | return (t != null);
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/lib/pnunit/agent/TestConsoleAccess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | using PNUnit.Framework;
5 |
6 | namespace PNUnit.Agent
7 | {
8 | public class TestLogInfo : MarshalByRefObject, ITestLogInfo
9 | {
10 | public string OSVersion = string.Empty;
11 | public string BackendType = string.Empty;
12 |
13 | public void SetOSVersion(string s)
14 | {
15 | OSVersion = s;
16 | }
17 |
18 | public void SetBackendType(string s)
19 | {
20 | BackendType = s;
21 | }
22 | }
23 |
24 | public class TestConsoleAccess : MarshalByRefObject, ITestConsoleAccess
25 | {
26 | public TestConsoleAccess(string outputFile)
27 | {
28 | mOutputFilePath = outputFile;
29 | }
30 |
31 | public void WriteLine(string s)
32 | {
33 | if (mStoreOutputEnabled)
34 | AppendOutputTest(s);
35 |
36 | if(mConsoleEnabled)
37 | Console.WriteLine(s);
38 | }
39 |
40 | public void Write(char[] buf)
41 | {
42 | if (mStoreOutputEnabled)
43 | AppendOutputTest(buf);
44 |
45 | if (mConsoleEnabled)
46 | Console.Write(buf);
47 | }
48 |
49 | public void Clear()
50 | {
51 | using (StreamWriter sw = new StreamWriter(mOutputFilePath, false))
52 | {
53 | sw.WriteLine();
54 | }
55 | }
56 |
57 | public override object InitializeLifetimeService()
58 | {
59 | return null;
60 | }
61 |
62 | internal static void EnableConsole()
63 | {
64 | mConsoleEnabled = true;
65 | }
66 |
67 | internal static void DisableConsole()
68 | {
69 | mConsoleEnabled = false;
70 | }
71 |
72 | internal static void EnableStoreOutput()
73 | {
74 | mStoreOutputEnabled = true;
75 | }
76 |
77 | internal static void DisableStoreOutput()
78 | {
79 | mStoreOutputEnabled = false;
80 | }
81 |
82 | private void AppendOutputTest(string text)
83 | {
84 | using (StreamWriter sw = new StreamWriter(mOutputFilePath, true))
85 | {
86 | sw.WriteLine(text);
87 | }
88 | }
89 |
90 | private void AppendOutputTest(char[] buf)
91 | {
92 | using (StreamWriter sw = new StreamWriter(mOutputFilePath, true))
93 | {
94 | sw.WriteLine(buf);
95 | }
96 | }
97 |
98 | string mOutputFilePath;
99 | static bool mConsoleEnabled = true;
100 | static bool mStoreOutputEnabled = true;
101 | }
102 | }
--------------------------------------------------------------------------------
/lib/pnunit/agent/agent.conf:
--------------------------------------------------------------------------------
1 |
2 | 8080
3 | .
4 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/App.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/lib/pnunit/launcher/App.ico
--------------------------------------------------------------------------------
/lib/pnunit/launcher/Barrier.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 |
4 | namespace PNUnit.Launcher
5 | {
6 | public class Barrier
7 | {
8 | public int mCount;
9 | public int mMaxCount;
10 | private Object mLock = new Object();
11 | private string mName;
12 |
13 | private static int MAX_WAIT_TIME = 600 * 1000; //milliseconds - 10 minutes
14 | public static void SetMaxWaitTime(int seconds)
15 | {
16 | MAX_WAIT_TIME = seconds * 1000;
17 | }
18 |
19 | public Barrier(string name, int maxCount)
20 | {
21 | mCount = 0;
22 | mName = name;
23 | mMaxCount = maxCount;
24 | }
25 |
26 | public void Enter()
27 | {
28 | lock( mLock )
29 | {
30 | ++mCount;
31 | if( mCount == mMaxCount )
32 | {
33 | Monitor.PulseAll(mLock);
34 | }
35 | else if( mCount < mMaxCount )
36 | {
37 | if (!Monitor.Wait(mLock, MAX_WAIT_TIME))
38 | {
39 | Console.WriteLine("Barrier {0} abandoned due to timeout!!!",
40 | mName);
41 | }
42 | }
43 | else
44 | {
45 | //nothing to do, entering in a barrier already used
46 | }
47 | }
48 | }
49 |
50 | public void Abandon()
51 | {
52 | lock( mLock )
53 | {
54 | --mMaxCount;
55 | if( mCount >= mMaxCount )
56 | {
57 | mCount = 0;
58 | Monitor.PulseAll(mLock);
59 | }
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/Configurator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.IO;
4 | using System.Runtime.Remoting.Channels;
5 | using System.Runtime.Remoting.Channels.Tcp;
6 | using System.Runtime.Serialization.Formatters;
7 | using System.Reflection;
8 |
9 | using log4net;
10 | using log4net.Config;
11 |
12 | namespace PNUnit.Launcher
13 | {
14 | internal class Configurator
15 | {
16 | internal static bool ConfigureRemoting(int port, string ipToBind)
17 | {
18 | BinaryClientFormatterSinkProvider clientProvider = null;
19 | BinaryServerFormatterSinkProvider serverProvider =
20 | new BinaryServerFormatterSinkProvider();
21 | serverProvider.TypeFilterLevel =
22 | System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
23 |
24 | IDictionary props = new Hashtable();
25 | props["port"] = port;
26 | props["typeFilterLevel"] = TypeFilterLevel.Full;
27 |
28 | if (!string.IsNullOrEmpty(ipToBind))
29 | {
30 | mLog.InfoFormat("Binding the ip to {0}", ipToBind);
31 | props["bindTo"] = ipToBind;
32 | }
33 |
34 | try
35 | {
36 | TcpChannel chan = new TcpChannel(
37 | props, clientProvider, serverProvider);
38 |
39 | mLog.DebugFormat("Registering channel on port {0}", port);
40 | ChannelServices.RegisterChannel(chan, false);
41 | return true;
42 | }
43 | catch (Exception e)
44 | {
45 | mLog.InfoFormat("Can't register channel.\n{0}", e.Message);
46 | return false;
47 | }
48 | }
49 |
50 | internal static void ConfigureLogging(
51 | bool bIsAutomatedLauncher, string customLogOutputPath)
52 | {
53 | string logConfFileName = "launcher.log.conf";
54 |
55 | if (bIsAutomatedLauncher)
56 | logConfFileName = "automated" + logConfFileName;
57 |
58 | if (!File.Exists(logConfFileName))
59 | {
60 | logConfFileName = GetConfigFilePath(logConfFileName);
61 | }
62 |
63 | // the following property must be declared in the "file" tag in .log.conf appenders:
64 | // "%property{LogFolder}"
65 | log4net.GlobalContext.Properties["LogFolder"] = customLogOutputPath;
66 |
67 | XmlConfigurator.Configure(new FileInfo(logConfFileName));
68 | }
69 |
70 | static string GetConfigFilePath(string fileName)
71 | {
72 | return Path.Combine(GetAppPath(), fileName);
73 | }
74 |
75 | static string GetAppPath()
76 | {
77 | return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
78 | }
79 |
80 | static readonly ILog mLog = LogManager.GetLogger("launcher");
81 | }
82 | }
--------------------------------------------------------------------------------
/lib/pnunit/launcher/LauncherArgs.cs:
--------------------------------------------------------------------------------
1 | namespace PNUnit.Launcher
2 | {
3 | internal class LauncherArgs
4 | {
5 | internal string ConfigFile;
6 | internal string ResultLogFile;
7 | internal string ErrorLogFile;
8 | internal string ResultFile = null;
9 | internal string FailedConfigFile = null;
10 | internal int RetryOnFailure = 0;
11 | internal int MaxRetry = DEFAULT_TEST_RETRY;
12 | internal bool ShellMode = false;
13 | internal TestRange TestRange = null;
14 | internal int TestsTimeout = 0;
15 | internal string ListTestsFile;
16 | internal string UseFileReport;
17 |
18 | const int DEFAULT_TEST_RETRY = 3;
19 | }
20 | }
--------------------------------------------------------------------------------
/lib/pnunit/launcher/LauncherStatus.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace PNUnit.Launcher
4 | {
5 | internal class LauncherStatus
6 | {
7 | internal int TestCount;
8 | internal int TestToExecuteCount;
9 | internal int CurrentTest;
10 | internal int ExecutedTests;
11 | internal string CurrentTestName;
12 | internal string WarningMsg;
13 |
14 | internal LauncherStatus(int testCount, int testToExecuteCount)
15 | {
16 | TestCount = testCount;
17 | TestToExecuteCount = testToExecuteCount;
18 | }
19 |
20 | internal void SetCurrentTestName(string testName)
21 | {
22 | CurrentTestName = testName;
23 | }
24 |
25 | internal void SetWarningMessage(string warningMessage)
26 | {
27 | WarningMsg = warningMessage;
28 | }
29 |
30 | internal List GetRepeatedTests()
31 | {
32 | lock (this)
33 | {
34 | return new List(mRepeatedTests);
35 | }
36 | }
37 |
38 | internal List GetFailedTests()
39 | {
40 | lock (this)
41 | {
42 | return new List(mFailedTests);
43 | }
44 | }
45 |
46 | internal List GetIgnoredTests()
47 | {
48 | lock (this)
49 | {
50 | return new List(mIgnoredTests);
51 | }
52 | }
53 |
54 | internal void Increment()
55 | {
56 | ++CurrentTest;
57 | }
58 |
59 | internal void IncrementExecuted()
60 | {
61 | ++ExecutedTests;
62 | }
63 |
64 | internal void AddFailed(string failed)
65 | {
66 | lock (this)
67 | {
68 | if (mFailedTests.Contains(failed))
69 | return;
70 |
71 | mFailedTests.Add(failed);
72 | }
73 | }
74 |
75 | internal void AddIgnored(string ignored)
76 | {
77 | lock (this)
78 | {
79 | if (mIgnoredTests.Contains(ignored))
80 | return;
81 |
82 | mIgnoredTests.Add(ignored);
83 | }
84 | }
85 |
86 | internal void AddRepeated(string repeated)
87 | {
88 | lock (this)
89 | {
90 | if (mRepeatedTests.Contains(repeated))
91 | return;
92 |
93 | mRepeatedTests.Add(repeated);
94 | }
95 | }
96 |
97 | internal void UpdateProgress(
98 | int runTestsCount, int totalTestCount,
99 | List failed, List ignored)
100 | {
101 | lock (this)
102 | {
103 | CurrentTest = runTestsCount;
104 | ExecutedTests = runTestsCount;
105 | TestCount = totalTestCount;
106 | TestToExecuteCount = totalTestCount;
107 | mFailedTests = failed;
108 | mIgnoredTests = ignored;
109 | }
110 | }
111 |
112 | List mRepeatedTests = new List();
113 | List mFailedTests = new List();
114 | List mIgnoredTests = new List();
115 | }
116 | }
--------------------------------------------------------------------------------
/lib/pnunit/launcher/NUnitResultCollector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 |
4 | using NUnit.Core;
5 | using NUnit.Util;
6 |
7 |
8 | namespace PNUnit.Launcher
9 | {
10 | class NUnitResultCollector
11 | {
12 | private ArrayList mResultList = new ArrayList();
13 |
14 | internal void AddResults(TestResult[] results)
15 | {
16 | mResultList.AddRange(results);
17 | }
18 |
19 | internal void SaveResults(string fileName)
20 | {
21 | TestResult all = new TestResult(new TestName());
22 |
23 | foreach (TestResult r in mResultList) all.AddResult(r);
24 |
25 | new XmlResultWriter(fileName).SaveTestResult(all);
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/TestsRun.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | using NUnit.Core;
6 |
7 | using PNUnit.Framework;
8 |
9 | namespace PNUnit.Launcher
10 | {
11 | internal class TestsRun
12 | {
13 | internal bool PendingTestsToFinish()
14 | {
15 | lock (mResultLock)
16 | {
17 | return (mLaunchedTests > 0) && (mResults.Count < mLaunchedTests);
18 | }
19 | }
20 |
21 | internal bool IsTestExecuted(string name)
22 | {
23 | lock (mResultLock)
24 | {
25 | return mExecutedTests.Contains(name);
26 | }
27 | }
28 |
29 | internal TestResult[] GetTestResults()
30 | {
31 | lock (mResultLock)
32 | {
33 | TestResult[] result = new TestResult[mResults.Count];
34 | int i = 0;
35 | foreach (TestResult res in mResults)
36 | result[i++] = res;
37 |
38 | return result;
39 | }
40 | }
41 |
42 | internal void IncrementTestsLaunched()
43 | {
44 | lock (mResultLock)
45 | {
46 | ++mLaunchedTests;
47 | }
48 | }
49 |
50 | internal void DecrementTestsLaunched()
51 | {
52 | lock (mResultLock)
53 | {
54 | --mLaunchedTests;
55 | }
56 | }
57 |
58 | internal int LaunchedCount
59 | {
60 | get
61 | {
62 | lock (mResultLock)
63 | {
64 | return mLaunchedTests;
65 | }
66 | }
67 | }
68 |
69 | internal void AddExecutedTest(string testName)
70 | {
71 | lock (mResultLock)
72 | {
73 | mExecutedTests.Add(testName);
74 | }
75 | }
76 |
77 | internal void AddTestResult(PNUnitTestResult testResult)
78 | {
79 | lock (mResultLock)
80 | {
81 | mResults.Add(testResult);
82 | }
83 | }
84 |
85 | internal bool AllTestsFinished()
86 | {
87 | lock (mResultLock)
88 | {
89 | return mResults.Count == mLaunchedTests;
90 | }
91 | }
92 |
93 | internal int TestsResultsCount
94 | {
95 | get
96 | {
97 | lock (mResultLock)
98 | {
99 | return mResults.Count;
100 | }
101 | }
102 | }
103 |
104 | Object mResultLock = new Object();
105 | int mLaunchedTests = 0;
106 | List mExecutedTests = new List();
107 | List mResults = new List();
108 | }
109 | }
--------------------------------------------------------------------------------
/lib/pnunit/launcher/automation/LauncherService.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 |
5 | using log4net;
6 |
7 | namespace PNUnit.Launcher.Automation
8 | {
9 | class LauncherService: MarshalByRefObject, ILauncher
10 | {
11 | public LauncherService(string ipToBind, int port)
12 | {
13 | mListenAddress = string.Format("{0}:{1}", ipToBind, port);
14 | }
15 |
16 | // live forever
17 | public override object InitializeLifetimeService()
18 | {
19 | return null;
20 | }
21 |
22 | public string RunTest(
23 | string testFile,
24 | List testsToRun,
25 | string resultLogFile,
26 | string errorLogFile,
27 | string failedConfFile,
28 | int numRetriesOnFailure,
29 | TestSuiteLoggerParams loggerParams,
30 | TestRange testRange,
31 | List cliArgs,
32 | int testTimeout)
33 | {
34 | mLog.InfoFormat("Request to run tests on file [{0}]", testFile);
35 |
36 | if (mAutomatedLauncher != null)
37 | {
38 | string msg = "Can't launch another test suite because a test suite is currently running";
39 | mLog.Error(msg);
40 | return msg;
41 | }
42 |
43 | mAutomatedLauncher = new PNUnitAutomatedLauncher(mListenAddress);
44 |
45 | return mAutomatedLauncher.RunTest(
46 | testFile,
47 | testsToRun,
48 | resultLogFile,
49 | errorLogFile,
50 | failedConfFile,
51 | numRetriesOnFailure,
52 | loggerParams,
53 | testRange,
54 | cliArgs == null ? null : cliArgs.ToArray(),
55 | testTimeout);
56 | }
57 |
58 | public AutomatedLauncherStatus GetStatus()
59 | {
60 | mLog.DebugFormat("GetStatus invoked");
61 |
62 | if (mAutomatedLauncher == null)
63 | {
64 | return new AutomatedLauncherStatus();
65 | }
66 |
67 | return mAutomatedLauncher.GetStatus();
68 | }
69 |
70 | public void Exit()
71 | {
72 | CanExit = true;
73 | }
74 |
75 | public bool CanExit = false;
76 |
77 | string mListenAddress;
78 |
79 | PNUnitAutomatedLauncher mAutomatedLauncher = null;
80 |
81 | static readonly ILog mLog = LogManager.GetLogger("AutomatedLauncher");
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/filereport/StatusReport.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 |
5 | using log4net;
6 |
7 | using PNUnit.Launcher.Automation;
8 |
9 | namespace PNUnit.Launcher.FileReport
10 | {
11 | internal static class StatusReport
12 | {
13 | internal static void Write(
14 | string file, LauncherStatus status, bool bFinished)
15 | {
16 | string content = GetContent(status, bFinished);
17 |
18 | int retries = 0;
19 | while (true)
20 | {
21 | try
22 | {
23 | File.WriteAllText(file, content);
24 | return;
25 | }
26 | catch(Exception e)
27 | {
28 | mLog.Info("The status file cannot be written. Error: " + e.Message);
29 | if (retries++ > 10)
30 | return;
31 |
32 | System.Threading.Thread.Sleep(500);
33 | continue;
34 | }
35 | }
36 | }
37 |
38 | static string GetContent(LauncherStatus status, bool bFinished)
39 | {
40 | return string.Join(FileReportConstants.FIELD_SEPARATOR, new string[] {
41 | status.TestCount.ToString(),
42 | status.TestToExecuteCount.ToString(),
43 | status.CurrentTestName,
44 | status.CurrentTest.ToString(),
45 | status.ExecutedTests.ToString(),
46 | string.Join(FileReportConstants.LIST_SEPARATOR, status.GetRepeatedTests().ToArray()),
47 | string.Join(FileReportConstants.LIST_SEPARATOR, status.GetFailedTests().ToArray()),
48 | string.Join(FileReportConstants.LIST_SEPARATOR, status.GetIgnoredTests().ToArray()),
49 | status.WarningMsg,
50 | bFinished.ToString()});
51 | }
52 |
53 | static readonly ILog mLog = LogManager.GetLogger("launcher");
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/filereport/TestLogReport.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Text;
5 |
6 | namespace PNUnit.Launcher.FileReport
7 | {
8 | internal static class TestLogReport
9 | {
10 | internal static void LogTest(
11 | string file,
12 | TestSuiteEntry.Data entry,
13 | string testName,
14 | bool isRepeated)
15 | {
16 | string contents = string.Join(FileReportConstants.TEST_FIELD_SEPARATOR, new string[] {
17 | testName,
18 | entry.BackendType,
19 | entry.ClientConfig,
20 | entry.ServerConfig,
21 | entry.ExecTime.ToString(),
22 | entry.Status,
23 | entry.Log,
24 | isRepeated.ToString()});
25 |
26 | File.AppendAllText(file, contents + FileReportConstants.TEST_SEPARATOR);
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/launcherautomation/FileReportConstants.cs:
--------------------------------------------------------------------------------
1 | namespace PNUnit.Launcher.FileReport
2 | {
3 | public class FileReportConstants
4 | {
5 | public const string FIELD_SEPARATOR = "@#@";
6 | public const string LIST_SEPARATOR = "#$#";
7 |
8 | public const string TEST_FIELD_SEPARATOR = ".@#@.";
9 | public const string TEST_SEPARATOR = "#$@%@$#\n";
10 |
11 | public const string LOG_FILE_EXTENSION = ".log";
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/launcherautomation/ILauncher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text;
4 | using System.Collections.Generic;
5 |
6 | using System.Security.Permissions;
7 | using System.Runtime.Serialization;
8 | using System.Runtime.Serialization.Formatters.Binary;
9 |
10 | namespace PNUnit.Launcher.Automation
11 | {
12 | public interface ILauncher
13 | {
14 | string RunTest(
15 | string testFile,
16 | List testsToRun,
17 | string resultLogFile,
18 | string errorLogFile,
19 | string failedConfFile,
20 | int numRetriesOnFailure,
21 | TestSuiteLoggerParams loggerParams,
22 | TestRange testRange,
23 | List cliArgs,
24 | int testTimeout);
25 |
26 | AutomatedLauncherStatus GetStatus();
27 |
28 | void Exit();
29 | }
30 |
31 | [Serializable]
32 | public class AutomatedLauncherStatus
33 | {
34 | public int TestCount;
35 | public int TestToExecuteCount;
36 | public int CurrentTest;
37 | public int ExecutedTests;
38 | public string CurrentTestName = string.Empty;
39 | public List RepeatedTests = new List();
40 | public List FailedTests = new List();
41 | public List IgnoredTests = new List();
42 | public bool Finished = false;
43 | public string WarningMsg = string.Empty;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/launcherautomation/TestRange.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace PNUnit.Launcher
4 | {
5 | [Serializable]
6 | public class TestRange
7 | {
8 | public int StartTest = 0;
9 | public int EndTest = 0;
10 |
11 | public static TestRange FromString(string range)
12 | {
13 | if (string.IsNullOrEmpty(range))
14 | return null;
15 |
16 | // format 0-15 or 80-
17 | string[] parts = range.Split('-');
18 |
19 | if (parts.Length < 1)
20 | return null;
21 |
22 | int ini;
23 |
24 | if (!int.TryParse(parts[0], out ini))
25 | return null;
26 |
27 | if (parts[1] == string.Empty ||
28 | parts[1].Equals("LAST", StringComparison.InvariantCultureIgnoreCase))
29 | return new TestRange(ini, LAST);
30 |
31 | int end;
32 |
33 | if (!int.TryParse(parts[1], out end))
34 | return null;
35 |
36 | return new TestRange(ini, end);
37 | }
38 |
39 | public TestRange(int ini, int end)
40 | {
41 | SetTestRange(ini, end);
42 | }
43 |
44 | public void SetTestRange(int ini, int end)
45 | {
46 | StartTest = ini;
47 | EndTest = end;
48 | }
49 |
50 | public void ResetTestRange()
51 | {
52 | SetTestRange(0, 0);
53 | }
54 |
55 | public override string ToString()
56 | {
57 | string end = (EndTest == LAST) ? "LAST" : string.Format("{0}", EndTest);
58 | return string.Format("{0}-{1}", StartTest, end);
59 | }
60 |
61 | public const int LAST = int.MaxValue;
62 | }
63 | }
--------------------------------------------------------------------------------
/lib/pnunit/launcher/launcherautomation/TestSuiteLoggerParams.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace PNUnit.Launcher
6 | {
7 | [Serializable]
8 | public class TestSuiteLoggerParams
9 | {
10 | public TestSuiteLoggerParams(
11 | string buildType,
12 | string buildName,
13 | int cset,
14 | string buildComment,
15 | string suiteType,
16 | string suiteName,
17 | string host,
18 | string vmachine,
19 | bool bLogSuccess)
20 | {
21 | mbInitialized = true;
22 |
23 | mBuildType = buildType;
24 | mBuildName = buildName;
25 | mCset = cset;
26 | mBuildComment = buildComment;
27 | mSuiteType = suiteType;
28 | mSuiteName = suiteName;
29 | mHost = host;
30 | mVMachine = vmachine;
31 | mbLogSuccess = bLogSuccess;
32 | }
33 |
34 | public TestSuiteLoggerParams()
35 | {
36 | mbInitialized = false;
37 | }
38 |
39 | public bool IsInitialized()
40 | {
41 | return mbInitialized;
42 | }
43 |
44 | public string BuildType { get { return mBuildType; } }
45 | public string BuildName { get { return mBuildName; } }
46 | public int Cset { get { return mCset; } }
47 | public string Comment { get { return mBuildComment; } }
48 | public string SuiteType { get { return mSuiteType; } }
49 | public string SuiteName { get { return mSuiteName; } }
50 | public string Host { get { return mHost; } }
51 | public string VMachine { get { return mVMachine; } }
52 | public bool LogSuccessfulTests { get { return mbLogSuccess; } }
53 |
54 | string mBuildType;
55 | string mBuildName;
56 | int mCset;
57 | string mBuildComment;
58 | string mSuiteType;
59 | string mSuiteName;
60 | string mHost;
61 | string mVMachine;
62 | bool mbLogSuccess;
63 | bool mbInitialized;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/launcherautomation/launcherautomation.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | true
5 | bin\x86\Debug\
6 | DEBUG;TRACE
7 | full
8 | x86
9 | prompt
10 | false
11 |
12 |
13 | bin\x86\Release\
14 | TRACE
15 | true
16 | pdbonly
17 | x86
18 | prompt
19 | false
20 | false
21 |
22 |
23 |
24 | Debug
25 | AnyCPU
26 | {50BB6499-3821-4786-B9AD-9DDADB1A14FA}
27 | Library
28 | Properties
29 | launcherautomation
30 | launcherautomation
31 | v2.0
32 | 512
33 |
34 | PlasticSCM
35 | PlasticSCM
36 | PlasticSCM
37 | Plastic SCM Source Control Service:{774e58ba-f1b9-40a7-b676-834fa2c220fe}
38 |
39 |
40 | true
41 | full
42 | false
43 | ..\..\..\..\bin\pnunit\
44 | DEBUG;TRACE
45 | prompt
46 | 4
47 |
48 |
49 | pdbonly
50 | true
51 | bin\Release\
52 | TRACE
53 | prompt
54 | 4
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
76 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/test.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | First test group
5 |
6 |
7 | Test name
8 | Test assembly
9 | Fully qualified test name
10 | host:port
11 |
12 | fill me up!
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/testlogger/TestSuiteEntry.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | using NUnit.Core;
5 |
6 | using PNUnit.Framework;
7 |
8 | namespace PNUnit.Launcher
9 | {
10 | internal static class TestSuiteEntry
11 | {
12 | internal class Data
13 | {
14 | internal string ServerConfig = string.Empty;
15 | internal string BackendType = string.Empty;
16 | internal string ClientConfig = string.Empty;
17 | internal int ExecTime = 0;
18 | internal string Status = FAILURE_STATUS;
19 | internal string Log = string.Empty;
20 | }
21 |
22 | internal static Data Calculate(
23 | TestResult[] testResults, bool bLogSuccessful)
24 | {
25 | Data result = new Data();
26 |
27 | foreach (PNUnitTestResult tr in testResults)
28 | {
29 | if (string.IsNullOrEmpty(tr.BackendType))
30 | {
31 | //: client test
32 | result.ClientConfig = tr.OSVersion;
33 | result.ExecTime = (int)Math.Round(tr.Time);
34 | result.Status = tr.ResultState.ToString();
35 |
36 | if (tr.Killed)
37 | result.Status = KILLED_STATUS;
38 |
39 | if (bLogSuccessful || tr.ResultState != ResultState.Success)
40 | {
41 | result.Log += CollectOutput(tr);
42 | result.Log = result.Log.Replace("'", "''").Replace("\"", "''");
43 | }
44 | }
45 | else
46 | {
47 | //: server test
48 | result.ServerConfig = tr.OSVersion;
49 | result.BackendType = tr.BackendType;
50 | }
51 |
52 | if (tr.ResultState != ResultState.Success &&
53 | tr.ResultState != ResultState.Ignored)
54 | {
55 | result.Log += "---------------------------";
56 | result.Log += "ERROR: " + tr.Message;
57 | result.Log += "---------------------------";
58 | }
59 | }
60 | return result;
61 | }
62 |
63 | static string CollectOutput(PNUnitTestResult tr)
64 | {
65 | StringBuilder sb = new StringBuilder();
66 | sb.Append(tr.Output);
67 |
68 | if (tr.Results != null && tr.Results.Count > 0)
69 | foreach (TestResult child in tr.Results)
70 | DoCollectOutput(child, sb);
71 |
72 | return sb.ToString();
73 | }
74 |
75 | static void DoCollectOutput(TestResult res, StringBuilder sb)
76 | {
77 | if (res.Results != null && res.Results.Count > 0)//skip non-leaf nodes
78 | {
79 | foreach (TestResult child in res.Results)
80 | DoCollectOutput(child, sb);
81 |
82 | return;
83 | }
84 |
85 | sb.AppendLine();
86 |
87 | sb.AppendFormat(
88 | "Test: {0}\n Result: {1,-14} Assert Count: {2,-2} Time: {3,5}",
89 | res.FullName,
90 | GetExecutionResult(res),
91 | res.AssertCount,
92 | res.Time);
93 |
94 | sb.AppendLine();
95 |
96 | if (!res.IsSuccess)
97 | {
98 | sb.AppendLine("Message: " + res.Message);
99 | sb.AppendLine("Stack Trace: ");
100 | sb.AppendLine(res.StackTrace);
101 | }
102 | }
103 |
104 | static string GetExecutionResult(TestResult res)
105 | {
106 | if (res.IsSuccess) return "SUCCESS";
107 | if (res.IsFailure) return "FAILURE";
108 | if (!res.Executed) return "NOT EXECUTED";
109 | return "UNKNOWN";
110 | }
111 |
112 | const string FAILURE_STATUS = "Failure";
113 | const string KILLED_STATUS = "Killed";
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/lib/pnunit/launcher/testlogger/TestSuiteLogger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using NUnit.Core;
4 | using log4net;
5 |
6 | using TestLogger;
7 |
8 | namespace PNUnit.Launcher
9 | {
10 | internal class TestSuiteLogger
11 | {
12 | internal TestSuiteLoggerParams SuiteParams { get { return mTestSuiteLoggerParams; } }
13 |
14 | internal TestSuiteLogger(TestSuiteLoggerParams testSuiteLoggerParams)
15 | {
16 | mTestSuiteLoggerParams = testSuiteLoggerParams;
17 | }
18 |
19 | internal void SaveBuild()
20 | {
21 | TestLoggerClient client = new TestLoggerClient();
22 | try
23 | {
24 | mBuildId = client.SaveBuild(
25 | mTestSuiteLoggerParams.BuildType,
26 | mTestSuiteLoggerParams.BuildName,
27 | mTestSuiteLoggerParams.Cset.ToString(),
28 | mTestSuiteLoggerParams.Comment);
29 | }
30 | catch (Exception e)
31 | {
32 | log.Error("ERROR LOGGING TEST STATS IN DATABASE: " + e.Message);
33 | }
34 | }
35 |
36 | internal void CreateSuite()
37 | {
38 | TestLoggerClient client = new TestLoggerClient();
39 | try
40 | {
41 | mSuiteRunId = client.SaveSuiteRun(
42 | mBuildId,
43 | mTestSuiteLoggerParams.SuiteType,
44 | mTestSuiteLoggerParams.SuiteName,
45 | mTestSuiteLoggerParams.Host,
46 | mTestSuiteLoggerParams.VMachine);
47 | }
48 | catch (Exception e)
49 | {
50 | log.Error("ERROR LOGGING TEST STATS IN DATABASE: " + e.Message);
51 | }
52 | }
53 |
54 | internal void LogTestRunResults(
55 | TestResult[] testResults, string suiteType, string testName, bool isRepeated)
56 | {
57 | TestSuiteEntry.Data entry = TestSuiteEntry.Calculate(
58 | testResults, mTestSuiteLoggerParams.LogSuccessfulTests);
59 |
60 | TestLoggerClient client = new TestLoggerClient();
61 | try
62 | {
63 | client.SaveTestRun(
64 | mBuildId,
65 | mSuiteRunId,
66 | suiteType,
67 | testName,
68 | entry.ClientConfig,
69 | entry.ServerConfig,
70 | entry.BackendType,
71 | entry.ExecTime,
72 | entry.Status,
73 | entry.Log,
74 | isRepeated);
75 | }
76 | catch (Exception e)
77 | {
78 | log.Error("ERROR LOGGING TEST STATS IN DATABASE: " + e.Message);
79 | }
80 | }
81 |
82 | readonly ILog log = LogManager.GetLogger("launcher");
83 | Guid mBuildId;
84 |
85 | TestSuiteLoggerParams mTestSuiteLoggerParams;
86 | Guid mSuiteRunId;
87 | }
88 | }
--------------------------------------------------------------------------------
/lib/pnunit/pnunit.framework/ProcessNameSetter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Text;
4 |
5 | public class ProcessNameSetter
6 | {
7 | [DllImport("libc")] // Linux
8 | private static extern int prctl(int option, byte[] arg2, IntPtr arg3,
9 | IntPtr arg4, IntPtr arg5);
10 |
11 | [DllImport("libc")] // BSD
12 | private static extern void setproctitle(byte[] fmt, byte[] str_arg);
13 |
14 | public static void SetProcessName(string name)
15 | {
16 | if (IsWindows())
17 | return;
18 |
19 | try
20 | {
21 | if (prctl(15 /* PR_SET_NAME */, Encoding.ASCII.GetBytes(name + "\0"),
22 | IntPtr.Zero, IntPtr.Zero, IntPtr.Zero) != 0)
23 | {
24 | Console.WriteLine("Error setting process name");
25 | }
26 | }
27 | catch (EntryPointNotFoundException)
28 | {
29 | try
30 | {
31 | setproctitle(Encoding.ASCII.GetBytes("%s\0"),
32 | Encoding.ASCII.GetBytes(name + "\0"));
33 | }
34 | catch (Exception e)
35 | {
36 | Console.WriteLine(e.Message);
37 | }
38 | }
39 | }
40 |
41 | private static bool IsWindows()
42 | {
43 | switch (Environment.OSVersion.Platform)
44 | {
45 | case PlatformID.Win32Windows:
46 | case PlatformID.Win32NT:
47 | case PlatformID.Win32S:
48 | return true;
49 | default:
50 | return false;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/lib/pnunit/pnunittestrunner/InitServices.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using NUnit.Util;
3 |
4 | namespace PNUnitTestRunner
5 | {
6 | public class InitServices
7 | {
8 | public static void InitNUnitServices()
9 | {
10 | // initialize NUnit services
11 | // Add Standard Services to ServiceManager
12 | ServiceManager.Services.AddService(new SettingsService());
13 | ServiceManager.Services.AddService(new DomainManager());
14 | ServiceManager.Services.AddService(new ProjectService());
15 |
16 | // initialize NUnit services
17 | // Add Standard Services to ServiceManager
18 | ServiceManager.Services.AddService(new SettingsService());
19 | ServiceManager.Services.AddService(new DomainManager());
20 | ServiceManager.Services.AddService(new ProjectService());
21 |
22 | NUnit.Core.CoreExtensions.Host.InitializeService();
23 |
24 | // Initialize Services
25 | ServiceManager.Services.InitializeServices();
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/lib/pnunit/pnunittestrunner/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 |
5 | using log4net;
6 | using log4net.Config;
7 |
8 | using PNUnit.Framework;
9 |
10 | namespace PNUnitTestRunner
11 | {
12 | class Program
13 | {
14 | static void Main(string[] args)
15 | {
16 | ConfigureLogging();
17 |
18 | // usage: pnunitinfofile agentconfigfile path to assemblies
19 | if (args.Length != 2)
20 | {
21 | Console.WriteLine("Wrong number of parameters; exiting ...");
22 | Environment.Exit(1);
23 | }
24 |
25 | if (args[0] == "preload")
26 | {
27 | RunPreload(args[1]);
28 | return;
29 | }
30 |
31 | InitServices.InitNUnitServices();
32 |
33 | RunOnce(args[0], args[1]);
34 | }
35 |
36 | static void RunOnce(string testInfoFile, string pathToAssemblies)
37 | {
38 | PNUnitTestInfo info = TestInfoReader.ReadTestInfo(testInfoFile);
39 |
40 | if (info == null)
41 | {
42 | Console.WriteLine("Cannot execute tests without information; exiting ...");
43 | Environment.Exit(1);
44 | }
45 |
46 | ProcessNameSetter.SetProcessName(info.TestName);
47 |
48 | IPNUnitServices services =
49 | PNUnitServices.GetPNunitServicesProxy(info.PNUnitServicesServer);
50 |
51 | if (info.TestName.StartsWith("run-nunit"))
52 | {
53 | new NUnitTestRunner(info, pathToAssemblies).Run(services);
54 | return;
55 | }
56 |
57 | new PNUnitTestRunner(pathToAssemblies).Run(info, services, null);
58 | }
59 |
60 | static void RunPreload(string pathToAssemblies)
61 | {
62 | mLog.Debug("Preload started. Path To assemblies:" + pathToAssemblies);
63 | InitServices.InitNUnitServices();
64 |
65 | PNUnitTestRunner runner = new PNUnitTestRunner(pathToAssemblies);
66 | runner.Preload();
67 |
68 | int pidOfThisExpectedByAgent = Codice.Test.PlatformIdentifier.IsWindows() ?
69 | System.Diagnostics.Process.GetCurrentProcess().Id :
70 | Mono.Unix.UnixEnvironment.GetParentProcessId();
71 |
72 | string testInfoFile = Path.Combine(
73 | Path.GetTempPath(),
74 | PNUnit.Agent.AssemblyPreload.PRELOADED_PROCESS_FILE_PREFIX + pidOfThisExpectedByAgent.ToString());
75 |
76 | int count = 0;
77 | while(!File.Exists(testInfoFile))
78 | {
79 | System.Threading.Thread.Sleep(150);
80 | mLog.DebugFormat("Waiting for testinfo file to be created...: {0}", testInfoFile);
81 |
82 | count++;
83 |
84 | if (count >= 6000) //wait 1,5 minutes for test arrival
85 | {
86 | mLog.Fatal("Tired of waiting: Cannot execute tests without information; exiting ...");
87 | Environment.Exit(1);
88 | }
89 |
90 | }
91 |
92 | mLog.DebugFormat("Preload read {0} from file", testInfoFile);
93 |
94 | PNUnitTestInfo info = TestInfoReader.ReadTestInfo(testInfoFile);
95 |
96 | if (info == null)
97 | {
98 | mLog.Fatal("Cannot execute tests without information; exiting ...");
99 | Environment.Exit(1);
100 | }
101 |
102 | ProcessNameSetter.SetProcessName(info.TestName);
103 |
104 | IPNUnitServices services =
105 | PNUnitServices.GetPNunitServicesProxy(info.PNUnitServicesServer);
106 |
107 | runner.Run(info, services, null);
108 | }
109 |
110 | static void ConfigureLogging()
111 | {
112 | string log4netpath = Path.Combine(
113 | Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
114 | "pnunittestrunner.log.conf");
115 |
116 | XmlConfigurator.Configure(new FileInfo(log4netpath));
117 | }
118 |
119 | static readonly ILog mLog = LogManager.GetLogger("Program");
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/lib/pnunit/pnunittestrunner/TestInfoReader.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using PNUnit.Framework;
3 | using System.IO;
4 | using System.Runtime.Serialization.Formatters.Binary;
5 | using System.Runtime.Serialization.Formatters;
6 | using log4net;
7 |
8 | namespace PNUnitTestRunner
9 | {
10 | public class TestInfoReader
11 | {
12 | public static PNUnitTestInfo ReadTestInfo(string testInfoPath)
13 | {
14 | int ini = Environment.TickCount;
15 | PNUnitTestInfo result = null;
16 |
17 | try
18 | {
19 | using (FileStream fs = new FileStream(testInfoPath, FileMode.Open, FileAccess.Read))
20 | {
21 | BinaryFormatter bf = new BinaryFormatter();
22 | bf.AssemblyFormat = FormatterAssemblyStyle.Simple;
23 | result = (PNUnitTestInfo)bf.Deserialize(fs);
24 |
25 | return result;
26 | }
27 | }
28 | catch (Exception e)
29 | {
30 | mLog.ErrorFormat("Something wrong happened when reading the agent info: " + e.Message);
31 | return null;
32 | }
33 | finally
34 | {
35 | TryDelete(testInfoPath);
36 | mLog.DebugFormat(
37 | "Read test info file {0} {1} ms",
38 | testInfoPath, Environment.TickCount - ini);
39 | }
40 | }
41 |
42 | static void TryDelete(string testInfoPath)
43 | {
44 | try
45 | {
46 | File.Delete(testInfoPath);
47 | }
48 | catch (Exception e)
49 | {
50 | mLog.WarnFormat("Could not delete testInfoFile {0} {1}", testInfoPath, e.Message);
51 | mLog.Debug(e.StackTrace);
52 | }
53 | }
54 |
55 | static readonly ILog mLog = LogManager.GetLogger("PNUnitTestRunner");
56 | }
57 | }
--------------------------------------------------------------------------------
/lib/pnunit/pnunittestrunner/pnunittestrunner.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 8.0.30703
7 | 2.0
8 | {06A6D68A-82A2-4CC2-8388-3DC6A43310BF}
9 | Exe
10 | Properties
11 | pnunittestrunner
12 | pnunittestrunner
13 | v4.5
14 |
15 |
16 | 512
17 | PlasticSCM
18 | PlasticSCM
19 | PlasticSCM
20 | Plastic SCM Source Control Service:{774e58ba-f1b9-40a7-b676-834fa2c220fe}
21 |
22 |
23 | AnyCPU
24 | true
25 | full
26 | false
27 | ..\..\..\bin\pnunit\
28 | DEBUG;TRACE
29 | prompt
30 | 4
31 |
32 |
33 | x86
34 | pdbonly
35 | true
36 | bin\Release\
37 | TRACE
38 | prompt
39 | 4
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | ..\..\log4net\log4net.dll
51 |
52 |
53 | False
54 | ..\..\..\02nervathirdparty\mono\Mono.Posix.dll
55 |
56 |
57 | ..\..\nunit\nunit.core.dll
58 |
59 |
60 | ..\..\nunit\nunit.core.interfaces.dll
61 |
62 |
63 | ..\..\nunit\nunit.util.dll
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | {621C27DA-CC29-4663-9FE4-BF5A67970C18}
72 | agent
73 |
74 |
75 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}
76 | pnunit.framework
77 |
78 |
79 |
80 |
81 |
82 |
83 |
90 |
--------------------------------------------------------------------------------
/lib/pnunit/testloggerinterface/ITestLogger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace TestLogger
4 | {
5 | public interface ITestLogger
6 | {
7 | bool CheckConnection();
8 |
9 | Guid SaveBuild(
10 | string type,
11 | string name,
12 | string changeset,
13 | string comment);
14 |
15 | Guid SaveSuiteRun(
16 | Guid buildId,
17 | string type,
18 | string name,
19 | string host,
20 | string vmachine);
21 |
22 | void SaveTestRun(
23 | Guid buildId,
24 | Guid suiteRunId,
25 | string suiteType,
26 | string testName,
27 | string clientConfig,
28 | string serverConfig,
29 | string backendType,
30 | int executionTimeSecs,
31 | string status,
32 | string log,
33 | bool isRepeated);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/lib/pnunit/testloggerinterface/TestLoggerClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 |
5 | using log4net;
6 |
7 | namespace TestLogger
8 | {
9 | public class TestLoggerClient
10 | {
11 | public TestLoggerClient()
12 | {
13 | mServerLoggerUrl = LoadLoggerServerUrl();
14 | }
15 |
16 | public TestLoggerClient(string serverLoggerUrl)
17 | {
18 | mServerLoggerUrl = serverLoggerUrl;
19 | }
20 |
21 | public bool CheckConnection()
22 | {
23 | ITestLogger logger = (ITestLogger)
24 | Activator.GetObject(typeof(ITestLogger), mServerLoggerUrl);
25 | return logger.CheckConnection();
26 | }
27 |
28 | public Guid SaveBuild(string type, string name, string changeset, string comment)
29 | {
30 | ITestLogger logger = (ITestLogger)
31 | Activator.GetObject(typeof(ITestLogger), mServerLoggerUrl);
32 | return logger.SaveBuild(type, name, changeset, comment);
33 | }
34 |
35 | public Guid SaveSuiteRun(
36 | Guid buildId,
37 | string type,
38 | string name,
39 | string host,
40 | string vmachine)
41 | {
42 | ITestLogger logger = (ITestLogger)
43 | Activator.GetObject(typeof(ITestLogger), mServerLoggerUrl);
44 | return logger.SaveSuiteRun(buildId, type, name, host, vmachine);
45 | }
46 |
47 | public void SaveTestRun(
48 | Guid buildId,
49 | Guid suiteRunId,
50 | string suiteType,
51 | string testName,
52 | string clientConfig,
53 | string serverConfig,
54 | string backendType,
55 | int executionTimeSecs,
56 | string status,
57 | string log,
58 | bool isRepeated)
59 | {
60 | ITestLogger logger = (ITestLogger)
61 | Activator.GetObject(typeof(ITestLogger), mServerLoggerUrl);
62 | logger.SaveTestRun(
63 | buildId,
64 | suiteRunId,
65 | suiteType,
66 | testName,
67 | clientConfig,
68 | serverConfig,
69 | backendType,
70 | executionTimeSecs,
71 | status,
72 | log,
73 | isRepeated);
74 | }
75 |
76 | private string LoadLoggerServerUrl()
77 | {
78 | string serverLoggerConfPath =
79 | Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
80 | TEST_LOGGER_SERVER_CONF_FILE);
81 | try
82 | {
83 | using (StreamReader sr = new StreamReader(serverLoggerConfPath))
84 | {
85 | return sr.ReadToEnd().Trim();
86 | }
87 | }
88 | catch (Exception)
89 | {
90 | return "tcp://192.168.1.78:9999/TestLogger";
91 | }
92 | }
93 |
94 | private string mServerLoggerUrl = string.Empty;
95 | private const string TEST_LOGGER_SERVER_CONF_FILE = "testloggerserver.conf";
96 | private readonly ILog log = LogManager.GetLogger("launcher");
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/lib/pnunit/testloggerinterface/testloggerinterface.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {17A8659A-7BBE-45F5-85DD-A931953775A2}
9 | Library
10 | Properties
11 | testloggerinterface
12 | testloggerinterface
13 | v2.0
14 | 512
15 |
16 | PlasticSCM
17 | PlasticSCM
18 | PlasticSCM
19 | Plastic SCM Source Control Service:{774e58ba-f1b9-40a7-b676-834fa2c220fe}
20 |
21 |
22 | true
23 | full
24 | false
25 | ..\..\..\bin\pnunit\
26 | DEBUG;TRACE
27 | prompt
28 | 4
29 |
30 |
31 | pdbonly
32 | true
33 | bin\Release\
34 | TRACE
35 | prompt
36 | 4
37 |
38 |
39 |
40 | ..\..\log4net\log4net.dll
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
56 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ErrorDialog.cs:
--------------------------------------------------------------------------------
1 | using Gtk;
2 |
3 | using Codice.Examples.GuiTesting.Lib;
4 | using Codice.Examples.GuiTesting.Linux.UI;
5 |
6 | namespace Codice.Examples.GuiTesting.Linux
7 | {
8 | internal class ErrorDialog : BaseDialog
9 | {
10 | internal Button OkButton { get { return mOkButton; } }
11 | internal Label MessageLabel { get { return mMessageLabel; } }
12 |
13 | internal ErrorDialog(string title, string message, Window parent)
14 | : base(title, parent)
15 | {
16 | BuildComponents(message);
17 | SetSizeRequest(DIALOG_WIDTH, DIALOG_HEIGHT);
18 | }
19 |
20 | void BuildComponents(string message)
21 | {
22 | HBox messageBox = new HBox();
23 |
24 | mMessageLabel = ControlBuilder.CreateExplanationLabel(message);
25 | Image messageImage = Image.NewFromIconName(
26 | "dialog-error", IconSize.Dialog);
27 |
28 | ControlPacker.Add(messageBox, messageImage);
29 | ControlPacker.Fill(
30 | messageBox,
31 | AlignmentBuilder.LeftPadding(
32 | mMessageLabel, AlignmentBuilder.SMALL_PADDING));
33 |
34 | AddComponents(
35 | AlignmentBuilder.TopBottomPadding(
36 | messageBox, AlignmentBuilder.SMALL_PADDING));
37 |
38 | mOkButton = CreateOkButton(
39 | Localization.GetText(Localization.Name.Ok));
40 |
41 | DefaultResponse = (ResponseType)GetResponseForWidget(mOkButton);
42 | }
43 |
44 | Button mOkButton;
45 | Label mMessageLabel;
46 |
47 | const int DIALOG_WIDTH = 360;
48 | const int DIALOG_HEIGHT = 160;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ExceptionsHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using log4net;
4 |
5 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
6 |
7 | namespace Codice.Examples.GuiTesting.Linux
8 | {
9 | internal static class ExceptionsHandler
10 | {
11 | internal static void SetExceptionHandlers(bool isTestingMode)
12 | {
13 | if (isTestingMode)
14 | {
15 | SetTestingExceptionHandlers();
16 | return;
17 | }
18 |
19 | SetStandardExceptionHandlers();
20 | }
21 |
22 | static void SetStandardExceptionHandlers()
23 | {
24 | AppDomain.CurrentDomain.UnhandledException += HandleTestingUnhandledException;
25 | GLib.ExceptionManager.UnhandledException += HandleUnhandledGlibTestingException;
26 | }
27 |
28 | static void SetTestingExceptionHandlers()
29 | {
30 | // We don't want to eat up the exception during testing like nothing
31 | // happens, but we still want to save it in order to display it
32 | // as the cause of the failed test.
33 | AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;
34 | GLib.ExceptionManager.UnhandledException += HandleUnhandledGlibException;
35 | }
36 |
37 | static void HandleUnhandledException(object sender, UnhandledExceptionEventArgs e)
38 | {
39 | // Here you'd usually log the exception, send telemetry events...
40 | Exception ex = e.ExceptionObject as Exception;
41 | if (ex == null)
42 | return;
43 |
44 | Console.Error.WriteLine(ex.Message);
45 | Console.Error.WriteLine(ex.StackTrace);
46 | }
47 |
48 | static void HandleUnhandledGlibException(GLib.UnhandledExceptionArgs e)
49 | {
50 | // Here you'd usually log the exception, send telemetry events...
51 | mLog.ErrorFormat("The runtime is terminating [{0}]", e.IsTerminating);
52 | e.ExitApplication = false;
53 |
54 | Exception ex = e.ExceptionObject as Exception;
55 | if (ex == null)
56 | return;
57 |
58 | Console.Error.WriteLine(ex.Message);
59 | Console.Error.WriteLine(ex.StackTrace);
60 | }
61 |
62 | static void HandleTestingUnhandledException(object sender, UnhandledExceptionEventArgs e)
63 | {
64 | HandleTestingException(e.ExceptionObject as Exception);
65 | }
66 |
67 | static void HandleUnhandledGlibTestingException(GLib.UnhandledExceptionArgs e)
68 | {
69 | HandleTestingException(e.ExceptionObject as Exception);
70 |
71 | mLog.ErrorFormat("The runtime is terminating [{0}]", e.IsTerminating);
72 | e.ExitApplication = false;
73 | }
74 |
75 | static void HandleTestingException(Exception ex)
76 | {
77 | GuiTesteableServices.UnhandledException = ex;
78 | }
79 |
80 | static readonly ILog mLog = LogManager.GetLogger("ExceptionsHandler");
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/application/gui/linux/GtkGuiMessage.cs:
--------------------------------------------------------------------------------
1 | using Codice.Examples.GuiTesting.Lib.Interfaces;
2 |
3 | namespace Codice.Examples.GuiTesting.Linux
4 | {
5 | internal class GtkGuiMessage : GuiMessage.IGuiMessage
6 | {
7 | void GuiMessage.IGuiMessage.ShowError(string title, string message)
8 | {
9 | ErrorDialog dialog = new ErrorDialog(
10 | title, message, WindowHandler.ApplicationWindow);
11 |
12 | WindowHandler.SetActiveDialogForTesting(dialog);
13 |
14 | try
15 | {
16 | dialog.RunModal();
17 | }
18 | finally
19 | {
20 | WindowHandler.RemoveDialogForTesting(dialog);
21 | dialog.Dispose();
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ProcessNameSetter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 | using System.Text;
4 |
5 | using log4net;
6 |
7 | namespace Codice.Examples.GuiTesting.Linux
8 | {
9 | internal class ProcessNameSetter
10 | {
11 | [DllImport("libc")] // Linux
12 | static extern int prctl(
13 | int option, byte[] arg2, IntPtr arg3, IntPtr arg4, IntPtr arg5);
14 |
15 | [DllImport("libc")] // BSD
16 | static extern int setproctitle(byte[] fmt, byte[] str_arg);
17 |
18 | internal static void SetProcessName(string name)
19 | {
20 | if (IsWindows())
21 | return;
22 |
23 | try
24 | {
25 | if (PrctlSetName(name) != 0)
26 | mLog.Debug("Error setting process name");
27 | }
28 | catch (EntryPointNotFoundException)
29 | {
30 | try
31 | {
32 | setproctitle(
33 | Encoding.ASCII.GetBytes("%s\0"),
34 | Encoding.ASCII.GetBytes(name + "\0"));
35 | }
36 | catch (Exception ex)
37 | {
38 | mLog.DebugFormat(
39 | "Couldn't change process name: {0}", ex.Message);
40 | }
41 | }
42 | }
43 |
44 | static int PrctlSetName(string name)
45 | {
46 | return prctl(
47 | (int)OPTION.PR_SET_NAME,
48 | Encoding.ASCII.GetBytes(name + "\0"),
49 | IntPtr.Zero,
50 | IntPtr.Zero,
51 | IntPtr.Zero);
52 | }
53 |
54 | enum OPTION
55 | {
56 | PR_SET_NAME = 15
57 | }
58 |
59 | private static bool IsWindows()
60 | {
61 | switch (Environment.OSVersion.Platform)
62 | {
63 | case PlatformID.Win32Windows:
64 | case PlatformID.Win32NT:
65 | case PlatformID.Win32S:
66 | return true;
67 | default:
68 | return false;
69 | }
70 | }
71 |
72 | static readonly ILog mLog = LogManager.GetLogger("ProcessNameSetter");
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/application/gui/linux/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | using Gtk;
5 |
6 | using GuiTest;
7 |
8 | using Codice.Examples.GuiTesting.Lib;
9 | using Codice.Examples.GuiTesting.Lib.Interfaces;
10 | using Codice.Examples.GuiTesting.Lib.Threading;
11 | using Codice.Examples.GuiTesting.Linux.Threading;
12 |
13 | namespace Codice.Examples.GuiTesting.Linux
14 | {
15 | static class Program
16 | {
17 | [STAThread]
18 | static void Main(string[] args)
19 | {
20 | try
21 | {
22 | ApplicationArgs appArgs = ApplicationArgs.Parse(args);
23 |
24 | ExceptionsHandler.SetExceptionHandlers(appArgs.IsTestingMode);
25 |
26 | ProcessNameSetter.SetProcessName("linux");
27 |
28 | ThreadWaiterBuilder.Initialize(new GtkApplicationTimerBuilder());
29 |
30 | GuiMessage.Initialize(new GtkGuiMessage());
31 |
32 | if (appArgs.IsTestingMode)
33 | InstallTestAssembliesResolver(appArgs.PathToAssemblies);
34 |
35 | // Tip: you could launch different windows depending on the
36 | // argument flags.
37 | Application.Init();
38 | WindowHandler.LaunchApplicationWindow();
39 |
40 | if (appArgs.IsTestingMode)
41 | WindowHandler.LaunchTest(appArgs.TestInfoFile, appArgs.PathToAssemblies);
42 |
43 | Application.Run();
44 | }
45 | catch (Exception ex)
46 | {
47 | // You would track the exception here
48 | Console.Error.WriteLine($"{ex.GetType()}: {ex.Message}");
49 | Console.Error.WriteLine(ex.StackTrace);
50 |
51 | ExitCode = 1;
52 | Application.Quit();
53 | }
54 | finally
55 | {
56 | // You would dispose everything you need here.
57 | Environment.Exit(ExitCode);
58 | }
59 | }
60 |
61 | static void InstallTestAssembliesResolver(string pathToAssemblies)
62 | {
63 | List assemblies = new List();
64 | assemblies.Add("nunit.core.dll");
65 | assemblies.Add("nunit.core.interfaces.dll");
66 | assemblies.Add("nunit.util.dll");
67 | assemblies.Add("pnunit.framework.dll");
68 |
69 | assemblies.Add("guitestinterfaces.dll");
70 | assemblies.Add("guitest.dll");
71 |
72 | GuiTestRunner.GuiTestAssemblyResolver.InstallAssemblyResolver(
73 | pathToAssemblies, assemblies);
74 | }
75 |
76 | static int ExitCode = 0;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/application/gui/linux/WindowHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Threading;
5 |
6 | using Gtk;
7 |
8 | using log4net;
9 | using log4net.Config;
10 | using log4net.Repository;
11 |
12 | using GuiTest;
13 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
14 | using Codice.Examples.GuiTesting.Lib;
15 | using Codice.Examples.GuiTesting.Linux.Testing;
16 |
17 | namespace Codice.Examples.GuiTesting.Linux
18 | {
19 | internal static class WindowHandler
20 | {
21 | internal static Window ApplicationWindow
22 | {
23 | get { return mApplicationWindow; }
24 | }
25 |
26 | internal static void LaunchApplicationWindow()
27 | {
28 | ApplicationOperations operations = new ApplicationOperations();
29 | mApplicationWindow = new ApplicationWindow(operations);
30 | mApplicationWindow.WindowPosition = WindowPosition.Center;
31 | mApplicationWindow.ShowAll();
32 | }
33 |
34 | internal static void UnregisterApplicationWindow()
35 | {
36 | mApplicationWindow.Dispose();
37 | mApplicationWindow = null;
38 |
39 | TerminateApplication();
40 | }
41 |
42 | internal static void SetActiveDialogForTesting(Dialog dialog)
43 | {
44 | if (!mbIsTestRun)
45 | return;
46 |
47 | mActiveDialog = dialog;
48 | }
49 |
50 | internal static void RemoveDialogForTesting(Dialog dialog)
51 | {
52 | if (!mbIsTestRun)
53 | return;
54 |
55 | if (mActiveDialog == dialog)
56 | mActiveDialog = null;
57 | }
58 |
59 | internal static Dialog GetActiveDialog()
60 | {
61 | return mActiveDialog;
62 | }
63 |
64 | internal static void LaunchTest(string testInfoFile, string pathToAssemblies)
65 | {
66 | mbIsTestRun = true;
67 |
68 | ConfigureTestLogging();
69 | InitTesteableServices();
70 |
71 | GuiTestRunner testRunner = new GuiTestRunner(
72 | testInfoFile, pathToAssemblies, new GuiFinalizer(), null);
73 |
74 | ThreadPool.QueueUserWorkItem(new WaitCallback(testRunner.Run));
75 | }
76 |
77 | static void ConfigureTestLogging()
78 | {
79 | try
80 | {
81 | string log4netPath = Path.Combine(
82 | Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
83 | "pnunittestrunner.log.conf");
84 |
85 | XmlConfigurator.Configure(mLogRepository, new FileInfo(log4netPath));
86 | }
87 | catch { } // Log config failed, nothing else to do!
88 | }
89 |
90 | static void InitTesteableServices()
91 | {
92 | TesteableApplicationWindow testeableWindow =
93 | new TesteableApplicationWindow(mApplicationWindow);
94 |
95 | GuiTesteableServices.Init(testeableWindow);
96 | }
97 |
98 | static void TerminateApplication()
99 | {
100 | if (mbIsTestRun)
101 | return;
102 |
103 | Application.Quit();
104 | }
105 |
106 | static ApplicationWindow mApplicationWindow;
107 | static Dialog mActiveDialog;
108 | static bool mbIsTestRun = false;
109 |
110 | static readonly ILoggerRepository mLogRepository =
111 | LogManager.CreateRepository("log4net-rep");
112 |
113 | class GuiFinalizer : GuiTestRunner.IGuiFinalizer
114 | {
115 | void GuiTestRunner.IGuiFinalizer.Finalize(int exitCode)
116 | {
117 | Environment.Exit(exitCode);
118 | }
119 | }
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/src/application/gui/linux/linux.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28010.2046
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "linux", "linux.csproj", "{353B26F1-B1C1-4731-ADF8-87B40A763F19}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lib", "..\..\lib\lib.csproj", "{A1079FA8-882B-40D6-A289-3A13767CABDD}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testing", "testing", "{0182C75F-FE4F-4A0F-B938-083A868BFA6B}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "guitest", "..\..\..\testing\guitest\guitest.csproj", "{9EE461F0-5FCA-4631-8335-73E1A0AF2861}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "guitestinterfaces", "..\..\..\testing\guitestinterfaces\guitestinterfaces.csproj", "{D775E82D-4045-4E11-AE85-4402CA0AD054}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pnunit.framework", "..\..\..\..\lib\pnunit\pnunit.framework\pnunit.framework.csproj", "{5261ABA1-98E6-4603-A4F0-59CAC307AC68}"
17 | EndProject
18 | Global
19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
20 | Debug|Any CPU = Debug|Any CPU
21 | NAnt|Any CPU = NAnt|Any CPU
22 | Release|Any CPU = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {353B26F1-B1C1-4731-ADF8-87B40A763F19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {353B26F1-B1C1-4731-ADF8-87B40A763F19}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {353B26F1-B1C1-4731-ADF8-87B40A763F19}.NAnt|Any CPU.ActiveCfg = Release|Any CPU
28 | {353B26F1-B1C1-4731-ADF8-87B40A763F19}.NAnt|Any CPU.Build.0 = Release|Any CPU
29 | {353B26F1-B1C1-4731-ADF8-87B40A763F19}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {353B26F1-B1C1-4731-ADF8-87B40A763F19}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.NAnt|Any CPU.ActiveCfg = Release|Any CPU
34 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.NAnt|Any CPU.Build.0 = Release|Any CPU
35 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.NAnt|Any CPU.ActiveCfg = Release|Any CPU
40 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.NAnt|Any CPU.Build.0 = Release|Any CPU
41 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Release|Any CPU.ActiveCfg = Release|Any CPU
42 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Release|Any CPU.Build.0 = Release|Any CPU
43 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
44 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Debug|Any CPU.Build.0 = Debug|Any CPU
45 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.NAnt|Any CPU.ActiveCfg = Release|Any CPU
46 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.NAnt|Any CPU.Build.0 = Release|Any CPU
47 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Release|Any CPU.ActiveCfg = Release|Any CPU
48 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Release|Any CPU.Build.0 = Release|Any CPU
49 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
50 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Debug|Any CPU.Build.0 = Debug|Any CPU
51 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.NAnt|Any CPU.ActiveCfg = NAnt|Any CPU
52 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.NAnt|Any CPU.Build.0 = NAnt|Any CPU
53 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Release|Any CPU.ActiveCfg = Release|Any CPU
54 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Release|Any CPU.Build.0 = Release|Any CPU
55 | EndGlobalSection
56 | GlobalSection(SolutionProperties) = preSolution
57 | HideSolutionNode = FALSE
58 | EndGlobalSection
59 | GlobalSection(NestedProjects) = preSolution
60 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861} = {0182C75F-FE4F-4A0F-B938-083A868BFA6B}
61 | {D775E82D-4045-4E11-AE85-4402CA0AD054} = {0182C75F-FE4F-4A0F-B938-083A868BFA6B}
62 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68} = {0182C75F-FE4F-4A0F-B938-083A868BFA6B}
63 | EndGlobalSection
64 | GlobalSection(ExtensibilityGlobals) = postSolution
65 | SolutionGuid = {FD1A3758-F68F-4C01-9C40-EE45432517B1}
66 | EndGlobalSection
67 | EndGlobal
68 |
--------------------------------------------------------------------------------
/src/application/gui/linux/testing/TesteableApplicationWindow.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
4 |
5 | namespace Codice.Examples.GuiTesting.Linux.Testing
6 | {
7 | internal class TesteableApplicationWindow : ITesteableApplicationWindow
8 | {
9 | internal TesteableApplicationWindow(ApplicationWindow window)
10 | {
11 | mWindow = window;
12 | }
13 |
14 | void ITesteableApplicationWindow.ChangeText(string text)
15 | {
16 | TestHelper.SetText(mWindow.TextEntry, text);
17 | }
18 |
19 | string ITesteableApplicationWindow.GetText()
20 | {
21 | return TestHelper.GetText(mWindow.TextEntry);
22 | }
23 |
24 | void ITesteableApplicationWindow.ClickAddButton()
25 | {
26 | TestHelper.ClickButton(mWindow.AddButton);
27 | }
28 |
29 | void ITesteableApplicationWindow.ClickRemoveButton()
30 | {
31 | TestHelper.ClickButton(mWindow.RemoveButton);
32 | }
33 |
34 | bool ITesteableApplicationWindow.AreButtonsEnabled()
35 | {
36 | return TestHelper.IsSensitive(mWindow.AddButton)
37 | && TestHelper.IsSensitive(mWindow.RemoveButton);
38 | }
39 |
40 | string ITesteableApplicationWindow.GetItemInListAt(int index)
41 | {
42 | return TestHelper.GetItemAt(mWindow.ListView, index);
43 | }
44 |
45 | int ITesteableApplicationWindow.GetItemsInListCount()
46 | {
47 | return TestHelper.GetItemCount(mWindow.ListView);
48 | }
49 |
50 | string ITesteableApplicationWindow.GetProgressMessage()
51 | {
52 | if (mWindow.ProgressControls.HasError)
53 | return string.Empty;
54 |
55 | return TestHelper.GetText(mWindow.ProgressControls.ProgressLabel);
56 | }
57 |
58 | string ITesteableApplicationWindow.GetErrorMessage()
59 | {
60 | if (!mWindow.ProgressControls.HasError)
61 | return string.Empty;
62 |
63 | return TestHelper.GetText(mWindow.ProgressControls.ProgressLabel);
64 | }
65 |
66 | ITesteableErrorDialog ITesteableApplicationWindow.GetErrorDialog()
67 | {
68 | if (WindowHandler.GetActiveDialog() == null)
69 | return null;
70 |
71 | ErrorDialog errorDialog = WindowHandler.GetActiveDialog() as ErrorDialog;
72 | if (errorDialog == null)
73 | return null;
74 |
75 | return new TesteableErrorDialog(errorDialog);
76 | }
77 |
78 | readonly ApplicationWindow mWindow;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/application/gui/linux/testing/TesteableErrorDialog.cs:
--------------------------------------------------------------------------------
1 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
2 |
3 | namespace Codice.Examples.GuiTesting.Linux.Testing
4 | {
5 | internal class TesteableErrorDialog : ITesteableErrorDialog
6 | {
7 | internal TesteableErrorDialog(ErrorDialog errorDialog)
8 | {
9 | mDialog = errorDialog;
10 | }
11 |
12 | void ITesteableErrorDialog.ClickOkButton()
13 | {
14 | TestHelper.ClickDialogButton(mDialog.OkButton);
15 | }
16 |
17 | string ITesteableErrorDialog.GetTitle()
18 | {
19 | return TestHelper.GetTitle(mDialog);
20 | }
21 |
22 | string ITesteableErrorDialog.GetMessage()
23 | {
24 | return TestHelper.GetText(mDialog.MessageLabel);
25 | }
26 |
27 | readonly ErrorDialog mDialog;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/application/gui/linux/threading/GtkApplicationTimer.cs:
--------------------------------------------------------------------------------
1 | using Codice.Examples.GuiTesting.Lib.Threading;
2 |
3 | namespace Codice.Examples.GuiTesting.Linux.Threading
4 | {
5 | internal class GtkApplicationTimerBuilder : IApplicationTimerBuilder
6 | {
7 | public IApplicationTimer Get(
8 | bool bModalMode,
9 | ThreadWaiter.TimerTick timerTickDelegate)
10 | {
11 | return new GtkApplicationTimer(DEFAULT_TIMER_INTERVAL, timerTickDelegate);
12 | }
13 |
14 | public IApplicationTimer Get(
15 | bool bModalMode,
16 | int timerInterval,
17 | ThreadWaiter.TimerTick timerTickDelegate)
18 | {
19 | return new GtkApplicationTimer((uint)timerInterval, timerTickDelegate);
20 | }
21 |
22 | const int DEFAULT_TIMER_INTERVAL = 500;
23 | }
24 |
25 | internal class GtkApplicationTimer : IApplicationTimer
26 | {
27 | internal GtkApplicationTimer(
28 | uint timerInterval, ThreadWaiter.TimerTick timerTickDelegate)
29 | {
30 | mTimerInterval = timerInterval;
31 | mTimerTickDelegate = timerTickDelegate;
32 | }
33 |
34 | public void Start()
35 | {
36 | mTimeoutId = GLib.Timeout.Add(
37 | mTimerInterval, new GLib.TimeoutHandler(OnTimerTick));
38 | }
39 |
40 | public void Stop()
41 | {
42 | if (mTimeoutId == 0)
43 | return;
44 |
45 | GLib.Source.Remove(mTimeoutId);
46 | mTimeoutId = 0;
47 | }
48 |
49 | bool OnTimerTick()
50 | {
51 | mTimerTickDelegate();
52 |
53 | return true;
54 | }
55 |
56 | uint mTimeoutId;
57 |
58 | readonly uint mTimerInterval;
59 | ThreadWaiter.TimerTick mTimerTickDelegate;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ui/AlignmentBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using Gtk;
8 |
9 | namespace Codice.Examples.GuiTesting.Linux.UI
10 | {
11 | internal static class AlignmentBuilder
12 | {
13 | internal const int SMALL_PADDING = 5;
14 |
15 | internal static void SetLeftAlignment(Label label)
16 | {
17 | label.SetAlignment(0, (float)0.5);
18 | }
19 |
20 | internal static void SetRightAlignment(Label label)
21 | {
22 | label.SetAlignment(1, (float)0.5);
23 | }
24 |
25 | internal static Alignment LeftPadding(Widget widget, uint leftPadding)
26 | {
27 | return Padding(widget, 0, 0, leftPadding, 0);
28 | }
29 |
30 | internal static Alignment RightPadding(Widget widget, uint rightPadding)
31 | {
32 | return Padding(widget, 0, 0, 0, rightPadding);
33 | }
34 |
35 | internal static Alignment LeftRightPadding(Widget widget, uint leftRightPadding)
36 | {
37 | return Padding(widget, 0, 0, leftRightPadding, leftRightPadding);
38 | }
39 |
40 | internal static Alignment TopBottomPadding(Widget widget, uint topBottomPadding)
41 | {
42 | return Padding(widget, topBottomPadding, topBottomPadding, 0, 0);
43 | }
44 |
45 | internal static Alignment RightAlignment(Widget widget)
46 | {
47 | Alignment result = new Alignment(1, 0, 0, 0);
48 | result.Add(widget);
49 |
50 | return result;
51 | }
52 |
53 | static Alignment Padding(
54 | Widget widget,
55 | uint topPadding,
56 | uint bottomPadding,
57 | uint leftPadding,
58 | uint rightPadding)
59 | {
60 | Alignment result = new Alignment(1, 1, 1, 1);
61 | result.TopPadding = topPadding;
62 | result.BottomPadding = bottomPadding;
63 | result.LeftPadding = leftPadding;
64 | result.RightPadding = rightPadding;
65 | result.Add(widget);
66 |
67 | return result;
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ui/BaseDialog.cs:
--------------------------------------------------------------------------------
1 | using Gtk;
2 |
3 | namespace Codice.Examples.GuiTesting.Linux.UI
4 | {
5 | internal class BaseDialog : Dialog
6 | {
7 | internal BaseDialog(string title, Window parent) : base(title, parent, DialogFlags.Modal)
8 | {
9 | SetPosition(WindowPosition.CenterOnParent);
10 | BorderWidth = 10;
11 | Resizable = false;
12 | HasSeparator = true;
13 | }
14 |
15 | public override void Dispose()
16 | {
17 | Destroy();
18 | base.Dispose();
19 | }
20 |
21 | internal void AddComponents(params Widget[] widgets)
22 | {
23 | foreach (Widget widget in widgets)
24 | ControlPacker.Add(VBox, widget);
25 |
26 | ShowAll();
27 | }
28 |
29 | internal Button CreateOkButton(string buttonText)
30 | {
31 | return (Button)AddButton(buttonText, ResponseType.Ok);
32 | }
33 |
34 | internal ResponseType RunModal()
35 | {
36 | WindowHandler.SetActiveDialogForTesting(this);
37 |
38 | ResponseType responseType;
39 | while ((responseType = (ResponseType)Run()) == ResponseType.None) { }
40 |
41 | return responseType;
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ui/CellContentRenderer.cs:
--------------------------------------------------------------------------------
1 | using Gtk;
2 | using Pango;
3 |
4 | namespace Codice.Examples.GuiTesting.Linux.UI
5 | {
6 | internal static class CellContentRenderer
7 | {
8 | internal static void RenderText(CellRenderer cell, string text)
9 | {
10 | CellRendererText textCell = cell as CellRendererText;
11 | textCell.FontDesc.Weight = Weight.Normal;
12 | textCell.Text = text;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ui/ControlBuilder.cs:
--------------------------------------------------------------------------------
1 | using Gtk;
2 |
3 | namespace Codice.Examples.GuiTesting.Linux.UI
4 | {
5 | internal static class ControlBuilder
6 | {
7 | internal static Button CreateButton(string text)
8 | {
9 | Button result = new Button(text);
10 | result.Relief = ReliefStyle.Normal;
11 | result.SetSizeRequest(DEFAULT_BUTTON_WIDTH, DEFAULT_BUTTON_HEIGHT);
12 |
13 | return result;
14 | }
15 |
16 | internal static Entry CreateEntry()
17 | {
18 | return new Entry();
19 | }
20 |
21 | internal static Label CreateExplanationLabel(string text)
22 | {
23 | Label result = CreateLabel();
24 | result.Name = text;
25 | result.LabelProp = Mono.Unix.Catalog.GetString(text);
26 | result.Justify = Justification.Left;
27 | result.LineWrapMode = Pango.WrapMode.Word;
28 | result.LineWrap = true;
29 | result.SizeAllocated += (sender, args) =>
30 | {
31 | Label label = sender as Label;
32 | label.SetSizeRequest(args.Allocation.Width - 1, -1);
33 | };
34 | return result;
35 | }
36 |
37 | internal static Label CreateLabel(string text)
38 | {
39 | Label result = CreateLabel();
40 | result.Name = text;
41 | result.LabelProp = Mono.Unix.Catalog.GetString(text);
42 | return result;
43 | }
44 |
45 | internal static Label CreateSelectableLabel()
46 | {
47 | Label result = CreateLabel();
48 | result.Selectable = true;
49 | return result;
50 | }
51 |
52 | internal static Label CreateLabel()
53 | {
54 | Label result = new Label();
55 | result.SetPadding(5, 0);
56 | return result;
57 | }
58 |
59 | internal static Widget CreateEmptyArea()
60 | {
61 | return new HBox(true, 0);
62 | }
63 |
64 | const int DEFAULT_BUTTON_WIDTH = 100;
65 | const int DEFAULT_BUTTON_HEIGHT = 34;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ui/ControlPacker.cs:
--------------------------------------------------------------------------------
1 | using Gtk;
2 |
3 | namespace Codice.Examples.GuiTesting.Linux.UI
4 | {
5 | internal static class ControlPacker
6 | {
7 | internal static void Add(Box box, Widget widget, uint padding = 0)
8 | {
9 | box.PackStart(widget, false, false, padding);
10 | }
11 |
12 | internal static void Fill(Box box, Widget widget, uint padding = 0)
13 | {
14 | box.PackStart(widget, true, true, padding);
15 | }
16 |
17 | internal static void PackActionButtons(HBox box, uint padding, params Widget[] buttons)
18 | {
19 | HBox buttonsBox = new HBox();
20 |
21 | Add(buttonsBox, buttons[0]);
22 | for (int i = 1; i < buttons.Length; i++)
23 | Add(buttonsBox, AlignmentBuilder.LeftPadding(buttons[i], padding));
24 |
25 | Fill(box, ControlBuilder.CreateEmptyArea());
26 | Add(box, buttonsBox);
27 | }
28 |
29 | internal static void PackProgressLabel(HBox box, Label progressLabel)
30 | {
31 | box.HeightRequest = PROGRESS_PANEL_HEIGHT;
32 | AlignmentBuilder.SetLeftAlignment(progressLabel);
33 | Fill(box, progressLabel);
34 | }
35 |
36 | const int PROGRESS_PANEL_HEIGHT = 22;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ui/GtkListView.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Codice.Examples.GuiTesting.Linux.UI
4 | {
5 | internal class GtkListView
6 | {
7 | internal delegate Gtk.TreePath FindRowFunc(Gtk.TreeModel model, T value);
8 |
9 | internal readonly Gtk.TreeView View;
10 |
11 | internal bool HeadersVisible
12 | {
13 | get { return View.HeadersVisible; }
14 | set { View.HeadersVisible = value; }
15 | }
16 |
17 | internal GtkListView(
18 | List columns,
19 | Dictionary sortFunctionsByColumn,
20 | Gtk.TreeModelFilterVisibleFunc visibleFunc)
21 | {
22 | View = TreeBuilder.CreateTreeView();
23 | mSortFunctionByColumn = sortFunctionsByColumn;
24 | mVisibleFunc = visibleFunc;
25 |
26 | foreach (Gtk.TreeViewColumn column in columns)
27 | View.AppendColumn(column);
28 | }
29 |
30 | internal void Fill(List values)
31 | {
32 | if (values == null)
33 | return;
34 |
35 | Gtk.ListStore listStore = new Gtk.ListStore(typeof(T));
36 |
37 | values.ForEach((val) => listStore.AppendValues(val));
38 |
39 | mModelFilter = new Gtk.TreeModelFilter(listStore, null);
40 | mModelFilter.VisibleFunc = mVisibleFunc;
41 |
42 | mModelSort = new Gtk.TreeModelSort(mModelFilter);
43 | SetSortFunctions(mModelSort, mSortFunctionByColumn);
44 |
45 | if (View.Model != null)
46 | (View.Model as Gtk.TreeModelSort).Dispose();
47 |
48 | View.Model = mModelSort;
49 | }
50 |
51 | internal List GetSelected()
52 | {
53 | List result = new List();
54 |
55 | if (View.Selection.CountSelectedRows() == 0)
56 | return result;
57 |
58 | foreach (Gtk.TreePath path in View.Selection.GetSelectedRows())
59 | result.Add(GetObjectFromTreePath(mModelSort, path));
60 |
61 | return result;
62 | }
63 |
64 | static T GetObjectFromTreePath(Gtk.TreeModelSort modelSort, Gtk.TreePath path)
65 | {
66 | Gtk.TreeIter iter;
67 | modelSort.GetIter(out iter, path);
68 | return GetObjectFromTreeIter(modelSort, iter);
69 | }
70 |
71 | static T GetObjectFromTreeIter(Gtk.TreeModel model, Gtk.TreeIter iter)
72 | {
73 | return (T)model.GetValue(iter, 0);
74 | }
75 |
76 | static void SetSortFunctions(
77 | Gtk.TreeModelSort treeModelSort,
78 | Dictionary sortFunctions)
79 | {
80 | foreach (int sortColumnId in sortFunctions.Keys)
81 | treeModelSort.SetSortFunc(sortColumnId, sortFunctions[sortColumnId]);
82 | }
83 |
84 | Gtk.TreeModelFilter mModelFilter;
85 | Gtk.TreeModelSort mModelSort;
86 |
87 | readonly Dictionary mSortFunctionByColumn;
88 | readonly Gtk.TreeModelFilterVisibleFunc mVisibleFunc;
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ui/Keyboard.cs:
--------------------------------------------------------------------------------
1 | using Gdk;
2 |
3 | namespace Codice.Examples.GuiTesting.Linux.UI
4 | {
5 | internal static class Keyboard
6 | {
7 | internal static bool IsEnterPressed(EventKey eventKey)
8 | {
9 | Key key = eventKey.Key;
10 |
11 | return key == Key.Return
12 | || key == Key.ISO_Enter
13 | || key == Key.Key_3270_Enter
14 | || key == Key.KP_Enter;
15 | }
16 |
17 | internal static bool IsSpacePressed(EventKey eventKey)
18 | {
19 | Key key = eventKey.Key;
20 |
21 | return key == Key.space
22 | || key == Key.KP_Space;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ui/Mouse.cs:
--------------------------------------------------------------------------------
1 | using Gdk;
2 |
3 | namespace Codice.Examples.GuiTesting.Linux.UI
4 | {
5 | internal static class Mouse
6 | {
7 | internal static bool IsRightMouseButtonPressed(EventButton eventButton)
8 | {
9 | return eventButton.Button == RIGTH_MOUSE_BUTTON;
10 | }
11 |
12 | const int RIGTH_MOUSE_BUTTON = 3;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ui/ProgressControls.cs:
--------------------------------------------------------------------------------
1 | using Gdk;
2 | using Gtk;
3 |
4 | using Codice.Examples.GuiTesting.Lib.Interfaces;
5 |
6 | namespace Codice.Examples.GuiTesting.Linux.UI
7 | {
8 | internal class ProgressControls : IProgressControls
9 | {
10 | public bool HasError { get { return mbHasError; } }
11 | public Label ProgressLabel { get { return mProgressLabel; } }
12 |
13 | internal ProgressControls(Label progressLabel, Widget[] widgets)
14 | {
15 | mProgressLabel = progressLabel;
16 | mWidgets = widgets;
17 | }
18 |
19 | void IProgressControls.HideProgress()
20 | {
21 | mProgressLabel.Visible = false;
22 |
23 | EnableWidgets(mWidgets);
24 |
25 | if (mbFocusedWidget != null)
26 | mbFocusedWidget.GrabFocus();
27 | }
28 |
29 | void IProgressControls.ShowError(string message)
30 | {
31 | mbHasError = true;
32 |
33 | mProgressLabel.ModifyFg(StateType.Normal, COLOR_RED);
34 | mProgressLabel.Text = message;
35 | mProgressLabel.Visible = true;
36 | }
37 |
38 | void IProgressControls.ShowProgress(string message)
39 | {
40 | mbHasError = false;
41 |
42 | mProgressLabel.ModifyFg(StateType.Normal, COLOR_BLACK);
43 | mProgressLabel.Text = message;
44 | mProgressLabel.Visible = true;
45 |
46 | mbFocusedWidget = GetFocusedWidget(mWidgets);
47 |
48 | DisableWidgets(mWidgets);
49 | }
50 |
51 | static void DisableWidgets(Widget[] widgets)
52 | {
53 | foreach (Widget widget in widgets)
54 | widget.Sensitive = false;
55 | }
56 |
57 | static void EnableWidgets(Widget[] widgets)
58 | {
59 | foreach (Widget widget in widgets)
60 | widget.Sensitive = true;
61 | }
62 |
63 | static Widget GetFocusedWidget(Widget[] widgets)
64 | {
65 | foreach (Widget widget in widgets)
66 | {
67 | if (widget.HasFocus)
68 | return widget;
69 | }
70 |
71 | return null;
72 | }
73 |
74 | Widget mbFocusedWidget;
75 | bool mbHasError;
76 |
77 | readonly Label mProgressLabel;
78 | readonly Widget[] mWidgets;
79 |
80 | static readonly Color COLOR_RED = new Color(255, 0, 0);
81 | static readonly Color COLOR_BLACK = new Color(0, 0, 0);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/application/gui/linux/ui/TreeBuilder.cs:
--------------------------------------------------------------------------------
1 | using Gtk;
2 |
3 | namespace Codice.Examples.GuiTesting.Linux.UI
4 | {
5 | internal static class TreeBuilder
6 | {
7 | internal static TreeView CreateTreeView()
8 | {
9 | TreeView result = new TreeView();
10 | result.FixedHeightMode = true;
11 | result.ButtonPressEvent += TreeView_ProtectButtonPressMultipleSelection;
12 | result.KeyPressEvent += TreeView_ProtectActivateMultipleSelection;
13 |
14 | return result;
15 | }
16 |
17 | internal static TreeViewColumn CreateColumn(
18 | string label,
19 | int fixedWidth,
20 | TreeCellDataFunc renderFunc)
21 | {
22 | TreeViewColumn result = new TreeViewColumn()
23 | {
24 | Title = label,
25 | Sizing = TreeViewColumnSizing.Fixed,
26 | FixedWidth = fixedWidth,
27 | Resizable = true,
28 | Reorderable = false,
29 | SortIndicator = false
30 | };
31 |
32 | CellRendererText cell = new CellRendererText();
33 | result.PackStart(cell, true);
34 | result.SetCellDataFunc(cell, renderFunc);
35 |
36 | return result;
37 | }
38 |
39 | [GLib.ConnectBefore]
40 | static void TreeView_ProtectButtonPressMultipleSelection(
41 | object sender, ButtonPressEventArgs e)
42 | {
43 | TreeView treeView = sender as TreeView;
44 |
45 | if (!Mouse.IsRightMouseButtonPressed(e.Event))
46 | {
47 | e.RetVal = false;
48 | return;
49 | }
50 |
51 | TreePath treePath;
52 | treeView.GetPathAtPos((int)e.Event.X, (int)e.Event.Y, out treePath);
53 |
54 | foreach (TreePath selectedRow in treeView.Selection.GetSelectedRows())
55 | {
56 | if (selectedRow.Equals(treePath))
57 | {
58 | e.RetVal = true;
59 | return;
60 | }
61 | }
62 |
63 | e.RetVal = false;
64 | }
65 |
66 | [GLib.ConnectBefore]
67 | static void TreeView_ProtectActivateMultipleSelection(
68 | object sender, KeyPressEventArgs args)
69 | {
70 | TreeView treeView = sender as TreeView;
71 |
72 | if (Keyboard.IsEnterPressed(args.Event)
73 | || Keyboard.IsSpacePressed(args.Event))
74 | {
75 | treeView.ActivateRow(null, null);
76 | args.RetVal = true;
77 | return;
78 | }
79 |
80 | args.RetVal = false;
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/application/gui/macos/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | using AppKit;
5 | using Foundation;
6 |
7 | using GuiTest;
8 |
9 | using Codice.Examples.GuiTesting.Lib;
10 | using Codice.Examples.GuiTesting.Lib.Threading;
11 | using Codice.Examples.GuiTesting.MacOS.threading;
12 | using Codice.Examples.GuiTesting.Lib.Interfaces;
13 |
14 | namespace Codice.Examples.GuiTesting.MacOS
15 | {
16 | [Register("AppDelegate")]
17 | public class AppDelegate : NSApplicationDelegate
18 | {
19 | public override bool ApplicationShouldTerminateAfterLastWindowClosed(NSApplication sender)
20 | {
21 | return !GetApplicationArgs().IsTestingMode;
22 | }
23 |
24 | public override void DidFinishLaunching(NSNotification notification)
25 | {
26 | ApplicationArgs appArgs = GetApplicationArgs();
27 |
28 | ExceptionsHandler.SetExceptionHandlers(appArgs.IsTestingMode);
29 |
30 | ThreadWaiterBuilder.Initialize(new MacApplicationTimerBuilder());
31 |
32 | WindowHandler.Initialize(this);
33 | GuiMessage.Initialize(new MacOsGuiMessage());
34 |
35 | NSApplication.SharedApplication.ActivateIgnoringOtherApps(true);
36 |
37 | if (appArgs.IsTestingMode)
38 | InstallTestAssembliesResolver(appArgs.PathToAssemblies);
39 |
40 | // Tip: you could launch different windows depending on the
41 | // argument flags.
42 | WindowHandler.LaunchApplicationWindow();
43 |
44 | if (appArgs.IsTestingMode)
45 | {
46 | RemotingHack.ApplyRemotingConfigurationWorkaround();
47 | WindowHandler.LaunchTest(appArgs.TestInfoFile, appArgs.PathToAssemblies);
48 | }
49 | }
50 |
51 | static void InstallTestAssembliesResolver(string pathToAssemblies)
52 | {
53 | List assemblies = new List();
54 | assemblies.Add("nunit.core.dll");
55 | assemblies.Add("nunit.core.interfaces.dll");
56 | assemblies.Add("nunit.util.dll");
57 | assemblies.Add("pnunit.framework.dll");
58 |
59 | assemblies.Add("guitestinterfaces.dll");
60 | assemblies.Add("guitest.dll");
61 |
62 | GuiTestRunner.GuiTestAssemblyResolver.InstallAssemblyResolver(
63 | pathToAssemblies, assemblies);
64 | }
65 |
66 | ApplicationArgs GetApplicationArgs()
67 | {
68 | string[] args = NSProcessInfo.ProcessInfo.Arguments;
69 |
70 | // NSProcessInfo.ProcessInfo.Arguments contains the executable
71 | // path. Just remove it.
72 | string[] result = new string[args.Length - 1];
73 | Array.Copy(args, 1, result, 0, args.Length - 1);
74 |
75 | return ApplicationArgs.Parse(result);
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-128.png
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-128@2x.png
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-16.png
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-16@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-16@2x.png
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-256.png
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-256@2x.png
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-32.png
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-32@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-32@2x.png
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-512.png
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PlasticSCM/GuiTestSharp/0a146b273dd8ad4301508862bb25acce65456728/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "filename": "AppIcon-16.png",
5 | "size": "16x16",
6 | "scale": "1x",
7 | "idiom": "mac"
8 | },
9 | {
10 | "filename": "AppIcon-16@2x.png",
11 | "size": "16x16",
12 | "scale": "2x",
13 | "idiom": "mac"
14 | },
15 | {
16 | "filename": "AppIcon-32.png",
17 | "size": "32x32",
18 | "scale": "1x",
19 | "idiom": "mac"
20 | },
21 | {
22 | "filename": "AppIcon-32@2x.png",
23 | "size": "32x32",
24 | "scale": "2x",
25 | "idiom": "mac"
26 | },
27 | {
28 | "filename": "AppIcon-128.png",
29 | "size": "128x128",
30 | "scale": "1x",
31 | "idiom": "mac"
32 | },
33 | {
34 | "filename": "AppIcon-128@2x.png",
35 | "size": "128x128",
36 | "scale": "2x",
37 | "idiom": "mac"
38 | },
39 | {
40 | "filename": "AppIcon-256.png",
41 | "size": "256x256",
42 | "scale": "1x",
43 | "idiom": "mac"
44 | },
45 | {
46 | "filename": "AppIcon-256@2x.png",
47 | "size": "256x256",
48 | "scale": "2x",
49 | "idiom": "mac"
50 | },
51 | {
52 | "filename": "AppIcon-512.png",
53 | "size": "512x512",
54 | "scale": "1x",
55 | "idiom": "mac"
56 | },
57 | {
58 | "filename": "AppIcon-512@2x.png",
59 | "size": "512x512",
60 | "scale": "2x",
61 | "idiom": "mac"
62 | }
63 | ],
64 | "info": {
65 | "version": 1,
66 | "author": "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/src/application/gui/macos/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/src/application/gui/macos/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/application/gui/macos/ExceptionsHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
4 |
5 | namespace Codice.Examples.GuiTesting.MacOS
6 | {
7 | internal class ExceptionsHandler
8 | {
9 | internal static void SetExceptionHandlers(bool isTestingMode)
10 | {
11 | if (isTestingMode)
12 | {
13 | SetTestingExceptionHandlers();
14 | return;
15 | }
16 |
17 | SetStandardExceptionHandlers();
18 | }
19 |
20 | static void SetStandardExceptionHandlers()
21 | {
22 | AppDomain.CurrentDomain.UnhandledException += HandleUndhandledException;
23 | }
24 |
25 | static void SetTestingExceptionHandlers()
26 | {
27 | AppDomain.CurrentDomain.UnhandledException += HandleTestingUnhandledException;
28 | }
29 |
30 | static void HandleUndhandledException(
31 | object sender, UnhandledExceptionEventArgs e)
32 | {
33 | // Here you'd usually log the exception, send telemetry events...
34 | }
35 |
36 | static void HandleTestingUnhandledException(
37 | object sender, UnhandledExceptionEventArgs e)
38 | {
39 | // We don't want to eat up the exception during testing like nothing
40 | // happens, but we still want to save it in order to display it
41 | // as the cause of the failed test.
42 | GuiTesteableServices.UnhandledException = (Exception)e.ExceptionObject;
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/application/gui/macos/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleName
6 | macos
7 | CFBundleIdentifier
8 | com.codicesoftware.guitesting.macos
9 | CFBundleShortVersionString
10 | 1.0
11 | CFBundleVersion
12 | 1
13 | LSMinimumSystemVersion
14 | 10.7
15 | CFBundleDevelopmentRegion
16 | en
17 | CFBundleInfoDictionaryVersion
18 | 6.0
19 | CFBundlePackageType
20 | APPL
21 | NSPrincipalClass
22 | NSApplication
23 | XSAppIconAssets
24 | Assets.xcassets/AppIcon.appiconset
25 | MonoBundleExecutable
26 | macos.exe
27 | CFBundleExecutable
28 | macos
29 | CFBundleDisplayName
30 | GUI Testing example
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/application/gui/macos/MacOsGuiMessage.cs:
--------------------------------------------------------------------------------
1 | using AppKit;
2 |
3 | using Codice.Examples.GuiTesting.Lib;
4 | using Codice.Examples.GuiTesting.Lib.Interfaces;
5 |
6 | namespace Codice.Examples.GuiTesting.MacOS
7 | {
8 | public class MacOsGuiMessage : GuiMessage.IGuiMessage
9 | {
10 | void GuiMessage.IGuiMessage.ShowError(string title, string message)
11 | {
12 | NSAlert alert = new NSAlert();
13 | alert.MessageText = title;
14 | alert.InformativeText = message;
15 | alert.Icon = NSImage.ImageNamed(NSImageName.Caution);
16 | alert.AlertStyle = NSAlertStyle.Warning;
17 |
18 | NSButton closeButton = alert.AddButton(
19 | Localization.GetText(Localization.Name.Ok));
20 | closeButton.KeyEquivalent = ESC_KEY_EQUIVALENT;
21 |
22 | WindowHandler.SetActiveDialogForTesting(alert);
23 |
24 | alert.RunModal();
25 |
26 | WindowHandler.RemoveDialogForTesting(alert);
27 | }
28 |
29 | internal static readonly string ESC_KEY_EQUIVALENT =
30 | ((char)0x001B).ToString();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/application/gui/macos/Main.cs:
--------------------------------------------------------------------------------
1 | using AppKit;
2 |
3 | namespace Codice.Examples.GuiTesting.MacOS
4 | {
5 | static class MainClass
6 | {
7 | static void Main(string[] args)
8 | {
9 | NSApplication.Init();
10 |
11 | // You only need this hack if you removed your MainMenu.xib class,
12 | // which is in charge of pointing out which is your Application's
13 | // delegate.
14 | NSApplication.SharedApplication.Delegate = new AppDelegate();
15 |
16 | NSApplication.Main(args);
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/application/gui/macos/RemotingHack.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Runtime.Remoting;
4 | using System.Reflection;
5 |
6 | namespace Codice.Examples.GuiTesting.MacOS
7 | {
8 | internal static class RemotingHack
9 | {
10 | internal static void ApplyRemotingConfigurationWorkaround()
11 | {
12 | new MonoBug44707_Workaround().HackMonoBug_44707();
13 | }
14 |
15 | class MonoBug44707_Workaround
16 | {
17 | // Bug #44707
18 | // RemotingConfiguration.Configure() throws RemotingException because
19 | // it cannot load 'machine.config'
20 | // https://bugzilla.xamarin.com/show_bug.cgi?id=44707
21 | internal void HackMonoBug_44707()
22 | {
23 | string machineConfigPath = Path.Combine(
24 | Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
25 | "machine.config");
26 |
27 | MethodInfo readConfigMethod =
28 | typeof(RemotingConfiguration).GetMethod(
29 | "ReadConfigFile",
30 | BindingFlags.NonPublic | BindingFlags.Static);
31 | CheckValidReadConfigFileMethod(readConfigMethod);
32 |
33 | readConfigMethod.Invoke(this, new[] { machineConfigPath });
34 |
35 | FieldInfo defaultReadField =
36 | typeof(RemotingConfiguration).GetField(
37 | "defaultConfigRead",
38 | BindingFlags.NonPublic | BindingFlags.Static);
39 | CheckValidDefaultConfigReadField(defaultReadField);
40 |
41 | defaultReadField.SetValue(this, true);
42 | }
43 |
44 | static void CheckValidReadConfigFileMethod(MethodInfo mi)
45 | {
46 | if (mi != null)
47 | return;
48 |
49 | throw new InvalidOperationException(
50 | "RemotingHack failed - ReadConfigFile method not found " +
51 | "in RemotingConfiguration class.");
52 | }
53 |
54 | static void CheckValidDefaultConfigReadField(FieldInfo fi)
55 | {
56 | if (fi != null)
57 | return;
58 |
59 | throw new InvalidOperationException(
60 | "RemotingHack failed - 'defaulConfigRead' field not found " +
61 | "in RemotingConfiguration class.");
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/application/gui/macos/ViewController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | using AppKit;
4 | using Foundation;
5 |
6 | namespace macos
7 | {
8 | public partial class ViewController : NSViewController
9 | {
10 | public ViewController(IntPtr handle) : base(handle)
11 | {
12 | }
13 |
14 | public override void ViewDidLoad()
15 | {
16 | base.ViewDidLoad();
17 |
18 | // Do any additional setup after loading the view.
19 | }
20 |
21 | public override NSObject RepresentedObject
22 | {
23 | get
24 | {
25 | return base.RepresentedObject;
26 | }
27 | set
28 | {
29 | base.RepresentedObject = value;
30 | // Update the view, if already loaded.
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/application/gui/macos/ViewController.designer.cs:
--------------------------------------------------------------------------------
1 | // WARNING
2 | //
3 | // This file has been generated automatically by Xamarin Studio to store outlets and
4 | // actions made in the UI designer. If it is removed, they will be lost.
5 | // Manual changes to this file may not be handled correctly.
6 | //
7 | using Foundation;
8 |
9 | namespace macos
10 | {
11 | [Register("ViewController")]
12 | partial class ViewController
13 | {
14 | void ReleaseDesignerOutlets()
15 | {
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/application/gui/macos/WindowHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Runtime.InteropServices;
5 | using System.Threading;
6 |
7 | using AppKit;
8 | using Foundation;
9 |
10 | using log4net;
11 | using log4net.Config;
12 | using log4net.Repository;
13 |
14 | using GuiTest;
15 |
16 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
17 | using Codice.Examples.GuiTesting.Lib;
18 | using Codice.Examples.GuiTesting.MacOS.Testing;
19 |
20 | namespace Codice.Examples.GuiTesting.MacOS
21 | {
22 | internal static class WindowHandler
23 | {
24 | internal static NSWindow ApplicationWindow
25 | {
26 | get { return mApplicationWindow; }
27 | }
28 |
29 | internal static void Initialize(NSObject application)
30 | {
31 | mApplication = application;
32 | }
33 |
34 | internal static void LaunchApplicationWindow()
35 | {
36 | ApplicationOperations operations = new ApplicationOperations();
37 | mApplicationWindow = new ApplicationWindow(operations);
38 | mApplicationWindow.ReleasedWhenClosed = true;
39 | mApplicationWindow.MakeKeyAndOrderFront(mApplication);
40 | }
41 |
42 | internal static void UnregisterApplicationWindow()
43 | {
44 | mApplicationWindow = null;
45 | }
46 |
47 | internal static void SetActiveDialogForTesting(NSObject dialog)
48 | {
49 | if (!mbIsTestRun)
50 | return;
51 |
52 | mActiveDialog = dialog;
53 | }
54 |
55 | internal static void RemoveDialogForTesting(NSObject dialog)
56 | {
57 | if (!mbIsTestRun)
58 | return;
59 |
60 | if (mActiveDialog == dialog)
61 | mActiveDialog = null;
62 | }
63 |
64 | internal static NSObject GetActiveDialog()
65 | {
66 | return mActiveDialog;
67 | }
68 |
69 | internal static void LaunchTest(string testInfoFile, string pathToAssemblies)
70 | {
71 | mbIsTestRun = true;
72 |
73 | ConfigureTestLogging();
74 | InitTesteableServices();
75 |
76 | GuiTestRunner testRunner = new GuiTestRunner(
77 | testInfoFile, pathToAssemblies, new GuiFinalizer(), null);
78 |
79 | ThreadPool.QueueUserWorkItem(new WaitCallback(testRunner.Run));
80 | }
81 |
82 | static void ConfigureTestLogging()
83 | {
84 | try
85 | {
86 | string log4netPath = Path.Combine(
87 | Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
88 | "pnunittestrunner.log.conf");
89 |
90 | XmlConfigurator.Configure(new FileInfo(log4netPath));
91 | }
92 | catch { }
93 | }
94 |
95 | static void InitTesteableServices()
96 | {
97 | TesteableApplicationWindow testeableWindow =
98 | new TesteableApplicationWindow(mApplicationWindow);
99 |
100 | GuiTesteableServices.Init(testeableWindow);
101 | }
102 |
103 | static NSObject mApplication;
104 |
105 | static ApplicationWindow mApplicationWindow;
106 | static NSObject mActiveDialog;
107 | static bool mbIsTestRun = false;
108 |
109 | class GuiFinalizer : GuiTestRunner.IGuiFinalizer
110 | {
111 | void GuiTestRunner.IGuiFinalizer.Finalize(int exitCode)
112 | {
113 | // Environmnet.Exit is unable to terminate unmanaged threads
114 | // launched by the native Cocoa framework. We don't use any
115 | // in this example application, but you could face crashes
116 | // if you decide to rely on Environment.Exit to set an exit code.
117 | Exit(exitCode);
118 | }
119 |
120 | [DllImport("__Internal", EntryPoint = "exit")]
121 | static extern void Exit(int exitCode);
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/application/gui/macos/macos.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "macos", "macos.csproj", "{6D9C8C74-3091-4963-BD5B-BF71A8611E01}"
5 | EndProject
6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testing", "testing", "{423E90A2-ACD1-4793-B302-C97C10DF4AD7}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "guitest", "..\..\..\testing\guitest\guitest.csproj", "{9EE461F0-5FCA-4631-8335-73E1A0AF2861}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pnunit.framework", "..\..\..\..\lib\pnunit\pnunit.framework\pnunit.framework.csproj", "{5261ABA1-98E6-4603-A4F0-59CAC307AC68}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "guitestinterfaces", "..\..\..\testing\guitestinterfaces\guitestinterfaces.csproj", "{D775E82D-4045-4E11-AE85-4402CA0AD054}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lib", "..\..\lib\lib.csproj", "{A1079FA8-882B-40D6-A289-3A13767CABDD}"
15 | EndProject
16 | Global
17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
18 | Debug|x86 = Debug|x86
19 | Release|x86 = Release|x86
20 | NAnt|Any CPU = NAnt|Any CPU
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {6D9C8C74-3091-4963-BD5B-BF71A8611E01}.Debug|x86.ActiveCfg = Debug|x86
24 | {6D9C8C74-3091-4963-BD5B-BF71A8611E01}.Debug|x86.Build.0 = Debug|x86
25 | {6D9C8C74-3091-4963-BD5B-BF71A8611E01}.Release|x86.ActiveCfg = Release|x86
26 | {6D9C8C74-3091-4963-BD5B-BF71A8611E01}.Release|x86.Build.0 = Release|x86
27 | {6D9C8C74-3091-4963-BD5B-BF71A8611E01}.NAnt|Any CPU.ActiveCfg = Debug|x86
28 | {6D9C8C74-3091-4963-BD5B-BF71A8611E01}.NAnt|Any CPU.Build.0 = Debug|x86
29 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Debug|x86.ActiveCfg = Debug|Any CPU
30 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Debug|x86.Build.0 = Debug|Any CPU
31 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Release|x86.ActiveCfg = Release|Any CPU
32 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Release|x86.Build.0 = Release|Any CPU
33 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.NAnt|Any CPU.ActiveCfg = Debug|Any CPU
34 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.NAnt|Any CPU.Build.0 = Debug|Any CPU
35 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Debug|x86.ActiveCfg = Debug|Any CPU
36 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Debug|x86.Build.0 = Debug|Any CPU
37 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Release|x86.ActiveCfg = Release|Any CPU
38 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Release|x86.Build.0 = Release|Any CPU
39 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.NAnt|Any CPU.ActiveCfg = NAnt|Any CPU
40 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.NAnt|Any CPU.Build.0 = NAnt|Any CPU
41 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Debug|x86.ActiveCfg = Debug|Any CPU
42 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Debug|x86.Build.0 = Debug|Any CPU
43 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Release|x86.ActiveCfg = Release|Any CPU
44 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Release|x86.Build.0 = Release|Any CPU
45 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.NAnt|Any CPU.ActiveCfg = Debug|Any CPU
46 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.NAnt|Any CPU.Build.0 = Debug|Any CPU
47 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Debug|x86.ActiveCfg = Debug|Any CPU
48 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Debug|x86.Build.0 = Debug|Any CPU
49 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Release|x86.ActiveCfg = Release|Any CPU
50 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Release|x86.Build.0 = Release|Any CPU
51 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.NAnt|Any CPU.ActiveCfg = Debug|Any CPU
52 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.NAnt|Any CPU.Build.0 = Debug|Any CPU
53 | EndGlobalSection
54 | GlobalSection(NestedProjects) = preSolution
55 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861} = {423E90A2-ACD1-4793-B302-C97C10DF4AD7}
56 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68} = {423E90A2-ACD1-4793-B302-C97C10DF4AD7}
57 | {D775E82D-4045-4E11-AE85-4402CA0AD054} = {423E90A2-ACD1-4793-B302-C97C10DF4AD7}
58 | EndGlobalSection
59 | GlobalSection(MonoDevelopProperties) = preSolution
60 | outputpath = ../../../../bin/application
61 | EndGlobalSection
62 | EndGlobal
63 |
--------------------------------------------------------------------------------
/src/application/gui/macos/testing/TesteableApplicationWindow.cs:
--------------------------------------------------------------------------------
1 | using AppKit;
2 |
3 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
4 |
5 | namespace Codice.Examples.GuiTesting.MacOS.Testing
6 | {
7 | internal class TesteableApplicationWindow : ITesteableApplicationWindow
8 | {
9 | public TesteableApplicationWindow(ApplicationWindow window)
10 | {
11 | mWindow = window;
12 | mHelper = new TestHelper();
13 | }
14 |
15 | void ITesteableApplicationWindow.ClickAddButton()
16 | {
17 | mHelper.ClickButton(mWindow.AddButton);
18 | }
19 |
20 | void ITesteableApplicationWindow.ClickRemoveButton()
21 | {
22 | mHelper.ClickButton(mWindow.RemoveButton);
23 | }
24 |
25 | bool ITesteableApplicationWindow.AreButtonsEnabled()
26 | {
27 | return mHelper.IsEnabled(mWindow.AddButton)
28 | && mHelper.IsEnabled(mWindow.RemoveButton);
29 | }
30 |
31 | void ITesteableApplicationWindow.ChangeText(string text)
32 | {
33 | mHelper.SetText(mWindow.TextField, text);
34 | }
35 |
36 | string ITesteableApplicationWindow.GetText()
37 | {
38 | return mHelper.GetText(mWindow.TextField);
39 | }
40 |
41 | int ITesteableApplicationWindow.GetItemsInListCount()
42 | {
43 | return mHelper.GetItemCount(mWindow.TableView);
44 | }
45 |
46 | string ITesteableApplicationWindow.GetItemInListAt(int index)
47 | {
48 | return mHelper.GetItemAt(mWindow.TableView, "Text", index);
49 | }
50 |
51 | string ITesteableApplicationWindow.GetProgressMessage()
52 | {
53 | if (mWindow.ProgressControls.HasError)
54 | return string.Empty;
55 |
56 | return mHelper.GetText(mWindow.ProgressControls.ProgressTextField);
57 | }
58 |
59 | string ITesteableApplicationWindow.GetErrorMessage()
60 | {
61 | if (!mWindow.ProgressControls.HasError)
62 | return string.Empty;
63 |
64 | return mHelper.GetText(mWindow.ProgressControls.ProgressTextField);
65 | }
66 |
67 | ITesteableErrorDialog ITesteableApplicationWindow.GetErrorDialog()
68 | {
69 | if (WindowHandler.GetActiveDialog() == null)
70 | return null;
71 |
72 | NSAlert errorDialog = WindowHandler.GetActiveDialog() as NSAlert;
73 | if (errorDialog == null)
74 | return null;
75 |
76 | return new TesteableErrorDialog(errorDialog);
77 | }
78 |
79 | readonly ApplicationWindow mWindow;
80 | readonly TestHelper mHelper;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/application/gui/macos/testing/TesteableErrorDialog.cs:
--------------------------------------------------------------------------------
1 | using AppKit;
2 |
3 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
4 | using Codice.Examples.GuiTesting.Lib;
5 |
6 | namespace Codice.Examples.GuiTesting.MacOS.Testing
7 | {
8 | internal class TesteableErrorDialog : ITesteableErrorDialog
9 | {
10 | internal TesteableErrorDialog(NSAlert alert)
11 | {
12 | mAlert = alert;
13 | mHelper = new TestHelper();
14 | }
15 |
16 | void ITesteableErrorDialog.ClickOkButton()
17 | {
18 | mHelper.ClickDialogButton(
19 | mHelper.GetButton(
20 | mAlert,
21 | Localization.GetText(Localization.Name.Ok)));
22 | }
23 |
24 | string ITesteableErrorDialog.GetTitle()
25 | {
26 | return mHelper.GetAlertTitle(mAlert);
27 | }
28 |
29 | string ITesteableErrorDialog.GetMessage()
30 | {
31 | return mHelper.GetAlertMessage(mAlert);
32 | }
33 |
34 | readonly NSAlert mAlert;
35 | readonly TestHelper mHelper;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/application/gui/macos/threading/MacApplicationTimer.cs:
--------------------------------------------------------------------------------
1 | using Foundation;
2 |
3 | using Codice.Examples.GuiTesting.Lib.Threading;
4 |
5 | namespace Codice.Examples.GuiTesting.MacOS.threading
6 | {
7 | public class MacApplicationTimerBuilder : IApplicationTimerBuilder
8 | {
9 | IApplicationTimer IApplicationTimerBuilder.Get(
10 | bool bModalMode, ThreadWaiter.TimerTick timerTickDelegate)
11 | {
12 | return new MacApplicationTimer(DEFAULT_TIMER_INTERVAL, timerTickDelegate);
13 | }
14 |
15 | const double DEFAULT_TIMER_INTERVAL = 0.0001;
16 | }
17 |
18 | public class MacApplicationTimer : IApplicationTimer
19 | {
20 | internal MacApplicationTimer(
21 | double timerInterval, ThreadWaiter.TimerTick timerTickDelegate)
22 | {
23 | mTimerInterval = timerInterval;
24 | mTimerTickDelegate = timerTickDelegate;
25 | }
26 |
27 | void IApplicationTimer.Start()
28 | {
29 | mTimer = NSTimer.CreateRepeatingScheduledTimer(
30 | mTimerInterval, OnTimerTick);
31 | NSRunLoop.Current.AddTimer(mTimer, NSRunLoopMode.EventTracking);
32 | }
33 |
34 | void IApplicationTimer.Stop()
35 | {
36 | if (mTimer == null)
37 | return;
38 |
39 | mTimer.Invalidate();
40 | mTimer = null;
41 | }
42 |
43 | void OnTimerTick(NSTimer timer)
44 | {
45 | mTimerTickDelegate();
46 | }
47 |
48 | readonly double mTimerInterval;
49 | readonly ThreadWaiter.TimerTick mTimerTickDelegate;
50 |
51 | NSTimer mTimer;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/application/gui/macos/ui/NSColors.cs:
--------------------------------------------------------------------------------
1 | using AppKit;
2 |
3 | namespace Codice.Examples.GuiTesting.MacOS.UI
4 | {
5 | internal static class NSColors
6 | {
7 | internal static readonly NSColor NotificationText = GetColorFromRgb(0, 103, 149);
8 | internal static readonly NSColor ErrorText = GetColorFromRgb(198, 38, 53);
9 |
10 | internal static NSColor GetColorFromRgb(int r, int g, int b)
11 | {
12 | return NSColor.FromCalibratedRgba(
13 | r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/application/gui/macos/ui/NSViewPacker.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | using AppKit;
4 | using Foundation;
5 |
6 | namespace Codice.Examples.GuiTesting.MacOS.UI
7 | {
8 | internal static class NSViewPacker
9 | {
10 | internal static void PackViews(
11 | NSView parent, string[] constraints, NSDictionary views)
12 | {
13 | foreach (NSView view in views.Values)
14 | {
15 | view.TranslatesAutoresizingMaskIntoConstraints = false;
16 | parent.AddSubview(view);
17 | }
18 |
19 | parent.AddConstraints(BuildConstraints(constraints, views));
20 | }
21 |
22 | internal static void Fill(NSView parent, NSView child)
23 | {
24 | PackViews(
25 | parent,
26 | new string[]
27 | {
28 | "H:|[child]|",
29 | "V:|[child]|"
30 | },
31 | new NSDictionary("child", child));
32 | }
33 |
34 | static NSLayoutConstraint[] BuildConstraints(
35 | string[] constraints, NSDictionary views)
36 | {
37 | List result = new List();
38 |
39 | foreach (string format in constraints)
40 | result.AddRange(NSLayoutConstraint.FromVisualFormat(format, 0, null, views));
41 |
42 | return result.ToArray();
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/application/gui/macos/ui/ProgressControls.cs:
--------------------------------------------------------------------------------
1 | using AppKit;
2 |
3 | using Codice.Examples.GuiTesting.Lib.Interfaces;
4 |
5 | namespace Codice.Examples.GuiTesting.MacOS.UI
6 | {
7 | internal class ProgressControls : IProgressControls
8 | {
9 | public bool HasError { get { return mbHasError; } }
10 | public NSTextField ProgressTextField { get { return mProgressTextField; } }
11 |
12 | internal ProgressControls(
13 | NSWindow window, NSTextField progressTextField, NSView[] views)
14 | {
15 | mWindow = window;
16 | mProgressTextField = progressTextField;
17 | mViews = views;
18 | }
19 |
20 | void IProgressControls.ShowProgress(string message)
21 | {
22 | mbHasError = false;
23 |
24 | mProgressTextField.TextColor = NSColors.NotificationText;
25 | mProgressTextField.StringValue = message;
26 | mProgressTextField.Hidden = false;
27 |
28 | mResponder = NSViewArray.GetFirstResponder(mWindow, mViews);
29 |
30 | NSViewArray.Disable(mViews);
31 | }
32 |
33 | void IProgressControls.HideProgress()
34 | {
35 | mProgressTextField.Hidden = true;
36 |
37 | NSViewArray.Enable(mViews);
38 |
39 | if (mResponder != null)
40 | mWindow.MakeFirstResponder(mResponder);
41 | }
42 |
43 | void IProgressControls.ShowError(string message)
44 | {
45 | mbHasError = true;
46 |
47 | mProgressTextField.TextColor = NSColors.ErrorText;
48 | mProgressTextField.StringValue = message;
49 | mProgressTextField.Hidden = false;
50 | }
51 |
52 | NSResponder mResponder;
53 | bool mbHasError = false;
54 |
55 | readonly NSWindow mWindow;
56 | readonly NSTextField mProgressTextField;
57 | readonly NSView[] mViews;
58 |
59 | static class NSViewArray
60 | {
61 | internal static void Enable(NSView[] views)
62 | {
63 | SetEnablement(views, true);
64 | }
65 |
66 | internal static void Disable(NSView[] views)
67 | {
68 | SetEnablement(views, false);
69 | }
70 |
71 | internal static NSView GetFirstResponder(NSWindow window, NSView[] views)
72 | {
73 | if (views == null)
74 | return null;
75 |
76 | foreach (NSView view in views)
77 | {
78 | if (window.FirstResponder == view)
79 | return view;
80 | }
81 |
82 | return null;
83 | }
84 |
85 | static void SetEnablement(NSView[] views, bool enabled)
86 | {
87 | if (views == null)
88 | return;
89 |
90 | foreach (NSView view in views)
91 | {
92 | if (view == null)
93 | continue;
94 |
95 | NSControl control = view as NSControl;
96 | if (control != null)
97 | {
98 | control.Enabled = enabled;
99 | continue;
100 | }
101 |
102 | NSTextView textView = view as NSTextView;
103 | if (textView != null)
104 | {
105 | textView.Selectable = enabled;
106 | textView.Editable = enabled;
107 |
108 | textView.TextColor = enabled
109 | ? NSColor.ControlText
110 | : NSColor.DisabledControlText;
111 | }
112 | }
113 | }
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/application/gui/windows/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/application/gui/windows/ErrorDialog.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | using Codice.Examples.GuiTesting.Lib;
6 | using Codice.Examples.GuiTesting.Windows.UI;
7 |
8 | namespace Codice.Examples.GuiTesting.Windows
9 | {
10 | internal class ErrorDialog : Form
11 | {
12 | internal Button OkButton { get { return mOkButton; } }
13 | internal Label MessageLabel { get { return mMessageLabel; } }
14 |
15 | internal ErrorDialog(string title, string message)
16 | {
17 | BuildComponents();
18 |
19 | Text = title;
20 | mMessageLabel.Text = message;
21 | }
22 |
23 | protected override void Dispose(bool disposing)
24 | {
25 | if (disposing)
26 | mOkButton.Click -= OkButton_Click;
27 |
28 | base.Dispose(disposing);
29 | }
30 |
31 | void OkButton_Click(object sender, EventArgs e)
32 | {
33 | DialogResult = DialogResult.OK;
34 | Close();
35 | }
36 |
37 | void BuildComponents()
38 | {
39 | Width = DIALOG_WIDTH;
40 | Height = DIALOG_HEIGHT;
41 | FormBorderStyle = FormBorderStyle.FixedDialog;
42 | MinimizeBox = false;
43 | MaximizeBox = false;
44 |
45 | SuspendLayout();
46 | try
47 | {
48 | ControlPacker.AddControl(
49 | this, ControlBuilder.CreateVerticalPadding(DockStyle.Top));
50 | ControlPacker.AddControl(this, BuildMessagePanel());
51 | ControlPacker.AddControl(
52 | this, ControlBuilder.CreateVerticalPadding(DockStyle.Top));
53 | ControlPacker.AddControl(this, BuildButtonPanel());
54 | ControlPacker.AddControl(
55 | this, ControlBuilder.CreateVerticalPadding(DockStyle.Bottom));
56 | }
57 | finally
58 | {
59 | ResumeLayout();
60 | }
61 | }
62 |
63 | Panel BuildMessagePanel()
64 | {
65 | Panel result = ControlBuilder.CreatePanel(DockStyle.Top);
66 | result.Height = 70;
67 |
68 | PictureBox errorPictureBox = ControlBuilder.CreatePictureBox(
69 | SystemIcons.Error.ToBitmap(), DockStyle.Left);
70 | mMessageLabel = ControlBuilder.CreateLabel(string.Empty, DockStyle.Fill);
71 | mMessageLabel.AutoSize = false;
72 |
73 | ControlPacker.AddControl(
74 | result, ControlBuilder.CreateHorizontalPadding(DockStyle.Left));
75 | ControlPacker.AddControl(result, errorPictureBox);
76 | ControlPacker.AddControl(
77 | result, ControlBuilder.CreateHorizontalPadding(DockStyle.Left));
78 | ControlPacker.AddControl(result, mMessageLabel);
79 | ControlPacker.AddControl(
80 | result, ControlBuilder.CreateHorizontalPadding(DockStyle.Right));
81 |
82 | return result;
83 | }
84 |
85 | Panel BuildButtonPanel()
86 | {
87 | Panel result = ControlBuilder.CreatePanel(
88 | ControlBuilder.DefaultControlHeight, DockStyle.Top);
89 |
90 | mOkButton = ControlBuilder.CreateButton(
91 | Localization.GetText(Localization.Name.Ok), DockStyle.Right);
92 |
93 | mOkButton.Click += OkButton_Click;
94 | CancelButton = mOkButton;
95 |
96 | ControlPacker.AddControl(result, mOkButton);
97 | ControlPacker.AddControl(
98 | result, ControlBuilder.CreateHorizontalPadding(DockStyle.Right));
99 |
100 | return result;
101 | }
102 |
103 | Label mMessageLabel;
104 | Button mOkButton;
105 |
106 | const int DIALOG_WIDTH = 310;
107 | const int DIALOG_HEIGHT = 155;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/application/gui/windows/ExceptionsHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Windows.Forms;
4 |
5 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
6 |
7 | namespace Codice.Examples.GuiTesting.Windows
8 | {
9 | internal static class ExceptionsHandler
10 | {
11 | internal static void SetExceptionHandlers(bool isTestingMode)
12 | {
13 | if (isTestingMode)
14 | {
15 | SetTestingExceptionHandlers();
16 | return;
17 | }
18 |
19 | SetStandardExceptionHandlers();
20 | }
21 |
22 | static void SetStandardExceptionHandlers()
23 | {
24 | Application.ThreadException += HandleThreadException;
25 | AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException;
26 | }
27 |
28 | static void SetTestingExceptionHandlers()
29 | {
30 | // We don't want to eat up the exception during testing like nothing
31 | // happens, but we still want to save it in order to display it
32 | // as the cause of the failed test.
33 | Application.ThreadException += HandleTestingThreadException;
34 | AppDomain.CurrentDomain.UnhandledException += HandleTestingUnhandledException;
35 | }
36 |
37 | static void HandleThreadException(object sender, ThreadExceptionEventArgs e)
38 | {
39 | // Here you'd usually log the exception, send telemetry events...
40 | }
41 |
42 | static void HandleUnhandledException(object sender, UnhandledExceptionEventArgs e)
43 | {
44 | // Here you'd usually log the exception, send telemetry events...
45 | }
46 |
47 | static void HandleTestingThreadException(object sender, ThreadExceptionEventArgs e)
48 | {
49 | HandleTestingException(e.Exception);
50 | }
51 |
52 | static void HandleTestingUnhandledException(object sender, UnhandledExceptionEventArgs e)
53 | {
54 | HandleTestingException((Exception)e.ExceptionObject);
55 | }
56 |
57 | static void HandleTestingException(Exception ex)
58 | {
59 | GuiTesteableServices.UnhandledException = ex;
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/application/gui/windows/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Windows.Forms;
4 |
5 | using GuiTest;
6 |
7 | using Codice.Examples.GuiTesting.Lib;
8 | using Codice.Examples.GuiTesting.Lib.Threading;
9 | using Codice.Examples.GuiTesting.Windows.Threading;
10 | using Codice.Examples.GuiTesting.Lib.Interfaces;
11 |
12 | namespace Codice.Examples.GuiTesting.Windows
13 | {
14 | static class Program
15 | {
16 | [STAThread]
17 | static void Main(string[] args)
18 | {
19 | try
20 | {
21 | ApplicationArgs appArgs = ApplicationArgs.Parse(args);
22 |
23 | ExceptionsHandler.SetExceptionHandlers(appArgs.IsTestingMode);
24 |
25 | ThreadWaiterBuilder.Initialize(new WinPlasticTimerBuilder());
26 |
27 | GuiMessage.Initialize(new WindowsGuiMessage());
28 |
29 | Application.EnableVisualStyles();
30 | Application.SetCompatibleTextRenderingDefault(false);
31 |
32 | if (appArgs.IsTestingMode)
33 | InstallTestAssembliesResolver(appArgs.PathToAssemblies);
34 |
35 | // Tip: you could launch different windows depending on the
36 | // argument flags.
37 | WindowHandler.LaunchApplicationWindow();
38 |
39 | if (appArgs.IsTestingMode)
40 | WindowHandler.LaunchTest(appArgs.TestInfoFile, appArgs.PathToAssemblies);
41 |
42 | Application.Run();
43 | }
44 | catch
45 | {
46 | // You would track the exception here.
47 | ExitCode = 1;
48 | Application.Exit();
49 | }
50 | finally
51 | {
52 | // You would dispose everything you need here.
53 | Environment.Exit(ExitCode);
54 | }
55 | }
56 |
57 | static void InstallTestAssembliesResolver(string pathToAssemblies)
58 | {
59 | List assemblies = new List();
60 | assemblies.Add("nunit.core.dll");
61 | assemblies.Add("nunit.core.interfaces.dll");
62 | assemblies.Add("nunit.util.dll");
63 | assemblies.Add("pnunit.framework.dll");
64 |
65 | assemblies.Add("guitestinterfaces.dll");
66 | assemblies.Add("guitest.dll");
67 |
68 | GuiTestRunner.GuiTestAssemblyResolver.InstallAssemblyResolver(
69 | pathToAssemblies, assemblies);
70 | }
71 |
72 | static int ExitCode = 0;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/application/gui/windows/WindowHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Threading;
5 | using System.Windows.Forms;
6 |
7 | using log4net;
8 | using log4net.Config;
9 | using log4net.Repository;
10 |
11 | using GuiTest;
12 |
13 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
14 | using Codice.Examples.GuiTesting.Lib;
15 | using Codice.Examples.GuiTesting.Windows.Testing;
16 |
17 | namespace Codice.Examples.GuiTesting.Windows
18 | {
19 | internal static class WindowHandler
20 | {
21 | internal static IWin32Window ApplicationWindow
22 | {
23 | get { return mApplicationWindow; }
24 | }
25 |
26 | internal static void LaunchApplicationWindow()
27 | {
28 | ApplicationOperations operations = new ApplicationOperations();
29 | mApplicationWindow = new ApplicationWindow(operations);
30 | mApplicationWindow.StartPosition = FormStartPosition.CenterScreen;
31 | mApplicationWindow.Show();
32 | }
33 |
34 | internal static void UnregisterApplicationWindow()
35 | {
36 | mApplicationWindow.Dispose();
37 | mApplicationWindow = null;
38 |
39 | TerminateApplication();
40 | }
41 |
42 | internal static void SetActiveDialogForTesting(Form dialog)
43 | {
44 | if (!mbIsTestRun)
45 | return;
46 |
47 | mActiveDialog = dialog;
48 | }
49 |
50 | internal static void RemoveDialogForTesting(Form dialog)
51 | {
52 | if (!mbIsTestRun)
53 | return;
54 |
55 | if (mActiveDialog == dialog)
56 | mActiveDialog = null;
57 | }
58 |
59 | internal static Form GetActiveDialog()
60 | {
61 | if (mActiveDialog == null)
62 | return null;
63 |
64 | // Although by this point the Form is created, it might not be
65 | // visible yet, so it's handle is not created.
66 | // If the handle is not created, all Invoke and BeginInvoke calls
67 | // will fail, so we'll have to wait.
68 | while (!mActiveDialog.IsHandleCreated) { }
69 |
70 | return mActiveDialog;
71 | }
72 |
73 | internal static void LaunchTest(string testInfoFile, string pathToAssemblies)
74 | {
75 | mbIsTestRun = true;
76 |
77 | ConfigureTestLogging();
78 | InitTesteableServices();
79 |
80 | GuiTestRunner testRunner = new GuiTestRunner(
81 | testInfoFile, pathToAssemblies, new GuiFinalizer(), null);
82 |
83 | ThreadPool.QueueUserWorkItem(new WaitCallback(testRunner.Run));
84 | }
85 |
86 | static void ConfigureTestLogging()
87 | {
88 | try
89 | {
90 | string log4netPath = Path.Combine(
91 | Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
92 | "pnunittestrunner.log.conf");
93 |
94 | XmlConfigurator.Configure(mLogRepository, new FileInfo(log4netPath));
95 | }
96 | catch { } // Log config failed, nothing else to do!
97 | }
98 |
99 | static void InitTesteableServices()
100 | {
101 | TesteableApplicationWindow testeableWindow =
102 | new TesteableApplicationWindow(mApplicationWindow);
103 |
104 | GuiTesteableServices.Init(testeableWindow);
105 | }
106 |
107 | static void TerminateApplication()
108 | {
109 | if (mbIsTestRun)
110 | return;
111 |
112 | Application.Exit();
113 | }
114 |
115 | static ApplicationWindow mApplicationWindow;
116 | static Form mActiveDialog;
117 | static bool mbIsTestRun = false;
118 |
119 | static readonly ILoggerRepository mLogRepository =
120 | LogManager.CreateRepository("log4net-rep");
121 |
122 | class GuiFinalizer : GuiTestRunner.IGuiFinalizer
123 | {
124 | void GuiTestRunner.IGuiFinalizer.Finalize(int exitCode)
125 | {
126 | Environment.Exit(exitCode);
127 | }
128 | }
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/src/application/gui/windows/WindowsGuiMessage.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 |
3 | using Codice.Examples.GuiTesting.Lib.Interfaces;
4 |
5 | namespace Codice.Examples.GuiTesting.Windows
6 | {
7 | internal class WindowsGuiMessage : GuiMessage.IGuiMessage
8 | {
9 | void GuiMessage.IGuiMessage.ShowError(string title, string message)
10 | {
11 | Form dialog = new ErrorDialog(title, message);
12 | dialog.StartPosition = FormStartPosition.CenterParent;
13 |
14 | WindowHandler.SetActiveDialogForTesting(dialog);
15 |
16 | try
17 | {
18 | dialog.ShowDialog(WindowHandler.ApplicationWindow);
19 | }
20 | finally
21 | {
22 | WindowHandler.RemoveDialogForTesting(dialog);
23 | dialog.Dispose();
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/application/gui/windows/testing/TestHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 |
3 | namespace Codice.Examples.GuiTesting.Windows.Testing
4 | {
5 | internal class TestHelper
6 | {
7 | internal TestHelper(Control control)
8 | {
9 | mControl = control;
10 | }
11 |
12 | internal string GetText(Control control)
13 | {
14 | string result = string.Empty;
15 | mControl.Invoke((MethodInvoker)delegate
16 | {
17 | result = control.Text;
18 | });
19 |
20 | return result;
21 | }
22 |
23 | internal void SetText(Control control, string text)
24 | {
25 | mControl.Invoke((MethodInvoker)delegate
26 | {
27 | control.Text = text;
28 | });
29 | }
30 |
31 | internal void ClickButton(Button button)
32 | {
33 | mControl.Invoke((MethodInvoker)delegate
34 | {
35 | button.PerformClick();
36 | });
37 | }
38 |
39 | internal void ClickDialogResultButton(Button button)
40 | {
41 | mControl.Invoke((MethodInvoker)delegate
42 | {
43 | button.PerformClick();
44 | });
45 |
46 | while (!mControl.IsDisposed) { }
47 | }
48 |
49 | internal bool IsEnabled(Control control)
50 | {
51 | bool result = false;
52 | mControl.Invoke((MethodInvoker)delegate
53 | {
54 | result = control.Enabled;
55 | });
56 |
57 | return result;
58 | }
59 |
60 | internal int GetItemCount(ListBox listBox)
61 | {
62 | int result = -1;
63 | mControl.Invoke((MethodInvoker)delegate
64 | {
65 | result = listBox.Items.Count;
66 | });
67 |
68 | return result;
69 | }
70 |
71 | internal object GetItemAt(ListBox listBox, int index)
72 | {
73 | object result = null;
74 | mControl.Invoke((MethodInvoker)delegate
75 | {
76 | result = listBox.Items[index];
77 | });
78 |
79 | return result;
80 | }
81 |
82 | readonly Control mControl;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/application/gui/windows/testing/TesteableApplicationWindow.cs:
--------------------------------------------------------------------------------
1 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
2 |
3 | namespace Codice.Examples.GuiTesting.Windows.Testing
4 | {
5 | internal class TesteableApplicationWindow : ITesteableApplicationWindow
6 | {
7 | internal TesteableApplicationWindow(ApplicationWindow window)
8 | {
9 | mWindow = window;
10 | mHelper = new TestHelper(mWindow);
11 | }
12 |
13 | void ITesteableApplicationWindow.ChangeText(string text)
14 | {
15 | mHelper.SetText(mWindow.TextBox, text);
16 | }
17 |
18 | string ITesteableApplicationWindow.GetText()
19 | {
20 | return mHelper.GetText(mWindow.TextBox);
21 | }
22 |
23 | void ITesteableApplicationWindow.ClickAddButton()
24 | {
25 | mHelper.ClickButton(mWindow.AddButton);
26 | }
27 |
28 | void ITesteableApplicationWindow.ClickRemoveButton()
29 | {
30 | mHelper.ClickButton(mWindow.RemoveButton);
31 | }
32 |
33 | bool ITesteableApplicationWindow.AreButtonsEnabled()
34 | {
35 | return mHelper.IsEnabled(mWindow.AddButton)
36 | && mHelper.IsEnabled(mWindow.RemoveButton);
37 | }
38 |
39 | string ITesteableApplicationWindow.GetItemInListAt(int index)
40 | {
41 | return mHelper.GetItemAt(mWindow.ListBox, index).ToString();
42 | }
43 |
44 | int ITesteableApplicationWindow.GetItemsInListCount()
45 | {
46 | return mHelper.GetItemCount(mWindow.ListBox);
47 | }
48 |
49 | string ITesteableApplicationWindow.GetProgressMessage()
50 | {
51 | if (mWindow.ProgressControls.HasError)
52 | return string.Empty;
53 |
54 | return mHelper.GetText(mWindow.ProgressControls.ProgressLabel);
55 | }
56 |
57 | string ITesteableApplicationWindow.GetErrorMessage()
58 | {
59 | if (!mWindow.ProgressControls.HasError)
60 | return string.Empty;
61 |
62 | return mHelper.GetText(mWindow.ProgressControls.ProgressLabel);
63 | }
64 |
65 | ITesteableErrorDialog ITesteableApplicationWindow.GetErrorDialog()
66 | {
67 | if (WindowHandler.GetActiveDialog() == null)
68 | return null;
69 |
70 | ErrorDialog errorDialog = WindowHandler.GetActiveDialog() as ErrorDialog;
71 | if (errorDialog == null)
72 | return null;
73 |
74 | return new TesteableErrorDialog(errorDialog);
75 | }
76 |
77 | readonly ApplicationWindow mWindow;
78 | readonly TestHelper mHelper;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/application/gui/windows/testing/TesteableErrorDialog.cs:
--------------------------------------------------------------------------------
1 | using Codice.Examples.GuiTesting.GuiTestInterfaces;
2 | using Codice.Examples.GuiTesting.Windows.Testing;
3 |
4 | namespace Codice.Examples.GuiTesting.Windows.Testing
5 | {
6 | internal class TesteableErrorDialog : ITesteableErrorDialog
7 | {
8 | internal TesteableErrorDialog(ErrorDialog dialog)
9 | {
10 | mErrorDialog = dialog;
11 | mHelper = new TestHelper(mErrorDialog);
12 | }
13 |
14 | void ITesteableErrorDialog.ClickOkButton()
15 | {
16 | mHelper.ClickDialogResultButton(mErrorDialog.OkButton);
17 | }
18 |
19 | string ITesteableErrorDialog.GetTitle()
20 | {
21 | return mHelper.GetText(mErrorDialog);
22 | }
23 |
24 | string ITesteableErrorDialog.GetMessage()
25 | {
26 | return mHelper.GetText(mErrorDialog.MessageLabel);
27 | }
28 |
29 | readonly ErrorDialog mErrorDialog;
30 | readonly TestHelper mHelper;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/application/gui/windows/threading/WinApplicationTimer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Forms;
3 |
4 | using Codice.Examples.GuiTesting.Lib.Threading;
5 |
6 | namespace Codice.Examples.GuiTesting.Windows.Threading
7 | {
8 | public class WinPlasticTimerBuilder : IApplicationTimerBuilder
9 | {
10 | IApplicationTimer IApplicationTimerBuilder.Get(
11 | bool bModalMode, ThreadWaiter.TimerTick timerTickDelegate)
12 | {
13 | return new WinPlasticTimer(DEFAULT_TIMER_INTERVAL, timerTickDelegate);
14 | }
15 |
16 | const int DEFAULT_TIMER_INTERVAL = 100;
17 | }
18 |
19 | public class WinPlasticTimer : IApplicationTimer
20 | {
21 | public WinPlasticTimer(int timerInterval, ThreadWaiter.TimerTick timerTickDelegate)
22 | {
23 | mTimerInterval = timerInterval;
24 | mTimerTickDelegate = timerTickDelegate;
25 | }
26 |
27 | public void Start()
28 | {
29 | mTimer = new Timer();
30 | mTimer.Interval = mTimerInterval;
31 | mTimer.Tick += OnTimerTick;
32 |
33 | mTimer.Start();
34 | }
35 |
36 | public void Stop()
37 | {
38 | mTimer.Stop();
39 | mTimer.Tick -= OnTimerTick;
40 | mTimer.Dispose();
41 | }
42 |
43 | void OnTimerTick(object sender, EventArgs e)
44 | {
45 | mTimerTickDelegate();
46 | }
47 |
48 | Timer mTimer;
49 |
50 | readonly int mTimerInterval;
51 | readonly ThreadWaiter.TimerTick mTimerTickDelegate;
52 | }
53 | }
--------------------------------------------------------------------------------
/src/application/gui/windows/ui/ControlBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Windows.Forms;
3 |
4 | namespace Codice.Examples.GuiTesting.Windows.UI
5 | {
6 | internal static class ControlBuilder
7 | {
8 | internal const int DefaultControlHeight = 23;
9 |
10 | internal const int DefaultHorizontalPaddingWidth = 6;
11 | internal const int DefaultVerticalPaddingHeight = 8;
12 |
13 | internal static Control CreateVerticalPadding(DockStyle dock)
14 | {
15 | Panel result = CreatePanel(dock);
16 | result.Height = DefaultVerticalPaddingHeight;
17 |
18 | return result;
19 | }
20 |
21 | internal static Control CreateHorizontalPadding(DockStyle dock)
22 | {
23 | Panel result = CreatePanel(dock);
24 | result.Width = DefaultHorizontalPaddingWidth;
25 |
26 | return result;
27 | }
28 |
29 | internal static Panel CreatePanel(int height, DockStyle dock)
30 | {
31 | Panel result = CreatePanel(dock);
32 | result.Height = height;
33 |
34 | return result;
35 | }
36 |
37 | internal static Panel CreatePanel(DockStyle dock)
38 | {
39 | Panel result = new Panel();
40 | result.Dock = dock;
41 |
42 | return result;
43 | }
44 |
45 | internal static Label CreateLabel(string text, DockStyle dock)
46 | {
47 | Label result = new Label();
48 | result.Text = text;
49 | result.Dock = dock;
50 | result.AutoSize = true;
51 |
52 | return result;
53 | }
54 |
55 | internal static TextBox CreateTextbox(DockStyle dock)
56 | {
57 | TextBox result = new TextBox();
58 | result.Dock = dock;
59 |
60 | return result;
61 | }
62 |
63 | internal static Button CreateButton(string text, DockStyle dock)
64 | {
65 | Button result = new Button();
66 | result.Text = text;
67 | result.Dock = dock;
68 |
69 | return result;
70 | }
71 |
72 | internal static ListBox CreateListBox(DockStyle dock)
73 | {
74 | ListBox result = new ListBox();
75 | result.Dock = dock;
76 |
77 | return result;
78 | }
79 |
80 | internal static PictureBox CreatePictureBox(Image image, DockStyle dock)
81 | {
82 | PictureBox result = new PictureBox();
83 | result.Image = image;
84 | result.Width = image.Width;
85 | result.Height = image.Height;
86 | result.Dock = dock;
87 |
88 | return result;
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/application/gui/windows/ui/ControlPacker.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 |
3 | namespace Codice.Examples.GuiTesting.Windows.UI
4 | {
5 | internal static class ControlPacker
6 | {
7 | internal static void AddControl(Control parent, Control child)
8 | {
9 | parent.Controls.Add(child);
10 | if (child.Dock == DockStyle.Left || child.Dock == DockStyle.Top ||
11 | child.Dock == DockStyle.Fill || child.Dock == DockStyle.None)
12 | {
13 | child.BringToFront();
14 | }
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/application/gui/windows/ui/ProgressControls.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Windows.Forms;
3 |
4 | using Codice.Examples.GuiTesting.Lib.Interfaces;
5 |
6 | namespace Codice.Examples.GuiTesting.Windows.UI
7 | {
8 | internal class ProgressControls : IProgressControls
9 | {
10 | public bool HasError { get { return mbHasError; } }
11 | public Label ProgressLabel { get { return mProgressLabel; } }
12 |
13 | internal ProgressControls(Label progressLabel, Control[] controls)
14 | {
15 | mProgressLabel = progressLabel;
16 | mControls = controls;
17 | }
18 |
19 | void IProgressControls.ShowProgress(string message)
20 | {
21 | mbHasError = false;
22 |
23 | mProgressLabel.ForeColor = Color.Black;
24 | mProgressLabel.Text = message;
25 | mProgressLabel.Show();
26 |
27 | mFocusedControl = GetFocusedControl(mControls);
28 |
29 | DisableControls(mControls);
30 | }
31 |
32 | void IProgressControls.HideProgress()
33 | {
34 | mProgressLabel.Hide();
35 |
36 | EnableControls(mControls);
37 |
38 | if (mFocusedControl != null)
39 | mFocusedControl.Focus();
40 | }
41 |
42 | void IProgressControls.ShowError(string message)
43 | {
44 | mbHasError = true;
45 |
46 | mProgressLabel.ForeColor = Color.Red;
47 | mProgressLabel.Text = message;
48 | mProgressLabel.Show();
49 | }
50 |
51 | static void EnableControls(Control[] controls)
52 | {
53 | foreach (Control control in controls)
54 | control.Enabled = true;
55 | }
56 |
57 | static void DisableControls(Control[] controls)
58 | {
59 | foreach (Control control in controls)
60 | control.Enabled = false;
61 | }
62 |
63 | static Control GetFocusedControl(Control[] controls)
64 | {
65 | foreach (Control control in controls)
66 | {
67 | if (control.Focused)
68 | return control;
69 | }
70 |
71 | return null;
72 | }
73 |
74 | Control mFocusedControl;
75 | bool mbHasError;
76 |
77 | readonly Label mProgressLabel;
78 | readonly Control[] mControls;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/application/gui/windows/windows.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28010.2026
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "windows", "windows.csproj", "{20C1F257-2ADF-4E38-AE86-F167E284AF99}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "lib", "..\..\lib\lib.csproj", "{A1079FA8-882B-40D6-A289-3A13767CABDD}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testing", "testing", "{2EBF8C53-4C4F-464D-9D79-45FACDA7DC87}"
11 | EndProject
12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "guitestinterfaces", "..\..\..\testing\guitestinterfaces\guitestinterfaces.csproj", "{D775E82D-4045-4E11-AE85-4402CA0AD054}"
13 | EndProject
14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "pnunit.framework", "..\..\..\..\lib\pnunit\pnunit.framework\pnunit.framework.csproj", "{5261ABA1-98E6-4603-A4F0-59CAC307AC68}"
15 | EndProject
16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "guitest", "..\..\..\testing\guitest\guitest.csproj", "{9EE461F0-5FCA-4631-8335-73E1A0AF2861}"
17 | EndProject
18 | Global
19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
20 | Debug|Any CPU = Debug|Any CPU
21 | NAnt|Any CPU = NAnt|Any CPU
22 | Release|Any CPU = Release|Any CPU
23 | EndGlobalSection
24 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
25 | {20C1F257-2ADF-4E38-AE86-F167E284AF99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
26 | {20C1F257-2ADF-4E38-AE86-F167E284AF99}.Debug|Any CPU.Build.0 = Debug|Any CPU
27 | {20C1F257-2ADF-4E38-AE86-F167E284AF99}.NAnt|Any CPU.ActiveCfg = Release|Any CPU
28 | {20C1F257-2ADF-4E38-AE86-F167E284AF99}.NAnt|Any CPU.Build.0 = Release|Any CPU
29 | {20C1F257-2ADF-4E38-AE86-F167E284AF99}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {20C1F257-2ADF-4E38-AE86-F167E284AF99}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.NAnt|Any CPU.ActiveCfg = Release|Any CPU
34 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.NAnt|Any CPU.Build.0 = Release|Any CPU
35 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Release|Any CPU.ActiveCfg = Release|Any CPU
36 | {A1079FA8-882B-40D6-A289-3A13767CABDD}.Release|Any CPU.Build.0 = Release|Any CPU
37 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
38 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Debug|Any CPU.Build.0 = Debug|Any CPU
39 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.NAnt|Any CPU.ActiveCfg = Release|Any CPU
40 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.NAnt|Any CPU.Build.0 = Release|Any CPU
41 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Release|Any CPU.ActiveCfg = Release|Any CPU
42 | {D775E82D-4045-4E11-AE85-4402CA0AD054}.Release|Any CPU.Build.0 = Release|Any CPU
43 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
44 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Debug|Any CPU.Build.0 = Debug|Any CPU
45 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.NAnt|Any CPU.ActiveCfg = NAnt|Any CPU
46 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.NAnt|Any CPU.Build.0 = NAnt|Any CPU
47 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Release|Any CPU.ActiveCfg = Release|Any CPU
48 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68}.Release|Any CPU.Build.0 = Release|Any CPU
49 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
50 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Debug|Any CPU.Build.0 = Debug|Any CPU
51 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.NAnt|Any CPU.ActiveCfg = Release|Any CPU
52 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.NAnt|Any CPU.Build.0 = Release|Any CPU
53 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Release|Any CPU.ActiveCfg = Release|Any CPU
54 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}.Release|Any CPU.Build.0 = Release|Any CPU
55 | EndGlobalSection
56 | GlobalSection(SolutionProperties) = preSolution
57 | HideSolutionNode = FALSE
58 | EndGlobalSection
59 | GlobalSection(NestedProjects) = preSolution
60 | {D775E82D-4045-4E11-AE85-4402CA0AD054} = {2EBF8C53-4C4F-464D-9D79-45FACDA7DC87}
61 | {5261ABA1-98E6-4603-A4F0-59CAC307AC68} = {2EBF8C53-4C4F-464D-9D79-45FACDA7DC87}
62 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861} = {2EBF8C53-4C4F-464D-9D79-45FACDA7DC87}
63 | EndGlobalSection
64 | GlobalSection(ExtensibilityGlobals) = postSolution
65 | SolutionGuid = {82C11AC5-A331-451E-9EE5-81E58F2E8E93}
66 | EndGlobalSection
67 | EndGlobal
68 |
--------------------------------------------------------------------------------
/src/application/lib/ApplicationArgs.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace Codice.Examples.GuiTesting.Lib
4 | {
5 | public class ApplicationArgs
6 | {
7 | public readonly bool IsTestingMode;
8 | public readonly string TestInfoFile;
9 | public readonly string PathToAssemblies;
10 |
11 | ApplicationArgs(
12 | bool isTestingMode,
13 | string testInfoFile,
14 | string pathToAssemblies)
15 | {
16 | IsTestingMode = isTestingMode;
17 | TestInfoFile = testInfoFile;
18 | PathToAssemblies = pathToAssemblies;
19 | }
20 |
21 | public static ApplicationArgs Parse(string[] args)
22 | {
23 | if (args.Length < 3
24 | || args[0] != TESTING_FLAG
25 | || !File.Exists(args[1])
26 | || !Directory.Exists(args[2]))
27 | {
28 | return new ApplicationArgs(false, string.Empty, string.Empty);
29 | }
30 |
31 | return new ApplicationArgs(true, args[1], args[2]);
32 | }
33 |
34 | const string TESTING_FLAG = "--testing";
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/application/lib/IGuiMessage.cs:
--------------------------------------------------------------------------------
1 | namespace Codice.Examples.GuiTesting.Lib.Interfaces
2 | {
3 | public class GuiMessage
4 | {
5 | public interface IGuiMessage
6 | {
7 | void ShowError(string title, string message);
8 | }
9 |
10 | public static void Initialize(IGuiMessage guiMessage)
11 | {
12 | mGuiMessage = guiMessage;
13 | }
14 |
15 | public static void ShowError(string title, string message)
16 | {
17 | mGuiMessage.ShowError(title, message);
18 | }
19 |
20 | static IGuiMessage mGuiMessage;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/application/lib/Localization.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Codice.Examples.GuiTesting.Lib
4 | {
5 | public class Localization
6 | {
7 | public enum Name
8 | {
9 | ApplicationName,
10 | Ok,
11 | AddButton,
12 | RemoveButton,
13 | TextInputLabel,
14 | AddingElementProgressText,
15 | RemovingElementProgressText,
16 | ElementCantBeEmptyErrorMessage,
17 | ErrorTitle,
18 | ElementNotInTheListErrorMessage,
19 | ElementInTheListErrorMessage
20 | }
21 |
22 | Localization()
23 | {
24 | mTexts = new Dictionary();
25 | mTexts.Add(Name.ApplicationName, "GUI Testing example");
26 | mTexts.Add(Name.Ok, "OK");
27 | mTexts.Add(Name.AddButton, "Add");
28 | mTexts.Add(Name.RemoveButton, "Remove");
29 | mTexts.Add(Name.TextInputLabel, "Text: ");
30 | mTexts.Add(Name.AddingElementProgressText, "Adding element {0}...");
31 | mTexts.Add(Name.RemovingElementProgressText, "Removing element {0}...");
32 | mTexts.Add(Name.ElementCantBeEmptyErrorMessage, "The element can't be empty!");
33 | mTexts.Add(Name.ErrorTitle, "Error");
34 | mTexts.Add(Name.ElementNotInTheListErrorMessage, "The element {0} is not in the list, and thus it can't be removed!");
35 | mTexts.Add(Name.ElementInTheListErrorMessage, "The element {0} is already in the list, and thus it can't be added!");
36 | }
37 |
38 | public static string GetText(Name name)
39 | {
40 | return GetInstance().TryGetString(name);
41 | }
42 |
43 | public static string GetText(Name name, params object[] args)
44 | {
45 | string result = GetInstance().TryGetString(name);
46 |
47 | return (result == UNLOCALIZED)
48 | ? UNLOCALIZED
49 | : string.Format(result, args);
50 | }
51 |
52 | static Localization GetInstance()
53 | {
54 | if (mInstance == null)
55 | mInstance = new Localization();
56 |
57 | return mInstance;
58 | }
59 |
60 | string TryGetString(Name name)
61 | {
62 | if (!mTexts.ContainsKey(name))
63 | return "UNLOCALIZED";
64 |
65 | return mTexts[name];
66 | }
67 |
68 | static Localization mInstance;
69 |
70 | readonly Dictionary mTexts;
71 |
72 | const string UNLOCALIZED = "UNLOCALIZED";
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/application/lib/interfaces/IApplicationWindow.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Codice.Examples.GuiTesting.Lib.Interfaces
4 | {
5 | public interface IApplicationWindow
6 | {
7 | void UpdateItems(List items);
8 | void ClearInput();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/application/lib/interfaces/IProgressControls.cs:
--------------------------------------------------------------------------------
1 | namespace Codice.Examples.GuiTesting.Lib.Interfaces
2 | {
3 | public interface IProgressControls
4 | {
5 | bool HasError { get; }
6 |
7 | void ShowProgress(string message);
8 | void HideProgress();
9 |
10 | void ShowError(string message);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/application/lib/lib.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {A1079FA8-882B-40D6-A289-3A13767CABDD}
8 | Library
9 | Properties
10 | Codice.Examples.GuiTesting.Lib
11 | lib
12 | v4.5
13 | 512
14 | true
15 |
16 |
17 | true
18 | full
19 | false
20 | ..\..\..\bin\application\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/src/application/lib/threading/ApplicationThread.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 |
4 | namespace Codice.Examples.GuiTesting.Lib.Threading
5 | {
6 | public class ApplicationThread
7 | {
8 | public bool IsRunning { get { lock (mLock) { return mbIsRunning; } } }
9 | public Exception Exception { get { lock (mLock) { return mException; } } }
10 |
11 | public delegate void Operation();
12 |
13 | public ApplicationThread(Operation performOperationDelegate)
14 | {
15 | SetRunning(true);
16 | mPerformOperationDelegate = performOperationDelegate;
17 | }
18 |
19 | public void Execute()
20 | {
21 | ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadWork));
22 | }
23 |
24 | void ThreadWork(object state)
25 | {
26 | SetException(null);
27 |
28 | try
29 | {
30 | mPerformOperationDelegate();
31 | }
32 | catch (Exception ex)
33 | {
34 | SetException(
35 | ex.InnerException == null
36 | ? ex
37 | : ex.InnerException);
38 | }
39 | finally
40 | {
41 | SetRunning(false);
42 | }
43 | }
44 |
45 | void SetRunning(bool bIsRunning)
46 | {
47 | lock (mLock)
48 | {
49 | mbIsRunning = bIsRunning;
50 | }
51 | }
52 |
53 | void SetException(Exception exception)
54 | {
55 | lock (mLock)
56 | {
57 | mException = exception;
58 | }
59 | }
60 |
61 | Operation mPerformOperationDelegate;
62 |
63 | bool mbIsRunning;
64 | Exception mException;
65 | object mLock = new object();
66 | }
67 | }
--------------------------------------------------------------------------------
/src/application/lib/threading/ApplicationThreadWaiter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Codice.Examples.GuiTesting.Lib.Threading
4 | {
5 | public interface IApplicationTimerBuilder
6 | {
7 | IApplicationTimer Get(
8 | bool bModalMode,
9 | ThreadWaiter.TimerTick timerTickDelegate);
10 | }
11 |
12 | public interface IApplicationTimer
13 | {
14 | void Start();
15 | void Stop();
16 | }
17 |
18 | public interface IThreadWaiterBuilder
19 | {
20 | IThreadWaiter GetWaiter();
21 | IThreadWaiter GetModalWaiter();
22 | }
23 |
24 | public interface IThreadWaiter
25 | {
26 | Exception Exception { get; }
27 |
28 | void Execute(
29 | ApplicationThread.Operation threadOperationDelegate,
30 | ApplicationThread.Operation afterOperationDelegate);
31 |
32 | void Cancel();
33 | }
34 |
35 | public static class ThreadWaiter
36 | {
37 | public delegate void TimerTick();
38 |
39 | public static void Initialize(IThreadWaiterBuilder threadWaiterBuilder)
40 | {
41 | mThreadWaiterBuilder = threadWaiterBuilder;
42 | }
43 |
44 | public static IThreadWaiter GetWaiter()
45 | {
46 | return mThreadWaiterBuilder.GetWaiter();
47 | }
48 |
49 | public static IThreadWaiter GetModalWaiter()
50 | {
51 | return mThreadWaiterBuilder.GetModalWaiter();
52 | }
53 |
54 | public static void Reset()
55 | {
56 | mThreadWaiterBuilder = new ThreadWaiterBuilder();
57 | }
58 |
59 | static IThreadWaiterBuilder mThreadWaiterBuilder = new ThreadWaiterBuilder();
60 | }
61 |
62 | public class ThreadWaiterBuilder : IThreadWaiterBuilder
63 | {
64 | public static void Initialize(IApplicationTimerBuilder timerBuilder)
65 | {
66 | mPlasticTimerBuilder = timerBuilder;
67 | }
68 |
69 | IThreadWaiter IThreadWaiterBuilder.GetWaiter()
70 | {
71 | return new PlasticThreadWaiter(mPlasticTimerBuilder, false);
72 | }
73 |
74 | IThreadWaiter IThreadWaiterBuilder.GetModalWaiter()
75 | {
76 | return new PlasticThreadWaiter(mPlasticTimerBuilder, true);
77 | }
78 |
79 | static IApplicationTimerBuilder mPlasticTimerBuilder;
80 | }
81 |
82 | public class PlasticThreadWaiter : IThreadWaiter
83 | {
84 | public Exception Exception { get { return mThreadOperation.Exception; } }
85 |
86 | internal PlasticThreadWaiter(
87 | IApplicationTimerBuilder timerBuilder, bool bModalMode)
88 | {
89 | mPlasticTimer = timerBuilder.Get(bModalMode, OnTimerTick);
90 | }
91 |
92 | public void Execute(
93 | ApplicationThread.Operation threadOperationDelegate,
94 | ApplicationThread.Operation afterOperationDelegate)
95 | {
96 | mThreadOperation = new ApplicationThread(threadOperationDelegate);
97 | mAfterOperationDelegate = afterOperationDelegate;
98 |
99 | mPlasticTimer.Start();
100 |
101 | mThreadOperation.Execute();
102 | }
103 |
104 | public void Cancel()
105 | {
106 | mbCancelled = true;
107 | }
108 |
109 | void OnTimerTick()
110 | {
111 | if (mThreadOperation.IsRunning)
112 | return;
113 |
114 | mPlasticTimer.Stop();
115 |
116 | if (mbCancelled)
117 | return;
118 |
119 | mAfterOperationDelegate();
120 | }
121 |
122 | bool mbCancelled = false;
123 |
124 | IApplicationTimer mPlasticTimer;
125 | ApplicationThread mThreadOperation;
126 | ApplicationThread.Operation mAfterOperationDelegate;
127 | }
128 | }
--------------------------------------------------------------------------------
/src/testing/guitest/PlatformUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace GuiTest
5 | {
6 | public static class PlatformUtils
7 | {
8 | public enum Platform
9 | {
10 | Unknown,
11 | Windows,
12 | MacOS,
13 | Linux
14 | }
15 |
16 | public static Platform CurrentPlatform
17 | {
18 | get
19 | {
20 | if (mCurrentPlatform != Platform.Unknown)
21 | return mCurrentPlatform;
22 |
23 | mCurrentPlatform = GetCurrentPlatform();
24 | return mCurrentPlatform;
25 | }
26 | }
27 |
28 | static Platform GetCurrentPlatform()
29 | {
30 | switch (Environment.OSVersion.Platform)
31 | {
32 | case PlatformID.MacOSX:
33 | return Platform.MacOS;
34 |
35 | case PlatformID.Unix:
36 | return AreMacOSDirectoriesPresent()
37 | ? Platform.MacOS
38 | : Platform.Linux;
39 |
40 | default:
41 | return Platform.Windows;
42 | }
43 | }
44 |
45 | static bool AreMacOSDirectoriesPresent()
46 | {
47 | return Directory.Exists("/Applications")
48 | && Directory.Exists("/System")
49 | && Directory.Exists("/Users")
50 | && Directory.Exists("/Volumes");
51 | }
52 |
53 | static Platform mCurrentPlatform = Platform.Unknown;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/testing/guitest/guitest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {9EE461F0-5FCA-4631-8335-73E1A0AF2861}
8 | Library
9 | Properties
10 | guitest
11 | guitest
12 | v4.5.1
13 | 512
14 | true
15 |
16 |
17 | true
18 | full
19 | false
20 | ..\..\..\bin\pnunit\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 | ..\..\..\lib\log4net\log4net.dll
36 |
37 |
38 | False
39 | ..\..\..\lib\mono\Mono.Posix.dll
40 |
41 |
42 | ..\..\..\lib\nunit\nunit.core.dll
43 |
44 |
45 | ..\..\..\lib\nunit\nunit.core.interfaces.dll
46 |
47 |
48 | ..\..\..\lib\nunit\nunit.framework.dll
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | {5261aba1-98e6-4603-a4f0-59cac307ac68}
64 | pnunit.framework
65 |
66 |
67 | {d775e82d-4045-4e11-ae85-4402ca0ad054}
68 | guitestinterfaces
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/src/testing/guitestinterfaces/GuiTesteableServices.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Codice.Examples.GuiTesting.GuiTestInterfaces
4 | {
5 | public class GuiTesteableServices
6 | {
7 | public static Exception UnhandledException
8 | {
9 | get { lock (mInstance) return mInstance.mUnhandledException; }
10 | set { lock (mInstance) mInstance.mUnhandledException = value; }
11 | }
12 |
13 | public static void Init(ITesteableApplicationWindow window)
14 | {
15 | if (mInstance == null)
16 | mInstance = new GuiTesteableServices();
17 |
18 | mInstance.mTesteableApplicationWindow = window;
19 | }
20 |
21 | public static ITesteableApplicationWindow GetApplicationWindow()
22 | {
23 | return mInstance.mTesteableApplicationWindow;
24 | }
25 |
26 | Exception mUnhandledException;
27 | static GuiTesteableServices mInstance;
28 |
29 | ITesteableApplicationWindow mTesteableApplicationWindow;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/testing/guitestinterfaces/ITesteableApplicationWindow.cs:
--------------------------------------------------------------------------------
1 | namespace Codice.Examples.GuiTesting.GuiTestInterfaces
2 | {
3 | public interface ITesteableApplicationWindow
4 | {
5 | void ClickAddButton();
6 | void ClickRemoveButton();
7 |
8 | bool AreButtonsEnabled();
9 |
10 | void ChangeText(string text);
11 | string GetText();
12 |
13 | int GetItemsInListCount();
14 | string GetItemInListAt(int index);
15 |
16 | string GetProgressMessage();
17 | string GetErrorMessage();
18 |
19 | ITesteableErrorDialog GetErrorDialog();
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/testing/guitestinterfaces/ITesteableErrorDialog.cs:
--------------------------------------------------------------------------------
1 | namespace Codice.Examples.GuiTesting.GuiTestInterfaces
2 | {
3 | public interface ITesteableErrorDialog
4 | {
5 | void ClickOkButton();
6 |
7 | string GetTitle();
8 | string GetMessage();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/testing/guitestinterfaces/guitestinterfaces.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {D775E82D-4045-4E11-AE85-4402CA0AD054}
8 | Library
9 | Properties
10 | Codice.Examples.GuiTesting.GuiTestInterfaces
11 | guitestinterfaces
12 | v4.5
13 | 512
14 | true
15 |
16 |
17 | true
18 | full
19 | false
20 | ..\..\..\bin\pnunit\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------