如何使用Atata框架在ckeditor中设置内容?

How to set content inside ckeditor using Atata framework?

我正在尝试在 ckeditor 中设置内容,准确地说是在 <iframe><body> 中,但是当我切换到框架时,系统会抛出:NoSuchElementException。我试图通过 class 或 css 选择器查找元素 - none 给出了结果。

我发现问题出在 <body> 本身的设置内容上,而这个 post:

How to get and set text editor value in selenium

但我不确定如何使用 Atata 执行 JavaScript。以下是我的部分代码。

<iframe> 所在的页面:

    public class DocumentEditPage : Page<_>
    {
        [FindById("cke_1_contents")]
        //[FindByClass("cke_wysiwyg_frame cke_reset")] 
        //[FindByIndex(0)]
        public Frame<DocumentFramePage, _> ContentSwedish { get; private set; 
    }

框架页:

    public class DocumentFramePage : Page<_>
    {
        [FindByClass("cke_editable cke_editable_themed cke_contents_ltr cke_show_borders")]
        //[FindByCss("body")]
        public TextInput<_> TextBoxEditingContent { get; private set; }

    }

测试:

    [Test]
        public void SaveContentInsideFrame()
        {

            string ID = "7";
            string valueToBeSet = "TestContent";


            Go.To<DocumentsPage>().
               Documents.Rows[x => x.Dokument_ID == ID].Edit().
               // Refresh page so the content can be visible
               RefreshPage().
               ContentSwedish.SwitchTo().
               TextBoxEditingContent.Clear().
               TextBoxEditingContent.Set(valueToBeSet).
               SwitchToRoot<DocumentEditPage>().
               // Click on Save button
               Save();
        }

HTML 页面代码:


<div id="cke_1_contents" class="cke_contents cke_reset" role="presentation" style="height: 200px;">
<span id="cke_52" class="cke_voice_label">Press ALT 0 for help</span>
<iframe src="" style="width: 100%; height: 100%;" class="cke_wysiwyg_frame cke_reset" title="Rich Text Editor, Details_0__Content" aria-describedby="cke_52" tabindex="0" allowtransparency="true" frameborder="0"></iframe></div>

<body class="cke_editable cke_editable_themed cke_contents_ltr cke_show_borders" spellcheck="false" contenteditable="true">
<h1>Test</h1>
<p>Test<br></p>
<p>Test<br></p>
<p><br></p>
</body>

为了回答我自己的问题,更改测试部分的代码解决了问题:

 [Test]
    public void SaveContentInsideFrame()
    {

        string ID = "7";
        string valueToBeSet = "TestContent";

        var body = Go.To<DocumentsPage>().
           Documents.Rows[x => x.Dokument_ID == ID].Edit().
           // Refresh page so the content can be visible
           RefreshPage();
           //Execute script for changing content
           AtataContext.Current.Driver.ExecuteScript("CKEDITOR.instances.Details_0__Content.setData('" + valueToBeSet + "')");              
           body.
           // Click on Save button
           Save();
    }

您可以为CKEditor创建一个控件class,如下所示:

[ControlDefinition("iframe", ContainingClass = "cke_wysiwyg_frame", ComponentTypeName = "CKEditor")]
public class CKEditor<TOwner> : EditableField<string, TOwner>
    where TOwner : PageObject<TOwner>
{
    protected override string GetValue()
    {
        string value = null;

        DoWithinFrame(body =>
        {
            value = body.Text;
        });

        return value;
    }

    protected override void SetValue(string value)
    {
        DoWithinFrame(body =>
        {
            body.Clear();
            body.SendKeys(value);
        });
    }

    // An appoach to set a value using JavaScript.
    //protected override void SetValue(string value)
    //{
    //    Driver.ExecuteScript(
    //        "arguments[0].contentDocument.getElementsByClassName('cke_editable_themed')[0].innerHTML = arguments[1];",
    //        Scope, // Actual CKEditor <iframe> element.
    //        value);
    //}

    protected void DoWithinFrame(Action<IWebElement> frameBodyAction)
    {
        var frame = Driver.SwitchTo().Frame(Scope);
        var frameBody = frame.Get(By.TagName("body"));

        frameBodyAction?.Invoke(frameBody);

        Driver.SwitchTo().DefaultContent();
    }
}

里面封装了iframe开关的逻辑

然后在页面对象中使用:

public class DocumentEditPage : Page<_>
{
    public CKEditor<_> Editor { get; private set; }
}

并在测试中像与常规输入字段一样与其交互:

Go.To<DocumentEditPage>().
    Editor.Set("sample text").
    Editor.Should.Equal("sample text");

以上代码适用于 CKEditor 4。在 https://ckeditor.com/ckeditor-4/demo/ 页面上测试。