or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdcommands.mdcontext.mdindex.mdinteractions.mdlocators.mdproviders.mdserver.mdutilities.md

locators.mddocs/

0

# Locators

1

2

Powerful element location system supporting CSS selectors, accessibility queries, chaining, and filtering for robust element targeting in browser tests.

3

4

## Capabilities

5

6

### Locator Interface

7

8

Main interface for locating and interacting with elements on the page.

9

10

```typescript { .api }

11

interface Locator {

12

/** Selector string that will be used to locate the element by the browser provider */

13

readonly selector: string;

14

15

// Selector methods

16

/** Creates a locator by ARIA role and optional attributes */

17

getByRole(role: string, options?: LocatorByRoleOptions): Locator;

18

/** Creates a locator by label text */

19

getByLabelText(text: string | RegExp, options?: LocatorOptions): Locator;

20

/** Creates a locator by alt text (matches any element with alt attribute) */

21

getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;

22

/** Creates a locator by placeholder text */

23

getByPlaceholder(text: string | RegExp, options?: LocatorOptions): Locator;

24

/** Creates a locator by text content (matches TextNode nodeValue or input value) */

25

getByText(text: string | RegExp, options?: LocatorOptions): Locator;

26

/** Creates a locator by title attribute */

27

getByTitle(text: string | RegExp, options?: LocatorOptions): Locator;

28

/** Creates a locator by test ID attribute (configurable via browser.locators.testIdAttribute) */

29

getByTestId(text: string | RegExp): Locator;

30

31

// Interaction methods

32

/** Click on an element */

33

click(options?: UserEventClickOptions): Promise<void>;

34

/** Triggers a double click event on an element */

35

dblClick(options?: UserEventDoubleClickOptions): Promise<void>;

36

/** Triggers a triple click event on an element */

37

tripleClick(options?: UserEventTripleClickOptions): Promise<void>;

38

/** Clears the input element content */

39

clear(options?: UserEventClearOptions): Promise<void>;

40

/** Moves the cursor position to the selected element */

41

hover(options?: UserEventHoverOptions): Promise<void>;

42

/** Moves the cursor to the document.body element */

43

unhover(options?: UserEventHoverOptions): Promise<void>;

44

/** Sets the value of the current input, textarea or contenteditable element */

45

fill(text: string, options?: UserEventFillOptions): Promise<void>;

46

/** Drags the current element to the target location */

47

dropTo(target: Locator, options?: UserEventDragAndDropOptions): Promise<void>;

48

/** Choose one or more values from a <select> element */

49

selectOptions(

50

values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[],

51

options?: UserEventSelectOptions

52

): Promise<void>;

53

/** Change a file input element to have the specified files */

54

upload(files: File | File[] | string | string[], options?: UserEventUploadOptions): Promise<void>;

55

56

// Screenshot

57

/** Make a screenshot of an element matching the locator */

58

screenshot(options?: LocatorScreenshotOptions): Promise<string>;

59

screenshot(options: Omit<LocatorScreenshotOptions, 'base64'> & { base64: true }): Promise<{

60

path: string;

61

base64: string;

62

}>;

63

64

// Query methods

65

/** Returns an element matching the selector (throws if not found) */

66

element(): Element;

67

/** Returns an array of elements matching the selector */

68

elements(): Element[];

69

/** Returns an element matching the selector or null if not found */

70

query(): Element | null;

71

/** Wraps an array of .elements() matching the selector in new Locators */

72

all(): Locator[];

73

74

// Filtering methods

75

/** Returns a locator for the nth element matching the selector */

76

nth(index: number): Locator;

77

/** Returns a locator for the first element matching the selector */

78

first(): Locator;

79

/** Returns a locator for the last element matching the selector */

80

last(): Locator;

81

/** Returns a locator that matches both the current locator and the provided locator */

82

and(locator: Locator): Locator;

83

/** Returns a locator that matches either the current locator or the provided locator */

84

or(locator: Locator): Locator;

85

/** Narrows existing locator according to the options */

86

filter(options: LocatorFilterOptions): Locator;

87

}

88

```

89

90

**Usage Examples:**

91

92

```typescript

93

import { page } from "@vitest/browser/context";

94

95

// Basic element location

96

const submitButton = page.getByRole("button", { name: "Submit" });

97

const usernameInput = page.getByLabelText("Username");

98

const errorMessage = page.getByText("Invalid credentials");

99

100

// Chaining locators

101

const formButton = page

102

.getByRole("form")

103

.getByRole("button", { name: "Submit" });

104

105

// Using filter options

106

const activeTab = page

107

.getByRole("tab")

108

.filter({ hasText: "Active" });

109

110

// Complex selectors

111

const specificItem = page

112

.getByRole("listitem")

113

.filter({ hasText: "Important" })

114

.first();

115

116

// Direct element access

117

const element = submitButton.element(); // throws if not found

118

const maybeElement = submitButton.query(); // returns null if not found

119

const allButtons = page.getByRole("button").elements();

120

```

