How to use WithFrameTests class of com.github.epadronu.balin.core package

Best Balin code snippet using com.github.epadronu.balin.core.WithFrameTests

Run Balin automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Browser.kt

Source: Browser.kt Github

copy
1/******************************************************************************
2 * Copyright 2016 Edinson E. Padrón Urdaneta
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
17/* ***************************************************************************/
18package com.github.epadronu.balin.core
19/* ***************************************************************************/
20
21/* ***************************************************************************/
22import com.github.epadronu.balin.config.Configuration
23import com.github.epadronu.balin.config.ConfigurationBuilder
24import com.github.epadronu.balin.config.ConfigurationSetup
25import com.github.epadronu.balin.exceptions.MissingPageUrlException
26import com.github.epadronu.balin.exceptions.PageImplicitAtVerificationException
27import com.github.epadronu.balin.utils.ThreadLocalDelegate
28import org.openqa.selenium.Alert
29import org.openqa.selenium.NoSuchWindowException
30import org.openqa.selenium.WebDriver
31import org.openqa.selenium.WebElement
32import org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent
33import kotlin.reflect.full.primaryConstructor
34/* ***************************************************************************/
35
36/* ***************************************************************************/
37/**
38 * Balin's backbone. The `Browser` interface binds together the different
39 * abstractions that form part of the library.
40 *
41 * Additionally, this interface defines the entry point for the Domain-Specific
42 * Language which Balin is built around.
43 */
44interface Browser : JavaScriptSupport, WaitingSupport, WebDriver {
45
46    companion object {
47        /**
48         * The builder in charge of generating the configuration.
49         */
50        private val configurationBuilder: ConfigurationBuilder by ThreadLocalDelegate {
51            ConfigurationBuilder()
52        }
53
54        /**
55         * The name of the property that dictates which setup to use.
56         */
57        internal const val BALIN_SETUP_NAME_PROPERTY: String = "balin.setup.name"
58
59        /**
60         * Retrieves the configuration generated by the builder, taking in
61         * account the value of the [BALIN_SETUP_NAME_PROPERTY] property.
62         */
63        internal val desiredConfiguration: ConfigurationSetup
64            get() = configurationBuilder.build().run {
65                setups[System.getProperty(BALIN_SETUP_NAME_PROPERTY) ?: "default"] ?: this
66            }
67
68        /**
69         * Domain-Specific language that let's you configure Balin's global
70         * behavior.
71         *
72         * @sample com.github.epadronu.balin.config.ConfigurationTests.call_the_configure_method_and_make_changes
73         *
74         * @param block here you can interact with the DSL.
75         */
76        fun configure(block: ConfigurationBuilder.() -> Unit) {
77            block(configurationBuilder)
78        }
79
80        /**
81         * This method represents the entry point for the Domain-Specific
82         * Language which Balin is built around.
83         *
84         * `drive` is the main abstraction layer for Selenium-WebDriver. Inside
85         * the [block] it receives as parameter, you can interact with the
86         * driver and use all the features Balin has to offer.
87         *
88         * @sample com.github.epadronu.balin.core.BrowserTests.perform_a_simple_web_navigation
89         *
90         * @param driverFactory provides the driver on which the navigation and interactions will be performed.
91         * @param autoQuit indicates if the driver should quit at the end of the [block].
92         * @param block here you interact with the driver alongside of Balin's assistance.
93         */
94        fun drive(
95            driverFactory: () -> WebDriver = desiredConfiguration.driverFactory,
96            autoQuit: Boolean = desiredConfiguration.autoQuit,
97            block: Browser.() -> Unit) = drive(Configuration(autoQuit, driverFactory), block)
98
99        /**
100         * This method represents the entry point for the Domain-Specific
101         * Language which Balin is built around.
102         *
103         * `drive` is the main abstraction layer for Selenium-WebDriver. Inside
104         * the [block] it receives as parameter, you can interact with the
105         * driver and use all the features Balin has to offer.
106         *
107         * @sample com.github.epadronu.balin.core.BrowserTests.perform_a_simple_web_navigation
108         *
109         * @param configuration defines Balin's local behavior for [block] only.
110         * @param block here you interact with the driver alongside of Balin's assistance.
111         */
112        fun drive(configuration: Configuration, block: Browser.() -> Unit) {
113            val desiredConfiguration = configuration.run {
114                setups[System.getProperty(BALIN_SETUP_NAME_PROPERTY) ?: "default"] ?: this
115            }
116
117            BrowserImpl(desiredConfiguration).apply {
118                try {
119                    block()
120                } catch (throwable: Throwable) {
121                    throw throwable
122                } finally {
123                    if (configurationSetup.autoQuit) {
124                        quit()
125                    }
126                }
127            }
128        }
129    }
130
131    /**
132     * Tells the browser at what page it should be located.
133     *
134     * If the page defines an _implicit at verification_, then it will be
135     * invoked immediately. If such verification fails, Balin will throw a
136     * [PageImplicitAtVerificationException] in order to perform an early
137     * failure.
138     *
139     * @sample com.github.epadronu.balin.core.BrowserTests.model_a_page_into_a_Page_Object_and_interact_with_it_via_the_at_method
140     *
141     * @param T the page's type.
142     * @param factory provides an instance of the page given the driver being used by the browser.
143     * @Returns An instance of the current page.
144     * @throws PageImplicitAtVerificationException if the page has an _implicit at verification_ which have failed.
145     */
146    fun <T : Page> at(factory: (Browser) -> T): T = factory(this).apply {
147        if (!verifyAt()) {
148            throw PageImplicitAtVerificationException()
149        }
150    }
151
152    /**
153     * Navigates to the given page.
154     *
155     * If the page has not defined a URL, then a
156     * [MissingPageUrlException] will be thrown immediately since
157     * is not possible to perform the navigation.
158     *
159     * If the page defines an _implicit at verification_, then it
160     * will be invoked immediately. If such verification fails, Balin
161     * will throw a [PageImplicitAtVerificationException] in order to
162     * perform an early failure.
163     *
164     * @sample com.github.epadronu.balin.core.BrowserTests.perform_a_simple_web_navigation
165     *
166     * @param T the page's type.
167     * @param factory provides an instance of the page given the driver being used by the browser.
168     * @Returns An instance of the current page.
169     * @throws MissingPageUrlException if the page has not defined a URL.
170     * @throws PageImplicitAtVerificationException if the page has an _implicit at verification_ which have failed.
171     * @see org.openqa.selenium.WebDriver.get
172     */
173    fun <T : Page> to(factory: (Browser) -> T): T = factory(this).apply {
174        get(url ?: throw MissingPageUrlException())
175
176        if (!verifyAt()) {
177            throw PageImplicitAtVerificationException()
178        }
179    }
180
181    /**
182     * Navigates to the given URL.
183     *
184     * @param url the URL the browser will navigate to.
185     * @return The browser's current URL.
186     *
187     * @see org.openqa.selenium.WebDriver.get
188     */
189    fun to(url: String): String {
190        get(url)
191
192        return currentUrl
193    }
194}
195/* ***************************************************************************/
196
197/* ***************************************************************************/
198/**
199 * Switches to the currently active modal dialog for this particular driver instance.
200 *
201 * You can interact with the dialog handler only inside [alertContext].
202 *
203 * @sample com.github.epadronu.balin.core.WithAlertTests.validate_context_switching_to_and_from_an_alert_popup_and_accept_it
204 *
205 * @param alertContext here you can interact with the dialog handler.
206 * @throws org.openqa.selenium.NoAlertPresentException If the dialog cannot be found.
207 */
208inline fun Browser.withAlert(alertContext: Alert.() -> Unit): Unit = try {
209    switchTo().alert().run {
210        alertContext()
211
212        if (this == alertIsPresent().apply(driver)) {
213            dismiss()
214        }
215    }
216} catch (throwable: Throwable) {
217    throw throwable
218} finally {
219    switchTo().defaultContent()
220}
221
222/**
223 * Select a frame by its (zero-based) index and switch the driver's context to
224 * it.
225 *
226 * Once the frame has been selected, all subsequent calls on the WebDriver
227 * interface are made to that frame till the end of [iFrameContext].
228 *
229 * If a exception is thrown inside [iFrameContext], the driver will return to
230 * its default context.
231 *
232 * @sample com.github.epadronu.balin.core.WithFrameTests.validate_context_switching_to_and_from_an_iframe_with_index
233 *
234 * @param index (zero-based) index.
235 * @param iFrameContext here you can interact with the given IFrame.
236 * @throws org.openqa.selenium.NoSuchFrameException If the frame cannot be found.
237 */
238inline fun Browser.withFrame(index: Int, iFrameContext: () -> Unit): Unit = try {
239    switchTo().frame(index)
240    iFrameContext()
241} catch (throwable: Throwable) {
242    throw throwable
243} finally {
244    switchTo().defaultContent()
245}
246
247/**
248 * Select a frame by its name or ID. Frames located by matching name attributes
249 * are always given precedence over those matched by ID.
250 *
251 * Once the frame has been selected, all subsequent calls on the WebDriver
252 * interface are made to that frame till the end of [iFrameContext].
253 *
254 * If a exception is thrown inside [iFrameContext], the driver will return to
255 * its default context.
256 *
257 * @sample com.github.epadronu.balin.core.WithFrameTests.validate_context_switching_to_and_from_an_iframe_with_id
258 *
259 * @param nameOrId the name of the frame window, the id of the &lt;frame&gt; or &lt;iframe&gt; element, or the (zero-based) index.
260 * @param iFrameContext here you can interact with the given IFrame.
261 * @throws org.openqa.selenium.NoSuchFrameException If the frame cannot be found.
262 */
263inline fun Browser.withFrame(nameOrId: String, iFrameContext: () -> Unit): Unit = try {
264    switchTo().frame(nameOrId)
265    iFrameContext()
266} catch (throwable: Throwable) {
267    throw throwable
268} finally {
269    switchTo().defaultContent()
270}
271
272/**
273 * Select a frame using its previously located WebElement.
274 *
275 * Once the frame has been selected, all subsequent calls on the WebDriver
276 * interface are made to that frame till the end of [iFrameContext].
277 *
278 * If a exception is thrown inside [iFrameContext], the driver will return to
279 * its default context.
280 *
281 * @sample com.github.epadronu.balin.core.WithFrameTests.validate_context_switching_to_and_from_an_iframe_with_web_element
282 *
283 * @param webElement the frame element to switch to.
284 * @param iFrameContext here you can interact with the given IFrame.
285 * @throws org.openqa.selenium.NoSuchFrameException If the frame cannot be found.
286 */
287inline fun Browser.withFrame(webElement: WebElement, iFrameContext: () -> Unit): Unit = try {
288    switchTo().frame(webElement)
289    iFrameContext()
290} catch (throwable: Throwable) {
291    throw throwable
292} finally {
293    switchTo().defaultContent()
294}
295
296/**
297 * Select a frame by its (zero-based) index and switch the driver's context to
298 * it.
299 *
300 * Once the frame has been selected, all subsequent calls on the WebDriver
301 * interface are made to that frame via a `Page Object` of type [T] till
302 * the end of [iFrameContext].
303 *
304 * If a exception is thrown inside [iFrameContext], the driver will return to
305 * its default context.
306 *
307 * @sample com.github.epadronu.balin.core.WithFrameTests.validate_context_switching_to_and_from_an_iframe_with_index_and_pages
308 *
309 * @param T the `Page Object`'s type.
310 * @param index (zero-based) index.
311 * @param iFrameContext here you can interact with the given IFrame via a `Page Object`.
312 * @throws org.openqa.selenium.NoSuchFrameException If the frame cannot be found.
313 */
314inline fun <reified T : Page> Browser.withFrame(index: Int, iFrameContext: T.() -> Unit): Unit = try {
315    switchTo().frame(index)
316    @Suppress("UNCHECKED_CAST")
317    iFrameContext(at(T::class.primaryConstructor as (Browser) -> T))
318} catch (throwable: Throwable) {
319    throw throwable
320} finally {
321    switchTo().defaultContent()
322}
323
324/**
325 * Select a frame by its name or ID. Frames located by matching name attributes
326 * are always given precedence over those matched by ID.
327 *
328 * Once the frame has been selected, all subsequent calls on the WebDriver
329 * interface are made to that frame via a `Page Object` of type [T] till
330 * the end of [iFrameContext].
331 *
332 * If a exception is thrown inside [iFrameContext], the driver will return to
333 * its default context.
334 *
335 * @sample com.github.epadronu.balin.core.WithFrameTests.validate_context_switching_to_and_from_an_iframe_with_id_and_pages
336 *
337 * @param T the `Page Object`'s type.
338 * @param nameOrId the name of the frame window, the id of the &lt;frame&gt; or &lt;iframe&gt; element, or the (zero-based) index.
339 * @param iFrameContext here you can interact with the given IFrame via a `Page Object`.
340 * @throws org.openqa.selenium.NoSuchFrameException If the frame cannot be found.
341 */
342inline fun <reified T : Page> Browser.withFrame(nameOrId: String, iFrameContext: T.() -> Unit): Unit = try {
343    switchTo().frame(nameOrId)
344    @Suppress("UNCHECKED_CAST")
345    iFrameContext(at(T::class.primaryConstructor as (Browser) -> T))
346} catch (throwable: Throwable) {
347    throw throwable
348} finally {
349    switchTo().defaultContent()
350}
351
352/**
353 * Select a frame using its previously located WebElement.
354 *
355 * Once the frame has been selected, all subsequent calls on the WebDriver
356 * interface are made to that frame via a `Page Object` of type [T] till
357 * the end of [iFrameContext].
358 *
359 * If a exception is thrown inside [iFrameContext], the driver will return to
360 * its default context.
361 *
362 * @sample com.github.epadronu.balin.core.WithFrameTests.validate_context_switching_to_and_from_an_iframe_with_web_element_and_pages
363 *
364 * @param T the `Page Object`'s type.
365 * @param webElement the frame element to switch to.
366 * @param iFrameContext here you can interact with the given IFrame via a `Page Object`.
367 * @throws org.openqa.selenium.NoSuchFrameException If the frame cannot be found.
368 */
369inline fun <reified T : Page> Browser.withFrame(webElement: WebElement, iFrameContext: T.() -> Unit): Unit = try {
370    switchTo().frame(webElement)
371    @Suppress("UNCHECKED_CAST")
372    iFrameContext(at(T::class.primaryConstructor as (Browser) -> T))
373} catch (throwable: Throwable) {
374    throw throwable
375} finally {
376    switchTo().defaultContent()
377}
378
379/**
380 * Switch the focus of future commands for this driver to the window with the
381 * given name/handle.
382 *
383 * The name/handle can be omitted and the switching will be performed
384 * automatically if and only if there is only two windows currently
385 * opened.
386 *
387 * Once the window has been selected, all subsequent calls on the WebDriver
388 * interface are made to that window till the end of [windowContext].
389 *
390 * If a exception is thrown inside [windowContext], the driver will return to
391 * the previous window.
392 *
393 * @sample com.github.epadronu.balin.core.WithWindowTests.validate_context_switching_to_and_from_a_window
394 *
395 * @param nameOrHandle The name of the window or the handle as returned by [WebDriver.getWindowHandle]
396 * @param windowContext Here you can interact with the given window.
397 * @throws NoSuchWindowException If the window cannot be found or, in the case of no name or handle is indicated,
398 *                               there is not exactly two windows currently opened.
399 */
400inline fun Browser.withWindow(nameOrHandle: String? = null, windowContext: WebDriver.() -> Unit) {
401    val originalWindow = windowHandle
402
403    val targetWindow = nameOrHandle ?: windowHandles.toSet().minus(originalWindow).run {
404        when (size) {
405            0 -> throw NoSuchWindowException("No new window was found")
406            1 -> first()
407            else -> throw NoSuchWindowException("The window cannot be determined automatically")
408        }
409    }
410
411    try {
412        switchTo().window(targetWindow).windowContext()
413    } catch (throwable: Throwable) {
414        throw throwable
415    } finally {
416        if (originalWindow != targetWindow && windowHandles.contains(targetWindow)) {
417            close()
418        }
419
420        switchTo().window(originalWindow)
421    }
422}
423/* ***************************************************************************/
424
Full Screen

