public static void WriteCommand(ChromeCommand message)
        {
            StringBuilder cmd = new StringBuilder();
            cmd.Append(string.Format("({0}) Command: {1} - Arguments: [", DateTime.Now.ToString(), message.Command));

            foreach (string arg in message.Arguments.Keys)
            {
                cmd.Append(string.Format("({0} : {1}) ", arg, message.Arguments[arg]));    
            }

            cmd.Append("]");

#if DEBUG
            //Console.WriteLine(cmd);
#endif

            Debug.WriteLine(cmd);
        }
        public string GetCurrentLocation()
        {
            WaitForBrowser();

            ChromeCommand command = new ChromeCommand("GetLocation");
            chromeHttpServer.SendMessage(command);
            ChromeResponse response = chromeHttpServer.HandleResponse(command);

            if (response.StatusCode == StatusCode.UNDEFINEDURL)
                throw new ChromeException("The current document has an undefined URL.");

            return response.Value.ToString();

        }
        public void NavigateBrowser(string url)
        {
            WaitForBrowser();

            ChromeCommand command = new ChromeCommand("NavigateBrowser");
            command.Arguments.Add("url", Utilities.FormatUrl(url));
            chromeHttpServer.SendMessage(command);
            ChromeResponse response = chromeHttpServer.HandleResponse(command);

            switch (response.StatusCode)
            {
                case StatusCode.NAVIGATEFAIL:
                    throw new NavigationTimeoutException(response.Value.ToString());
            }
        }
 public ChromeResponse HandleResponse(ChromeCommand command)
 {
     return HandleResponse(command, true);
 }
 public void OpenBrowser()
 {
     ConnectToChrome();
     WaitForBrowser();
     ChromeCommand command = new ChromeCommand("OpenBrowser");
     chromeHttpServer.SendMessage(command);
     chromeHttpServer.HandleResponse(command);
     curWindowHandle = GetChromeWindowHandle("about:swat - Google Chrome");
 }
        public string GetElementAttribute(IdentifierType identType, string identifier, string tagName, AttributeType attributeType, string attributeName, int timeout)
        {
            WaitForBrowser();

            ChromeCommand command = new ChromeCommand("GetElementAttribute");
            command.Arguments.Add("identifierType", identType.ToString());
            command.Arguments.Add("identifier", identifier);
            command.Arguments.Add("attributeName", attributeName);
            command.Arguments.Add("tagName", tagName);
            ChromeResponse response = chromeHttpServer.SendMessageWithTimeout(command, timeout);

            switch (response.StatusCode)
            {
                case StatusCode.ELEMENTDOESNOTEXIST:
                    if (WantInformativeExceptions.GetInformativeExceptions)
                        throw new ElementNotFoundException(identifier, identType, tagName);
                    throw new ElementNotFoundException(identifier, identType);

                case StatusCode.ATTRIBUTEERROR:
                    throw new AttributeErrorException(string.Format("The attribute name '{0}' was not found.", attributeName));

                case StatusCode.PORTDISCONNECTED:
                    throw new ChromeContentScriptIsNotConnectedException();
            }

            return response.Value.ToString();
        }
        public void PressKeys(IdentifierType identType, string identifier, string word, string tagName)
        {
            WaitForBrowser();

            string keyCodes = "";

            char[] characters = word.ToCharArray();
            for (int charIndex = 0; charIndex < characters.Length; charIndex++)
                keyCodes += ((int)characters[charIndex]) + "-";

            if (keyCodes.Length > 0)
            {
                ChromeCommand command = new ChromeCommand("PressKeys");
                command.Arguments.Add("keyCodes", keyCodes);
                command.Arguments.Add("identifierType", identType.ToString());
                command.Arguments.Add("identifier", identifier);
                command.Arguments.Add("tagName", tagName);
                command.Arguments.Add("attributeName", "value");
                command.Arguments.Add("attributeValue", word);

                chromeHttpServer.SendMessage(command);
                ChromeResponse response = chromeHttpServer.HandleResponse(command);

                switch (response.StatusCode)
                {
                    case StatusCode.SUCCESS:
                        break;
                    case StatusCode.ELEMENTDOESNOTEXIST:
                        if (WantInformativeExceptions.GetInformativeExceptions)
                            throw new ElementNotFoundException(identifier, identType, tagName);
                        else
                            throw new ElementNotFoundException(identifier, identType);
                }
            }

            //If we do enter or space it's the same as firing an onclick event on that element so give it time to load or do its action
            if (word.Contains("ENTER") || word.Contains("SPACE"))
            {
                Thread.Sleep(200);
                if (FindDialog(DateTime.Now.AddMilliseconds(100)) == IntPtr.Zero)
                    HandleSWATTabs();
            }
        }
        public void AttachBrowserToWindow(string windowTitle, int windowIndex, int timeout)
        {
            WaitForBrowser();
            LookForBrowser(windowTitle, windowIndex, Convert.ToDouble(timeout), true);

            // suffix is added to the window title for windows
            string suffix = " - Google Chrome";

            ChromeCommand command = new ChromeCommand("AttachToWindow");
            command.Arguments.Add("windowTitle", windowTitle);
            command.Arguments.Add("windowIndex", windowIndex);

            chromeHttpServer.SendMessage(command);
            ChromeResponse response = chromeHttpServer.HandleResponse(command);

            switch (response.StatusCode)
            {
                case StatusCode.SUCCESS:
                    curWindowHandle = GetChromeWindowHandle(response.Value + suffix);
                    break;

                case StatusCode.NOSUCHWINDOW:
                    throw new WindowNotFoundException(response.Value.ToString());

                case StatusCode.WINDOWINDEXOUTOFBOUNDS:
                    string indexLimit = response.Value.ToString();
                    string message;
                    if (indexLimit.Equals("1"))
                        message = "There is only one window";
                    else
                        message = "There are only " + indexLimit + " windows";

                    throw new IndexOutOfRangeException(message + " that has " + windowTitle + " in the title.");

                case StatusCode.PORTDISCONNECTED:
                    throw new ChromeContentScriptIsNotConnectedException();
            }

        }
        protected override string runJavaScript(string theScript)
        {
            WaitForBrowser();

            ChromeCommand command = new ChromeCommand("RunJavaScript");

            theScript = theScript.Replace("\"", "&quot;");

            command.Arguments.Add("theScript", theScript);

            chromeHttpServer.SendMessage(command);
            ChromeResponse response = chromeHttpServer.HandleResponse(command);

            if (response.Value.ToString() == "undefined")
                response.Value = "";

            return response.Value.ToString();
        }
 private ChromeResponse IsBrowserAttached()
 {
     ChromeCommand command = new ChromeCommand("AssertBrowserIsAttached");
     chromeHttpServer.SendMessage(command);
     return chromeHttpServer.HandleResponse(command);
 }
        public void SendMessage(ChromeCommand command, bool printConsoleMessages)
        {
            if (printConsoleMessages)
            {
                Utilities.WriteCommand(command);
            }

            if (!ConnectToExtension())
            {
                throw new ChromeExtensionNotConnectedException();
            }

            // ExtensionRequestPacket packet = pendingRequestQueue.Dequeue();
            ExtensionRequestPacket packet = pendingRequestQueue[0];

            pendingRequestQueue.RemoveAt(0);

            // Send the response to the Chrome extension.
            string commandString = command.ToString();
            //Utilities.WriteToConsole(string.Format("Executing {0} ", commandString));
            browser.PreviousRequest = command.Command;

            Send(packet, commandString, "application/json; charset=UTF-8");
        }
 public void SendMessage(ChromeCommand command)
 {
     SendMessage(command, true);
 }
        public ChromeResponse HandleResponse(ChromeCommand command, bool printConsoleMessages)
        {
            // Wait for a POST request to be pending from the Chrome extension.
            // Note that we need to leave the packet in the queue for the next
            // send message.

            DateTime timeout = DateTime.Now.AddSeconds(PacketTimeoutSeconds);
            browser.DialogInterrupted = false;

            using (DialogWatcher watcher = new DialogWatcher(browser))
            {
                while (DateTime.Now < timeout)
                {
                    lock (responseLock)
                    {
                        if (watcher.FoundDialog)
                        {
                            browser.DialogInterrupted = true;
                            break;
                        }

                        if (receivedResponse)
                            break;
                    }
                }
            }

            ChromeResponse response = new ChromeResponse();

            if (browser.DialogInterrupted)
            {
                response.StatusCode = StatusCode.SUCCESS;
                response.Value = "A JSDialog caused a timeout.";
                return response;
            }

            if (!receivedResponse)
            {
                throw new ChromeCommandTimedOutException(command.Command, PacketTimeoutSeconds);
            }

            // ExtensionRequestPacket packet = pendingRequestQueue.Peek();
            // If the page cannot be found, this gets index out of bounds
            ExtensionRequestPacket packet = pendingRequestQueue[0];

            // Parse the packet content, and deserialize from a JSON object.
            string responseString = ParseResponse(packet.Content);

            if (!string.IsNullOrEmpty(responseString))
            {
                response = JsonConvert.DeserializeObject<ChromeResponse>(responseString);

                if (response == null)
                    throw new ChromeException("No response was returned by the extension.");

                response.Value = response.Value ?? "";
            }

            string valueAsString = response.Value as string;
            if (valueAsString != null)
            {
                // First, collapse all \r\n pairs to \n, then replace all \n with
                // System.Environment.NewLine. This ensures the consistency of 
                // the values.
                response.Value = valueAsString.Replace("\r\n", "\n").Replace("\n", System.Environment.NewLine);
            }
            //Utilities.WriteToConsole(string.Format("Response was {0}", response.ToString()));

            if (printConsoleMessages)
            {
                Utilities.WriteResponse(response);
            }

            switch (response.StatusCode)
            {
                case StatusCode.BADCOMMAND:
                case StatusCode.BADJAVASCRIPT:
                case StatusCode.CONTENTSCRIPTCONNECTFAIL:
                case StatusCode.CONTENTSCRIPTERROR:
                case StatusCode.ELEMENTNOTVISIBLE:
                case StatusCode.INVALIDELEMENTSTATE:
                case StatusCode.NOSUCHFRAME:
                case StatusCode.STALEELEMENTREFERENCE:
                case StatusCode.UNHANDLEDERROR:
                    throw new ChromeException(response.Value.ToString());
            }

            return response;
        }
        public string GetCurrentDocumentTitle()
        {
            WaitForBrowser();

            ChromeCommand command = new ChromeCommand("GetWindowTitle");
            chromeHttpServer.SendMessage(command);
            ChromeResponse response = chromeHttpServer.HandleResponse(command);

            switch (response.StatusCode)
            {
                case StatusCode.UNDEFINEDTITLE:
                    throw new ChromeException("The current document has an undefined title.");
            }
            return response.Value.ToString();
        }
        public void CloseBrowser()
        {
            WaitForBrowser();

            ChromeCommand command = new ChromeCommand("CloseBrowser");
            chromeHttpServer.SendMessage(command);
            chromeHttpServer.HandleResponse(command);

            WaitForTabToClose();
            
            if (FindDialog(DateTime.Now.AddMilliseconds(100)) == IntPtr.Zero)
                HandleSWATTabs();
        }
        private ChromeResponse LookForBrowser(string windowTitle, int windowIndex, double timeout, bool expectPositiveResponse)
        {
            ConnectToChrome();

            ChromeCommand command = new ChromeCommand("FindBrowser");
            command.Arguments.Add("windowTitle", windowTitle);
            command.Arguments.Add("windowIndex", windowIndex);
            command.Arguments.Add("expectPositiveResult", expectPositiveResponse);

            return chromeHttpServer.SendMessageWithTimeout(command, System.Convert.ToInt32(timeout));
        }
        public void AssertElementIsActive(IdentifierType identType, string identifier, string tagName, int timeoutSeconds)
        {
            WaitForBrowser();

            ChromeCommand command = new ChromeCommand("AssertElementIsActive");
            command.Arguments.Add("identifierType", identType.ToString());
            command.Arguments.Add("identifier", identifier);
            command.Arguments.Add("tagName", tagName);
            ChromeResponse response = chromeHttpServer.SendMessageWithTimeout(command, timeoutSeconds);

            if (response.StatusCode == StatusCode.ELEMENTDOESNOTEXIST)
            {
                if (WantInformativeExceptions.GetInformativeExceptions)
                    throw new ElementNotFoundException(identifier, identType, tagName);

                throw new ElementNotFoundException(identifier, identType);
            }

            if (response.StatusCode == StatusCode.ELEMENTNOTACTIVE)
            {
                if (WantInformativeExceptions.GetInformativeExceptions)
                    throw new ElementNotActiveException(identifier, identType, tagName);

                throw new ElementNotActiveException(identifier, identType);
            }

            if (response.StatusCode == StatusCode.PORTDISCONNECTED)
                throw new ChromeContentScriptIsNotConnectedException();
        }
        public void AssertTopWindow(string browserTitle, int index, int timeout)
        {
            ChromeCommand command = new ChromeCommand("AssertTopWindow");
            command.Arguments.Add("title", browserTitle.ToLower());
            command.Arguments.Add("index", index);

            ChromeResponse response = chromeHttpServer.SendMessageWithTimeout(command, timeout);

            IntPtr topWindwHnd = NativeMethods.GetForegroundWindow();
            string actualTitle = NativeMethods.GetWindowText(topWindwHnd);
            string title = actualTitle.ToLower();

            if (response.StatusCode != StatusCode.SUCCESS || !title.Contains(browserTitle.ToLower()) || !title.Contains("google chrome"))
            {
                if (index == 0)
                {
                    if (WantInformativeExceptions.GetInformativeExceptions)
                        throw new TopWindowMismatchException(browserTitle, actualTitle);
                    else
                        throw new TopWindowMismatchException(browserTitle);
                }
                else
                {
                    if (response.StatusCode == StatusCode.WINDOWINDEXOUTOFBOUNDS)
                        throw new IndexOutOfRangeException("Index: " + index + " is too large, there are only " + response.Value + " window(s) with title " + browserTitle);
                    else if (WantInformativeExceptions.GetInformativeExceptions)
                        throw new TopWindowMismatchException(browserTitle, index, actualTitle);
                    else
                        throw new TopWindowMismatchException(browserTitle, index);
                }
            }
        }
 private int GetNumberOfSWATTabs()
 {
     WaitForBrowser();
     ChromeCommand command = new ChromeCommand("GetNumberOfSWATTabs");
     chromeHttpServer.SendMessage(command);
     ChromeResponse response = chromeHttpServer.HandleResponse(command);
     return Int32.Parse("" + response.Value);
 }
        public void ElementFireEvent(IdentifierType identType, string identifier, string tagName, string eventName)
        {
            WaitForBrowser(true);

            ChromeCommand command = new ChromeCommand("StimulateElement");
            command.Arguments.Add("identifierType", identType.ToString());
            command.Arguments.Add("identifier", identifier);
            command.Arguments.Add("tagName", tagName);

            if (eventName.StartsWith("on"))
                eventName = eventName.Remove(0, 2);

            command.Arguments.Add("eventName", eventName);

            ChromeResponse response = chromeHttpServer.SendMessageWithTimeout(command, DefaultTimeouts.FindElementTimeout);

            switch (response.StatusCode)
            {
                case StatusCode.SUCCESS:
                    break;
                case StatusCode.ELEMENTDOESNOTEXIST:
                    if (SWAT.WantInformativeExceptions.GetInformativeExceptions)
                        throw new ElementNotFoundException(identifier, identType, tagName);
                    else
                        throw new ElementNotFoundException(identifier, identType);
                case StatusCode.PORTDISCONNECTED:
                    throw new ChromeContentScriptIsNotConnectedException();
            }

            // Give the operating system time in case our stimulate element caused the window to close
            Sleep(100);

            if (FindDialog(DateTime.Now.AddMilliseconds(100)) == IntPtr.Zero)
                HandleSWATTabs();
        }
        public void RefreshBrowser()
        {
            WaitForBrowser();

            ChromeCommand command = new ChromeCommand("RefreshBrowser");
            //command.Arguments.Add("timeout", DefaultTimeouts.WaitForDocumentLoadTimeout);
            chromeHttpServer.SendMessage(command);
            ChromeResponse response = chromeHttpServer.HandleResponse(command);

            switch (response.StatusCode)
            {
                case StatusCode.NAVIGATEFAIL:
                    throw new NavigationTimeoutException(response.Value.ToString());
            }
        }
        public override void SetDocumentAttribute(string theAttributeName, object theAttributeValue)
        {
            WaitForBrowser();

            ChromeCommand command = new ChromeCommand("SetDocumentAttribute");
            command.Arguments.Add("theAttributeName", theAttributeName);
            command.Arguments.Add("theAttributeValue", theAttributeValue);

            chromeHttpServer.SendMessage(command);
            ChromeResponse response = chromeHttpServer.HandleResponse(command);

            switch (response.StatusCode)
            {
                case StatusCode.ELEMENTDOESNOTEXIST:
                    throw new ElementNotFoundException(theAttributeName, IdentifierType.Name);
            }
        }
        public void KillAllOpenBrowsers(string windowTitle)
        {
            WaitForBrowser();

            ChromeCommand command = new ChromeCommand("KillAllOpenBrowsers");

            command.Arguments.Add("windowTitle", windowTitle);

            chromeHttpServer.SendMessage(command);
            chromeHttpServer.HandleResponse(command);

            WaitForTabToClose();
        }
        private void WaitForBrowser(DateTime timeout)
        {
            if (DateTime.Now < timeout)
            {
                ChromeCommand command = new ChromeCommand("CheckTabStatus");
                chromeHttpServer.SendMessage(command);
                ChromeResponse response = chromeHttpServer.HandleResponse(command);

                switch (response.StatusCode)
                {
                    case StatusCode.SUCCESS:
                        break;
                    case StatusCode.LOADING:
                        Thread.Sleep(100);
                        WaitForBrowser(timeout);
                        break;
                }
            }
            return;
        }
        public ChromeResponse SendMessageWithTimeout(ChromeCommand command, int timeout)
        {
            ChromeResponse response;

            Utilities.WriteCommand(command);
            DateTime endTime = DateTime.Now.AddSeconds(timeout);
            do
            {
                SendMessage(command, false);
                response = HandleResponse(command, false);

                if (response.StatusCode == StatusCode.SUCCESS)
                    break;
            }
            while (DateTime.Now < endTime);

            Utilities.WriteResponse(response);
            return response;
        }