如何使用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/ 页面上测试。
我正在尝试在 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/ 页面上测试。