or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-karma-viewport

A Karma plugin for testing responsive features and layout

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/karma-viewport@1.0.x

To install, run

npx @tessl/cli install tessl/npm-karma-viewport@1.0.0

0

# karma-viewport

1

2

karma-viewport is a Karma plugin for testing responsive features and layout. It provides a global `viewport` object that allows tests to dynamically resize iframe dimensions, configure named breakpoints for different screen sizes, and iterate through multiple viewport configurations during test execution.

3

4

## Package Information

5

6

- **Package Name**: karma-viewport

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install karma-viewport`

10

11

## Core Imports

12

13

karma-viewport is a Karma plugin, so it doesn't use traditional imports for the main functionality. Instead, you configure it in your Karma configuration file and access the global `viewport` object in your tests.

14

15

For advanced usage, you can import utility functions:

16

17

```typescript

18

import { range, Viewport, ViewportConfiguration } from "karma-viewport";

19

```

20

21

### Karma Configuration

22

23

```javascript

24

// karma.conf.js

25

module.exports = function(config) {

26

config.set({

27

frameworks: ["viewport"],

28

29

// Optional viewport configuration

30

viewport: {

31

context: "#context", // iframe selector (default)

32

breakpoints: [

33

{

34

name: "mobile",

35

size: { width: 320, height: 480 }

36

},

37

{

38

name: "tablet",

39

size: { width: 768, height: 1024 }

40

},

41

{

42

name: "desktop",

43

size: { width: 1440, height: 900 }

44

}

45

]

46

}

47

});

48

};

49

```

50

51

### TypeScript Support

52

53

```typescript

54

/// <reference types="karma-viewport" />

55

```

56

57

## Basic Usage

58

59

```javascript

60

// Test file - viewport is available globally

61

describe("responsive layout", () => {

62

63

beforeEach(() => {

64

viewport.reset(); // Reset to default size

65

});

66

67

it("should work on mobile", () => {

68

viewport.set(320, 480); // Set specific dimensions

69

// Test mobile layout...

70

});

71

72

it("should work on tablet", () => {

73

viewport.set("tablet"); // Use named breakpoint

74

// Test tablet layout...

75

});

76

77

it("should test all breakpoints", () => {

78

viewport.each(name => {

79

// This runs for each configured breakpoint

80

console.log(`Testing ${name} viewport`);

81

// Test layout for current viewport...

82

});

83

});

84

});

85

```

86

87

## Capabilities

88

89

### Viewport Resizing

90

91

Core functionality for setting viewport dimensions using either pixel values or named breakpoints.

92

93

```typescript { .api }

94

/**

95

* Set viewport to specific width and optional height

96

* @param width - Width in pixels

97

* @param height - Optional height in pixels

98

*/

99

set(width: number, height?: number): void;

100

101

/**

102

* Set viewport to named breakpoint

103

* @param breakpoint - Name of configured breakpoint

104

*/

105

set(breakpoint: string): void;

106

107

/**

108

* Reset viewport to default size (100% x 100%)

109

*/

110

reset(): void;

111

```

112

113

### Document Loading

114

115

Load external HTML documents into the viewport iframe for testing complete pages.

116

117

```typescript { .api }

118

/**

119

* Load and embed document into viewport

120

* @param url - URL of document to load

121

* @param cb - Optional callback function called after load completes

122

* @returns Promise resolving with no result when load completes

123

*/

124

load(url: string, cb?: () => void): Promise<void>;

125

```

126

127

### Scroll Control

128

129

Control the scroll position within the viewport iframe.

130

131

```typescript { .api }

132

/**

133

* Change viewport scroll offset

134

* @param x - Horizontal offset in pixels

135

* @param y - Vertical offset in pixels (default: 0)

136

*/

137

offset(x: number, y?: number): void;

138

```

139

140

### Breakpoint Iteration

141

142

Execute test code across multiple viewport sizes using configured breakpoints.

143

144

```typescript { .api }

145

/**

146

* Execute callback for all configured breakpoints

147

* @param cb - Callback function receiving breakpoint name

148

* @returns Promise if callback returns Promise, void otherwise

149

*/

150

each<T>(cb: ViewportCallback<T>): void | Promise<void>;

151

152

/**

153

* Execute callback for breakpoints starting from specified breakpoint

154

* @param first - First breakpoint name

155

* @param cb - Callback function receiving breakpoint name

156

* @returns Promise if callback returns Promise, void otherwise

157

*/

158

from<T>(first: string, cb: ViewportCallback<T>): void | Promise<void>;

159

160

/**

161

* Execute callback for breakpoints up to specified breakpoint

162

* @param last - Last breakpoint name

163

* @param cb - Callback function receiving breakpoint name

164

* @returns Promise if callback returns Promise, void otherwise

165

*/

166

to<T>(last: string, cb: ViewportCallback<T>): void | Promise<void>;

167

168

/**

169

* Execute callback for breakpoints between two specified breakpoints (inclusive)

170

* @param first - First breakpoint name

171

* @param last - Last breakpoint name

172

* @param cb - Callback function receiving breakpoint name

173

* @returns Promise if callback returns Promise, void otherwise

174

*/

175

between<T>(first: string, last: string, cb: ViewportCallback<T>): void | Promise<void>;

176

```

177

178

**Iteration Examples:**

179

180

```javascript

181

// Test all breakpoints

182