121

122

### Selector Methods

123

124

Individual selector methods for different element targeting strategies.

125

126

#### getByRole

127

128

```typescript { .api }

129

/**

130

* Creates a locator by ARIA role, ARIA attributes and accessible name

131

* @param role - ARIA role or custom role string

132

* @param options - Role-specific options for filtering

133

* @returns Locator for elements matching the role criteria

134

*/

135

getByRole(role: string, options?: LocatorByRoleOptions): Locator;

136

137

interface LocatorByRoleOptions extends LocatorOptions {

138

/** Should checked elements be included or not */

139

checked?: boolean;

140

/** Should disabled elements be included or not */

141

disabled?: boolean;

142

/** Should expanded elements be included or not */

143

expanded?: boolean;

144

/** Should normally excluded elements be queried */

145

includeHidden?: boolean;

146

/** Number attribute for heading, listitem, row, treeitem roles */

147

level?: number;

148

/** Accessible name to match */

149

name?: string | RegExp;

150

/** Should pressed elements be included or not */

151

pressed?: boolean;

152

/** Should selected elements be included or not */

153

selected?: boolean;

154

}

155

```

156

157

**Usage Examples:**

158

159

```typescript

160

// Basic roles

161

page.getByRole("button");

162

page.getByRole("textbox");

163

page.getByRole("link");

164

165

// With name matching

166

page.getByRole("button", { name: "Submit Form" });

167

page.getByRole("button", { name: /submit/i });

168

169

// With state filtering

170

page.getByRole("checkbox", { checked: true });

171

page.getByRole("button", { disabled: false });

172

page.getByRole("tab", { selected: true });

173

174

// With level (for headings)

175

page.getByRole("heading", { level: 2 });

176

```

177

178

#### getByText

179

180

```typescript { .api }

181

/**

182

* Creates a locator by text content. Matches against TextNode's nodeValue

183

* or input's value if type is button or reset. Always normalizes whitespace.

184

* @param text - Text to search for (string or RegExp)

185

* @param options - Text matching options

186

* @returns Locator for elements containing the text

187

*/

188

getByText(text: string | RegExp, options?: LocatorOptions): Locator;

189

```

190

191

**Usage Examples:**

192

193

```typescript

194

// Exact text matching

195

page.getByText("Welcome back");

196

197

// Partial text matching (default)

198

page.getByText("Welcome"); // matches "Welcome back"

199

200

// Exact matching

201

page.getByText("Welcome", { exact: true }); // only matches "Welcome"

202

203

// Regular expressions

204

page.getByText(/welcome/i); // case insensitive

205

page.getByText(/error.*occurred/); // pattern matching

206

```

207

208

#### getByLabelText

209

210

```typescript { .api }

211

/**

212

* Creates a locator by label text association. Finds form controls

213

* associated with labels containing the specified text.

214

* @param text - Label text to search for

215

* @param options - Label matching options

216

* @returns Locator for form controls with matching labels

217

*/

218

getByLabelText(text: string | RegExp, options?: LocatorOptions): Locator;

219

```

220

221

**Usage Examples:**

222

223

```typescript

224

// Form inputs with labels

225

page.getByLabelText("Email address");

226

page.getByLabelText("Password");

227

page.getByLabelText("Remember me"); // checkbox

228

229

// Partial matching

230

page.getByLabelText("Email"); // matches "Email address"

231

232

// Case insensitive with RegExp

233

page.getByLabelText(/email/i);

234

```

235

236

#### getByTestId

237

238

```typescript { .api }

239

/**

240

* Creates a locator by test ID attribute. Uses the configured test ID attribute

241

* from browser.locators.testIdAttribute (default: "data-testid").

242

* @param testId - Test ID value to match

243

* @returns Locator for elements with matching test ID

244

*/

245

getByTestId(testId: string | RegExp): Locator;

246

```

247

248

**Usage Examples:**

249

250

```typescript

251

// Standard test IDs

252

page.getByTestId("submit-button");

253

page.getByTestId("user-profile");

254

255

// Pattern matching

256

page.getByTestId(/button-\d+/);

257

258

// Custom test ID attribute (configured in vitest.config.js)

259

// browser: { locators: { testIdAttribute: "data-cy" } }

260

page.getByTestId("login-form"); // looks for data-cy="login-form"

261

```

262

263

### Filtering and Chaining

264

265

Methods for refining and combining locators.

266

267

#### Filter Method

268

269

