blob: 7eb12118a4daafe03ab8a454b8be47816b2f7a56 [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
import 'dart:async';
import 'dart:math';
import '../common/by.dart';
import '../common/request_client.dart';
import '../common/web_element.dart' as common;
import '../common/webdriver_handler.dart';
import 'common.dart';
import 'web_driver.dart';
class WebElement extends common.WebElement implements SearchContext {
final WebDriver driver;
final String id;
/// The context from which this element was found.
final SearchContext? context;
/// How the element was located from the context.
final dynamic /* String | Finder */ locator;
/// The index of this element in the set of element founds. If the method
/// used to find this element always returns one element, then this is null.
final int? index;
final AsyncRequestClient _client;
final WebDriverHandler _handler;
WebElement(this.driver, this._client, this._handler,,
[this.context, this.locator, this.index]);
/// Click on this element.
Future<void> click() => _client.send(_handler.element.buildClickRequest(id),
/// Send [keysToSend] to this element.
Future<void> sendKeys(String keysToSend) => _client.send(
_handler.element.buildSendKeysRequest(id, keysToSend),
/// Clear the content of a text element.
Future<void> clear() => _client.send(_handler.element.buildClearRequest(id),
/// Is this radio button/checkbox selected?
Future<bool> get selected => _client.send(
/// Is this form element enabled?
Future<bool> get enabled => _client.send(
/// Is this element visible in the page?
Future<bool> get displayed => _client.send(
/// The location within the document of this element.
Future<Point<int>> get location => _client.send(
/// The size of this element.
Future<Rectangle<int>> get size => _client.send(
/// The bounds of this element.
Future<Rectangle<int>> get rect async {
final location = await this.location;
final size = await this.size;
return Rectangle<int>(location.x, location.y, size.width, size.height);
/// The tag name for this element.
Future<String> get name => _client.send(_handler.element.buildNameRequest(id),
/// Visible text within this element.
Future<String> get text => _client.send(_handler.element.buildTextRequest(id),
///Find an element nested within this element.
/// Throws [NoSuchElementException] if matching element is not found.
Future<WebElement> findElement(By by) => _client.send(
_handler.elementFinder.buildFindElementRequest(by, id),
(response) => driver.getElement(
_handler.elementFinder.parseFindElementResponse(response), this, by));
/// Find multiple elements nested within this element.
Stream<WebElement> findElements(By by) async* {
final ids = await _client.send(
_handler.elementFinder.buildFindElementsRequest(by, id),
var i = 0;
for (var id in ids) {
yield driver.getElement(id, this, by, i);
/// Access to the HTML attributes of this tag.
/// TODO(DrMarcII): consider special handling of boolean attributes.
Attributes get attributes => Attributes((name) => _client.send(
_handler.element.buildAttributeRequest(id, name),
/// Access to the selenium attributes of this tag.
/// This is deprecated, only used to support old pageloader.
Attributes get seleniumAttributes => Attributes((name) => _client.send(
_handler.element.buildSeleniumAttributeRequest(id, name),
/// Access to the HTML properties of this tag.
Attributes get properties => Attributes((name) => _client.send(
_handler.element.buildPropertyRequest(id, name),
/// Access to the cssProperties of this element.
/// TODO(DrMarcII): consider special handling of color and possibly other
/// properties.
Attributes get cssProperties => Attributes((name) => _client.send(
_handler.element.buildCssPropertyRequest(id, name),
Future<bool> equals(WebElement other) async =>
other is WebElement && other.driver == driver && == id;
int get hashCode => driver.hashCode * 3 + id.hashCode;
bool operator ==(other) =>
other is WebElement && other.driver == driver && == id;
String toString() {
var out = StringBuffer()..write(context);
if (locator is By) {
if (index == null) {
} else {
} else {
if (index != null) {
return out.toString();