WithFrameTests.kt

Source: WithFrameTests.kt Github

copy
1/******************************************************************************
2 * Copyright 2016 Edinson E. Padrón Urdaneta
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
17/* ***************************************************************************/
18package com.github.epadronu.balin.core
19/* ***************************************************************************/
20
21/* ***************************************************************************/
22import com.github.epadronu.balin.extensions.`$`
23import org.openqa.selenium.NoSuchFrameException
24import org.openqa.selenium.WebDriver
25import org.openqa.selenium.htmlunit.HtmlUnitDriver
26import org.testng.Assert.assertEquals
27import org.testng.Assert.assertThrows
28import org.testng.Assert.fail
29import org.testng.annotations.DataProvider
30import org.testng.annotations.Test
31import com.gargoylesoftware.htmlunit.BrowserVersion.FIREFOX_60 as BROWSER_VERSION
32/* ***************************************************************************/
33
34/* ***************************************************************************/
35class WithFrameTests {
36
37    companion object {
38        @JvmStatic
39        val pageWithIFramesUrl = WithFrameTests::class.java
40            .getResource("/test-pages/page-with-iframes.html")
41            .toString()
42    }
43
44    @DataProvider(name = "JavaScript-incapable WebDriver factory", parallel = true)
45    fun `Create a JavaScript-incapable WebDriver factory`() = arrayOf(
46        arrayOf({ HtmlUnitDriver(BROWSER_VERSION) })
47    )
48
49    @Test(description = "Validate context switching to and from an IFrame with index",
50        dataProvider = "JavaScript-incapable WebDriver factory")
51    fun validate_context_switching_to_and_from_an_iframe_with_index(driverFactory: () -> WebDriver) {
52        Browser.drive(driverFactory) {
53            // Given I navigate to the page under test, which contains three IFrames
54            to(pageWithIFramesUrl)
55
56            // And I'm in the context of the page
57            assertEquals(`$`("h1", 0).text, "Page with IFrames")
58
59            // When I change the driver's context to the second IFrame
60            withFrame(1) {
61                // Then I should be able to interact with such IFrame
62                assertEquals(
63                    `$`(".tag-home__item", 0).text.trim(),
64                    "The search engine that doesn't track you. Learn More.")
65            }
66
67            // And I should return into the context of the page at the end of the `withFrame` method
68            assertEquals(`$`("h1", 0).text, "Page with IFrames")
69        }
70    }
71
72    @Test(description = "Validate context switching to and from an IFrame with ID",
73        dataProvider = "JavaScript-incapable WebDriver factory")
74    fun validate_context_switching_to_and_from_an_iframe_with_id(driverFactory: () -> WebDriver) {
75        Browser.drive(driverFactory) {
76            // Given I navigate to the page under test, which contains three IFrames
77            to(pageWithIFramesUrl)
78
79            // And I'm in the context of the page
80            assertEquals(`$`("h1", 0).text, "Page with IFrames")
81
82            // When I change the driver's context to the searx.me IFrame
83            withFrame("searx-iframe") {
84                // Then I should be able to interact with such IFrame
85                assertEquals(`$`("#main-logo", 0).text.trim(), "searx")
86            }
87
88            // And I should return into the context of the page at the end of the `withFrame` method
89            assertEquals(`$`("h1", 0).text, "Page with IFrames")
90        }
91    }
92
93    @Test(description = "Validate context switching to and from an IFrame with WebElement",
94        dataProvider = "JavaScript-incapable WebDriver factory")
95    fun validate_context_switching_to_and_from_an_iframe_with_web_element(driverFactory: () -> WebDriver) {
96        Browser.drive(driverFactory) {
97            // Given I navigate to the page under test, which contains three IFrames
98            to(pageWithIFramesUrl)
99
100            // And I'm in the context of the page
101            assertEquals(`$`("h1", 0).text, "Page with IFrames")
102
103            // When I change the driver's context to the first IFrame
104            withFrame(`$`("iframe", 0)) {
105                // Then I should be able to interact with such IFrame
106                assertEquals(`$`(".overview-header", 0).text, "Try Kotlin")
107            }
108
109            // And I should return into the context of the page at the end of the `withFrame` method
110            assertEquals(`$`("h1", 0).text, "Page with IFrames")
111        }
112    }
113
114    @Test(description = "Validate context switching to and from an IFrame with index and pages",
115        dataProvider = "JavaScript-incapable WebDriver factory")
116    fun validate_context_switching_to_and_from_an_iframe_with_index_and_pages(driverFactory: () -> WebDriver) {
117        // Given a Page Object for the page under test, which contains three IFrames
118        class IndexPage(browser: Browser) : Page(browser) {
119
120            override val url = pageWithIFramesUrl
121
122            override val at = at {
123                title == "Page with IFrames"
124            }
125
126            val headerText
127                get() = `$`("h1", 0).text
128        }
129
130        // And a Page Object for the DuckDuckGo IFrame
131        class DuckDuckGoHomePage(browser: Browser) : Page(browser) {
132
133            override val at = at {
134                `$`(".cw--c > div > a", 0).text.trim() == "About DuckDuckGo"
135            }
136
137            val homeFooterText
138                get() = `$`(".tag-home__item", 0).text.trim()
139        }
140
141        Browser.drive(driverFactory) {
142            // And I navigate to the page under test
143            val indexPage = to(::IndexPage)
144
145            // And I'm in the context of such page
146            assertEquals(indexPage.headerText, "Page with IFrames")
147
148            // When I change the driver's context to DuckDuckGo IFrame
149            withFrame<DuckDuckGoHomePage>(1) {
150                // Then I should be able to interact with such IFrame via its Page Object
151                assertEquals(homeFooterText, "The search engine that doesn't track you. Learn More.")
152            }
153
154            // And I should return into the context of the page under test at the end of the `withFrame` method
155            assertEquals(indexPage.headerText, "Page with IFrames")
156        }
157    }
158
159    @Test(description = "Validate context switching to and from an IFrame with ID and pages",
160        dataProvider = "JavaScript-incapable WebDriver factory")
161    fun validate_context_switching_to_and_from_an_iframe_with_id_and_pages(driverFactory: () -> WebDriver) {
162        // Given a Page Object for the page under test, which contains three IFrames
163        class IndexPage(browser: Browser) : Page(browser) {
164
165            override val url = pageWithIFramesUrl
166
167            override val at = at {
168                title == "Page with IFrames"
169            }
170
171            val headerText
172                get() = `$`("h1", 0).text
173        }
174
175        // And a Page Object for the searx.me IFrame
176        class SearxHomePage(browser: Browser) : Page(browser) {
177
178            override val at = at {
179                `$`(".instance > a", 0).text.trim() == "searx.me"
180            }
181
182            val logoImageText
183                get() = `$`("#main-logo", 0).text
184        }
185
186        Browser.drive(driverFactory) {
187            // And I navigate to the page under test
188            val indexPage = to(::IndexPage)
189
190            // And I'm in the context of such page
191            assertEquals(indexPage.headerText, "Page with IFrames")
192
193            // When I change the driver's context to searx.me IFrame
194            withFrame<SearxHomePage>("searx-iframe") {
195                // Then I should be able to interact with such IFrame via its Page Object
196                assertEquals(logoImageText, "searx")
197            }
198
199            // And I should return into the context of the page under test at the end of the `withFrame` method
200            assertEquals(indexPage.headerText, "Page with IFrames")
201        }
202    }
203
204    @Test(description = "Validate context switching to and from an IFrame with WebElement and pages",
205        dataProvider = "JavaScript-incapable WebDriver factory")
206    fun validate_context_switching_to_and_from_an_iframe_with_web_element_and_pages(driverFactory: () -> WebDriver) {
207        // Given a Page Object for the page under test, which contains three IFrames
208        class IndexPage(browser: Browser) : Page(browser) {
209
210            override val url = pageWithIFramesUrl
211
212            override val at = at {
213                title == "Page with IFrames"
214            }
215
216            val headerText
217                get() = `$`("h1", 0).text
218        }
219
220        // And a Page Object for the KotlinLang IFrame
221        class KotlinLangIndexPage(browser: Browser) : Page(browser) {
222
223            override val at = at {
224                `$`("a.global-header-logo", 0).text == "Kotlin"
225            }
226
227            val tryKotlinHeaderText
228                get() = `$`(".overview-header", 0).text
229        }
230
231        Browser.drive(driverFactory) {
232            // And I navigate to the page under test
233            val indexPage = to(::IndexPage)
234
235            // And I'm in the context of such page
236            assertEquals(indexPage.headerText, "Page with IFrames")
237
238            // When I change the driver's context to KotlinLang IFrame
239            withFrame<KotlinLangIndexPage>(`$`("iframe", 0)) {
240                // Then I should be able to interact with such IFrame via its Page Object
241                assertEquals(tryKotlinHeaderText, "Try Kotlin")
242            }
243
244            // And I should return into the context of the page under test at the end of the `withFrame` method
245            assertEquals(indexPage.headerText, "Page with IFrames")
246        }
247    }
248
249    @Test(dataProvider = "JavaScript-incapable WebDriver factory")
250    fun `Frame switching should fail when an invalid IFrame index is provided`(driverFactory: () -> WebDriver) {
251        Browser.drive(driverFactory) {
252            // Given I navigate to the page under test, which contains three IFrames
253            to(pageWithIFramesUrl)
254
255            // When I change the driver's context via an invalid index
256            // Then a failure should be communicated
257            assertThrows(NoSuchFrameException::class.java) {
258                withFrame(4) {
259                    fail("This shouldn't be reached")
260                }
261            }
262
263            // And I should return into the context of the page at the end of the `withFrame` method
264            assertEquals(`$`("h1", 0).text, "Page with IFrames")
265        }
266    }
267
268    @Test(dataProvider = "JavaScript-incapable WebDriver factory")
269    fun `Frame switching should fail when an invalid IFrame ID is provided`(driverFactory: () -> WebDriver) {
270        Browser.drive(driverFactory) {
271            // Given I navigate to the page under test, which contains three IFrames
272            to(pageWithIFramesUrl)
273
274            // When I change the driver's context via an invalid ID
275            // Then a failure should be communicated
276            assertThrows(NoSuchFrameException::class.java) {
277                withFrame("invalid-iframe") {
278                    fail("This shouldn't be reached")
279                }
280            }
281
282            // And I should return into the context of the page at the end of the `withFrame` method
283            assertEquals(`$`("h1", 0).text, "Page with IFrames")
284        }
285    }
286
287    @Test(dataProvider = "JavaScript-incapable WebDriver factory")
288    fun `Frame switching should fail when a WebElement other than an IFrame is provided`(driverFactory: () -> WebDriver) {
289        Browser.drive(driverFactory) {
290            // Given I navigate to the page under test, which contains three IFrames
291            to(pageWithIFramesUrl)
292
293            // When I change the driver's context via a WebElement other than an IFrame
294            // Then a failure should be communicated
295            assertThrows(NoSuchFrameException::class.java) {
296                withFrame(`$`("p", 0)) {
297                    fail("This shouldn't be reached")
298                }
299            }
300
301            // And I should return into the context of the page at the end of the `withFrame` method
302            assertEquals(`$`("h1", 0).text, "Page with IFrames")
303        }
304    }
305}
306/* ***************************************************************************/
307
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie