我试图在ckeditor内部设置内容,确切地说,在<body>中设置一个<iframe>,但是一旦切换到框架,系统就会抛出: NoSuchElementException。我试图通过类或css选择器查找元素--这些都没有给出结果。
我发现问题在于设置<body>本身的内容,这篇文章:
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>发布于 2019-05-15 12:30:00
您可以为CKEditor创建一个控件类,如下所示:
[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/页面上进行了测试。
发布于 2019-05-15 11:08:40
要回答我自己的问题,修改测试部分的代码可以解决以下问题:
[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();
}https://stackoverflow.com/questions/56134447
复制相似问题