C# 使用C和Selenium将多行SQL文本输入网页上的代码镜像文本框

C# 使用C和Selenium将多行SQL文本输入网页上的代码镜像文本框,c#,selenium,codemirror,C#,Selenium,Codemirror,我正在尝试使用Selenium将SQL代码输入到代码镜像文本框中。为了回答这个问题,我将以这个网站为例 我的问题是: 如果代码包含回车符或换行符,我无法将MSSQL SQL代码提交到代码文本框中 作为一种解决方法,在使用JavaScript函数将其写入文本框之前,我将删除所有这些内容,但最终的结果是非常难看的word-wrapped SQL 我还尝试在SeleniumWebElement对象上使用SendKeys方法将代码发送到文本框中,但我不确定要查找哪个元素。使用SendKeys需要选择te

我正在尝试使用Selenium将SQL代码输入到代码镜像文本框中。为了回答这个问题,我将以这个网站为例

我的问题是:

如果代码包含回车符或换行符,我无法将MSSQL SQL代码提交到代码文本框中

作为一种解决方法,在使用JavaScript函数将其写入文本框之前,我将删除所有这些内容,但最终的结果是非常难看的word-wrapped SQL

我还尝试在SeleniumWebElement对象上使用SendKeys方法将代码发送到文本框中,但我不确定要查找哪个元素。使用SendKeys需要选择textbox,当我尝试调用该对象上的Click和SendKeys方法时,我经常会得到一个错误,即元素不允许用户交互

如果我能始终找到一个可以交互的元素,比如TextArea,我会尝试将剪贴板的内容粘贴到其中,而不是向textbox发送大量的按键。例如,下面的错误通常会导致无法与此对象交互,但偶尔也会发生,这可能取决于文本框的当前内容

Clipboard.SetText(sql);
var txtbx = codeMirror.FindElement(By.CssSelector("textarea"));
txtbx.Click();
txtbx.SendKeys(OpenQA.Selenium.Keys.Control + "v");
       
我认为设置文本的最佳机会是使用executescript方法在CodeMirror对象上执行setValue JavaScript方法,如下所示。同样,如果SQL没有CR/LF字符,那么这是可行的,但是如何更改代码以允许使用这些字符呢

我已经看到很多关于这个的帖子,但是我的JavaScript知识可能不够好,无法让我了解最终结果。我希望有人能用下面的代码重建一个工作示例。以下是相对简短的说明

创建C项目控制台应用程序、winForms等,并添加以下3个Nuget软件包:

Selenium.Chrome.WebDriver
Selenium.WebDriver
Selenium.WebDriver.ChromeDriver
创建一个类SeleniumHelperGudSoft并粘贴到以下代码中:

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SqlSmoke.Classes
{
    public class SeleniumHelperGudusoft
    {
        private IWebDriver driver;

        public SeleniumHelperGudusoft()
        {
            var chromeDriverService = ChromeDriverService.CreateDefaultService();
            chromeDriverService.HideCommandPromptWindow = false;

            ChromeOptions options = new ChromeOptions();
            options.AddAdditionalCapability("useAutomationExtension", false);
            this.driver = new ChromeDriver(chromeDriverService, options);
        }

        public void NavigateToMain()
        {
            driver.Url = @"http://www.gudusoft.com/sqlflow/#/";
        }

        public void SetLanguageToMsSql()
        {
            string languageButtoncssSelector = "#Root > div > div.Main > div > div.Route.Row.x-start.y-stretch > div.SQLFlowEditor > div.SQLFlowEditorOperations.Row.x-start.y-center > div.DbVendor > div > div > svg";
            var languageButton = driver.FindElement(By.CssSelector(languageButtoncssSelector));
            languageButton.Click();

            string msSqlCssSelector = "#Root > div > div.Main > div > div.Route.Row.x-start.y-stretch > div.SQLFlowEditor > div.SQLFlowEditorOperations.Row.x-start.y-center > div.DbVendor > ul > li:nth-child(10)";
            var msSql = driver.FindElement(By.CssSelector(msSqlCssSelector));
            msSql.Click();
        }

        public void SetSqlText(string sql)
        {
            IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
            var codeMirror = driver.FindElement(By.ClassName("CodeMirror"));
            js.ExecuteScript("arguments[0].CodeMirror.setValue(\"" + sql + "\");", codeMirror); //<<<<----Fails here with the error message shown below in my post
        }

        public void ClickVisualizeButton()
        {
            string buttonCssSelector = "#Visualize > div";
            var button = driver.FindElement(By.CssSelector(buttonCssSelector));
            button.Click();
        }
    }
}
如何修改示例以将第二个查询输入到CodeMirror文本框中

使现代化 代码镜像文档可在此处找到:

下面是错误的完整调用堆栈:

OpenQA.Selenium.WebDriverException
  HResult=0x80131500
  Message=javascript error: Invalid or unexpected token
  (Session info: chrome=84.0.4147.105)
  Source=WebDriver
  StackTrace:
   at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
   at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.Remote.RemoteWebDriver.ExecuteScriptCommand(String script, String commandName, Object[] args)
   at OpenQA.Selenium.Remote.RemoteWebDriver.ExecuteScript(String script, Object[] args)
   at MyNAME.Selenium.SeleniumHelperGudusoft.SetSqlText(String sql) in C:\Users\MYLANID\Desktop\SqlSmoke Code\MyNAME.Selenium\SeleniumHelper.cs:line 41
   at MyNAME.Selenium.Form1.button3_Click(Object sender, EventArgs e) in C:\Users\MYLANID\Desktop\SqlSmoke Code\MyNAME.Selenium\Form1.cs:line 201
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at MyNAME.Selenium.Program.Main() in C:\Users\MYLANID\Desktop\SqlSmoke Code\MyNAME.Selenium\Program.cs:line 19

在JavaScript中设置值时,可能需要重新转义回车符和换行符:

var sql = @"SELECT foo
FROM bar";
var jsString = sql.Replace("\r", "\\r")
                  .Replace("\n", "\\n");

js.ExecuteScript("arguments[0].CodeMirror.setValue(\"" + jsString + "\");", codeMirror);
生成的JavaScript行将是:

参数[0]。CodeMirror.setValueSELECT foo\n\r从工具栏 请注意,SQL字符串中的任何双引号也需要转义,以便它们不会过早结束JavaScript字符串:

var sql = @"SELECT foo AS '"bar"'
FROM baz";
var jsString = sql.Replace("\r", "\\r")
                  .Replace("\n", "\\n")
                  .Replace("\"", "\\\"");

js.ExecuteScript("arguments[0].CodeMirror.setValue(\"" + jsString + "\");", codeMirror);
因此,生成的JavaScript是:

参数[0]。CodeMirror.setValueSELECT foo作为“\bar\”\n\r来自baz;
要避免此错误,只需将SQL字符串作为参数提供:

js.ExecuteScript("arguments[0].CodeMirror.setValue(arguments[1]);", codeMirror, sql);
或使用反勾号引用:

js.ExecuteScript("arguments[0].CodeMirror.setValue(`" + sql + "`);", codeMirror);

您最好的选择可能是从剪贴板粘贴文本。。。虽然我还没有试过在C。。。在java中,粘贴方式如下:stringvkey=v;element.sendKeysKeys.CONTROL,vKey;请看这里设置剪贴板在C:谢谢你的答复。我文章中的第一个代码块就是一个尝试这样做的例子,但是正如文章中提到的,我得到了一个selenium错误,我使用SendKeys的元素不允许交互。我不使用Java编写代码,但我得到了我所做的,但主要是查看Java示例。我不熟悉Selenium这是我第一次尝试使用它。无法将MSSQL SQL代码提交到代码文本框是什么意思?你有错误吗?表单验证消息?sql变量来自哪里?它也是用C硬编码的吗?SQL是否来自文件,如果是,它使用什么行尾?这到底是怎么失败的?你在处理什么HTML?CodeMirror是某种形式的富文本编辑器吗?@GregBurghardt我更新了我的帖子,以包含特定的错误消息,并使其在哪里出现更清楚。是的,SQL是硬编码的。在我的示例中,我有两个SQL,一个带有CR LF,另一个不带CR LF。第二个失败了,你太棒了。非常感谢。为了表示我的感谢,我不会立即标记这是答案,而是在2天内,当这个问题有资格获得奖金时,向您提供500分奖金。无需转义/替换,只需使用模板字符串反勾,并引用:js.ExecuteScriptarguments[0]。CodeMirror.setValue\u0060+sql+\u0060;,编码镜;
js.ExecuteScript("arguments[0].CodeMirror.setValue(arguments[1]);", codeMirror, sql);
js.ExecuteScript("arguments[0].CodeMirror.setValue(`" + sql + "`);", codeMirror);