viewport.each(name => {

183

console.log(`Testing ${name}`);

184

// Test logic here

185

});

186

187

// Test from tablet onwards

188

viewport.from("tablet", name => {

189

// Tests tablet, desktop, etc.

190

});

191

192

// Test up to tablet

193

viewport.to("tablet", name => {

194

// Tests mobile, tablet

195

});

196

197

// Test specific range

198

viewport.between("tablet", "desktop", name => {

199

// Tests tablet, desktop

200

});

201

202

// Async support

203

viewport.each(async name => {

204

await someAsyncTest();

205

});

206

```

207

208

## Configuration

209

210

### Viewport Configuration

211

212

Configure the plugin behavior in your Karma configuration file.

213

214

```typescript { .api }

215

interface ViewportConfiguration {

216

/** Context element selector (default: "#context") */

217

context: string;

218

/** Array of named breakpoints */

219

breakpoints: ViewportBreakpoint[];

220

}

221

222

interface ViewportBreakpoint {

223

/** Breakpoint name */

224

name: string;

225

/** Viewport dimensions */

226

size: {

227

width: number;

228

height: number;

229

};

230

}

231

```

232

233

### Utility Functions

234

235

Utility functions exported by the karma-viewport module for advanced usage.

236

237

```typescript { .api }

238

/**

239

* Resolve relevant breakpoint range between two breakpoints

240

* @param breakpoints - Array of viewport breakpoints

241

* @param first - First breakpoint name

242

* @param last - Last breakpoint name (defaults to first)

243

* @returns Array of breakpoints in the specified range

244

* @throws ReferenceError if breakpoint name is invalid

245

*/

246

function range(

247

breakpoints: ViewportBreakpoint[],

248

first: string,

249

last?: string

250

): ViewportBreakpoint[];

251

```

252

253

## Types

254

255

```typescript { .api }

256

/**

257

* Callback function type for viewport iteration methods

258

*/

259

type ViewportCallback<T> = (breakpoint: string) => T;

260

261

/**

262

* Main Viewport class - available as global 'viewport' instance

263

*/

264

class Viewport {

265

/** Viewport configuration (read-only) */

266

readonly config: Readonly<ViewportConfiguration>;

267

/** Target iframe element */

268

readonly context: HTMLIFrameElement;

269

270

/**

271

* Create viewport resizer

272

* @param config - Viewport configuration

273

* @param parent - Initialization context (window)

274

* @throws ReferenceError if context selector doesn't match HTMLIFrameElement

275

*/

276

constructor(config: ViewportConfiguration, parent: Window);

277

278

/** Set viewport to specific dimensions */

279

set(width: number, height?: number): void;

280

/** Set viewport to named breakpoint */

281

set(breakpoint: string): void;

282

/** Reset viewport to default size */

283

reset(): void;

284

/** Load and embed document into viewport */

285

load(url: string, cb?: () => void): Promise<void>;

286

/** Change viewport scroll offset */

287

offset(x: number, y?: number): void;

288

/** Execute callback for all breakpoints */

289

each<T>(cb: ViewportCallback<T>): void | Promise<void>;

290

/** Execute callback starting from specified breakpoint */

291

from<T>(first: string, cb: ViewportCallback<T>): void | Promise<void>;

292

/** Execute callback up to specified breakpoint */

293

to<T>(last: string, cb: ViewportCallback<T>): void | Promise<void>;

294

/** Execute callback between two specified breakpoints */

295

between<T>(first: string, last: string, cb: ViewportCallback<T>): void | Promise<void>;

296

}

297

298

/**

299

* Global viewport instance declaration

300

*/

301

declare const viewport: Viewport;

302

```

303

304

## Error Handling

305

306

karma-viewport performs extensive parameter validation and throws specific errors:

307

308

```typescript { .api }

309

/**

310

* Common errors thrown by karma-viewport

311

*/

312

313

// Invalid breakpoint name in set(), each(), from(), to(), between() methods

314

ReferenceError: `Invalid breakpoint: ${inspect(name)}`

315

316

// Invalid context selector during initialization

317

ReferenceError: `No match for selector: ${inspect(config.context)}`

318

319

// Invalid viewport width (must be positive number)

320

TypeError: `Invalid breakpoint width: ${width}`

321

322

// Invalid viewport height (must be positive number or undefined)

323

TypeError: `Invalid breakpoint height: ${height}`

324

325

// Invalid viewport configuration object

326

TypeError: `Invalid viewport configuration: ${viewport}`

327

328

// Configuration validation errors (uses jsonschema validation)

329

TypeError: `Invalid viewport configuration: ${result.errors[0].stack}`

330

331

// Karma iframe configuration requirement

332

Error: "Invalid configuration: client.useIframe must be set to true or a different context selector must be given"

333

```

334

335

**Parameter Validation Rules:**

336

- Viewport width must be a positive number > 0

337

- Viewport height must be a positive number > 0 or undefined

338

- Breakpoint names must exist in the configuration

339

- Context selector must match an existing HTMLIFrameElement

340

- Configuration must pass JSON schema validation

341

342

## Browser Compatibility

343

344

- Chrome

345

- Firefox

346

- Safari

347

- Edge 13-15

348

- IE 9-11

349

350

**Requirements:**

351

- Karma must be configured with `client.useIframe: true` when using default context

352

- The context iframe element must exist in the test environment