```typescript { .api }

270

/**

271

* Narrows existing locator according to filter criteria

272

* @param options - Filter criteria

273

* @returns New locator with applied filters

274

*/

275

filter(options: LocatorFilterOptions): Locator;

276

277

interface LocatorFilterOptions {

278

/** Text content that element should have */

279

hasText?: string | RegExp;

280

/** Text content that element should NOT have */

281

hasNotText?: string | RegExp;

282

/** Child locator that element should contain */

283

has?: Locator;

284

/** Child locator that element should NOT contain */

285

hasNot?: Locator;

286

}

287

```

288

289

**Usage Examples:**

290

291

```typescript

292

// Filter by text content

293

page.getByRole("listitem").filter({ hasText: "Active" });

294

page.getByRole("button").filter({ hasNotText: "Disabled" });

295

296

// Filter by child elements

297

page.getByRole("article").filter({

298

has: page.getByRole("button", { name: "Edit" })

299

});

300

301

// Combined filters

302

page.getByRole("row").filter({

303

hasText: "John",

304

has: page.getByRole("cell", { name: "Active" })

305

});

306

```

307

308

#### Logical Operators

309

310

```typescript { .api }

311

/**

312

* Returns a locator that matches both the current locator and the provided locator

313

*/

314

and(locator: Locator): Locator;

315

316

/**

317

* Returns a locator that matches either the current locator or the provided locator

318

*/

319

or(locator: Locator): Locator;

320

```

321

322

**Usage Examples:**

323

324

```typescript

325

// Element must match both conditions

326

const specificButton = page

327

.getByRole("button")

328

.and(page.getByText("Submit"));

329

330

// Element can match either condition

331

const anyInput = page

332

.getByRole("textbox")

333

.or(page.getByRole("searchbox"));

334

```

335

336

#### Position Methods

337

338

```typescript { .api }

339

/**

340

* Returns a locator for the nth element matching the selector

341

*/

342

nth(index: number): Locator;

343

344

/**

345

* Returns a locator for the first element matching the selector

346

*/

347

first(): Locator;

348

349

/**

350

* Returns a locator for the last element matching the selector

351

*/

352

last(): Locator;

353

```

354

355

**Usage Examples:**

356

357

```typescript

358

// Positional selection

359

page.getByRole("listitem").first();

360

page.getByRole("listitem").last();

361

page.getByRole("listitem").nth(2); // third item (0-indexed)

362

page.getByRole("listitem").nth(-1); // last item

363

364

// Multiple elements

365

const allItems = page.getByRole("listitem").all();

366

for (const item of allItems) {

367

await item.click();

368

}

369

```

370

371

### Query Methods

372

373

Methods for retrieving actual DOM elements from locators.

374

375

```typescript { .api }

376

/**

377

* Returns an element matching the selector. Throws if not found or multiple elements match.

378

*/

379

element(): Element;

380

381

/**

382

* Returns an array of elements matching the selector. Returns empty array if none found.

383

*/

384

elements(): Element[];

385

386

/**

387

* Returns an element matching the selector or null if not found. Throws if multiple elements match.

388

*/

389

query(): Element | null;

390

391

/**

392

* Wraps an array of elements matching the selector in new Locators

393

*/

394

all(): Locator[];

395

```

396

397

**Usage Examples:**

398

399

```typescript

400

import { page } from "@vitest/browser/context";

401

402

// Get single element (throws if not found)

403

const button = page.getByRole("button").element();

404

button.click(); // direct DOM API usage

405

406

// Safe element access

407

const maybeButton = page.getByRole("button").query();

408

if (maybeButton) {

409

maybeButton.click();

410

}

411

412

// Get all matching elements

413

const inputs = page.getByRole("textbox").elements();

414

inputs.forEach(input => {

415

console.log(input.value);

416

});

417

418

// Get locators for all elements

419

const itemLocators = page.getByRole("listitem").all();

420

for (const locator of itemLocators) {

421

await locator.click(); // use locator API

422

}

423

```

424

425

## Types

426

427

Core locator option interfaces:

428

429

```typescript { .api }

430

interface LocatorOptions {

431

/** Whether to find an exact match: case-sensitive and whole-string */

432

exact?: boolean;

433

}

434

435

interface LocatorFilterOptions {

436

/** Text content that element should have */

437

hasText?: string | RegExp;

438

/** Text content that element should NOT have */

439

hasNotText?: string | RegExp;

440

/** Child locator that element should contain */

441

has?: Locator;

442

/** Child locator that element should NOT contain */

443

hasNot?: Locator;

444

}

445

446

interface LocatorScreenshotOptions extends Omit<ScreenshotOptions, 'element'> {

447

path?: string;

448

base64?: boolean;

449

save?: boolean;

450

}

451

```