Skip to content

Commit b728df4

Browse files
denrasemarandaneto
andauthored
Feat: Screenshot Attachment (#1088)
Co-authored-by: Manoel Aranda Neto <[email protected]> Co-authored-by: Manoel Aranda Neto <[email protected]>
1 parent 3a69405 commit b728df4

24 files changed

+565
-20
lines changed

.github/workflows/flutter.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ jobs:
8181
if: runner.os == 'Linux'
8282
run: |
8383
cd flutter
84-
flutter test --platform chrome --test-randomize-ordering-seed=random
84+
flutter test --platform chrome --test-randomize-ordering-seed=random --exclude-tags canvasKit
85+
flutter test --platform chrome --test-randomize-ordering-seed=random --tags canvasKit --web-renderer canvaskit
8586
8687
- name: Test VM with coverage
8788
if: runner.os != 'macOS'

.github/workflows/web-example-ghpages.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ jobs:
1818
with:
1919
workingDir: flutter/example
2020
customArgs: --source-maps
21+
webRenderer: canvaskit
2122

2223
- name: Upload source maps
2324
run: |

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## Unreleased
44

5+
### Features
6+
7+
- Feat: Screenshot Attachment ([#1088](https://github.com/getsentry/sentry-dart/pull/1088))
8+
59
### Fixes
610

711
- Merging of integrations and packages ([#1111](https://github.com/getsentry/sentry-dart/pull/1111))

dart/lib/sentry_private.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// attachments
2+
// ignore: invalid_export_of_internal_element
3+
export 'src/sentry_client_attachment_processor.dart';

dart/lib/src/sentry_attachment/sentry_attachment.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ class SentryAttachment {
8383
addToTransactions: addToTransactions,
8484
);
8585

86+
SentryAttachment.fromScreenshotData(Uint8List bytes)
87+
: this.fromUint8List(bytes, 'screenshot.png',
88+
contentType: 'image/png',
89+
attachmentType: SentryAttachment.typeAttachmentDefault);
90+
8691
/// Attachment type.
8792
/// Should be one of types given in [AttachmentType].
8893
final String attachmentType;

dart/lib/src/sentry_client.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import 'sentry_envelope.dart';
1919
import 'client_reports/client_report_recorder.dart';
2020
import 'client_reports/discard_reason.dart';
2121
import 'transport/data_category.dart';
22+
import 'sentry_client_attachment_processor.dart';
2223

2324
/// Default value for [User.ipAddress]. It gets set when an event does not have
2425
/// a user and IP address. Only applies if [SentryOptions.sendDefaultPii] is set
@@ -37,6 +38,9 @@ class SentryClient {
3738

3839
SentryStackTraceFactory get _stackTraceFactory => _options.stackTraceFactory;
3940

41+
SentryClientAttachmentProcessor get _clientAttachmentProcessor =>
42+
_options.clientAttachmentProcessor;
43+
4044
/// Instantiates a client using [SentryOptions]
4145
factory SentryClient(SentryOptions options) {
4246
if (options.sendClientReports) {
@@ -130,12 +134,15 @@ class SentryClient {
130134
preparedEvent = _eventWithRemovedBreadcrumbsIfHandled(preparedEvent);
131135
}
132136

137+
final attachments = await _clientAttachmentProcessor.processAttachments(
138+
scope?.attachments ?? [], preparedEvent);
139+
133140
final envelope = SentryEnvelope.fromEvent(
134141
preparedEvent,
135142
_options.sdk,
136143
dsn: _options.dsn,
137144
traceContext: scope?.span?.traceContext(),
138-
attachments: scope?.attachments,
145+
attachments: attachments.isNotEmpty ? attachments : null,
139146
);
140147

141148
final id = await captureEnvelope(envelope);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import 'dart:async';
2+
3+
import 'package:meta/meta.dart';
4+
5+
import './sentry_attachment/sentry_attachment.dart';
6+
import './protocol/sentry_event.dart';
7+
8+
@internal
9+
class SentryClientAttachmentProcessor {
10+
Future<List<SentryAttachment>> processAttachments(
11+
List<SentryAttachment> attachments, SentryEvent event) async {
12+
return attachments;
13+
}
14+
}

dart/lib/src/sentry_options.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:meta/meta.dart';
55
import 'package:http/http.dart';
66

77
import '../sentry.dart';
8+
import '../sentry_private.dart';
89
import 'client_reports/client_report_recorder.dart';
910
import 'client_reports/noop_client_report_recorder.dart';
1011
import 'sentry_exception_factory.dart';
@@ -354,6 +355,10 @@ class SentryOptions {
354355
@internal
355356
late SentryStackTraceFactory stackTraceFactory =
356357
SentryStackTraceFactory(this);
358+
359+
@internal
360+
late SentryClientAttachmentProcessor clientAttachmentProcessor =
361+
SentryClientAttachmentProcessor();
357362
}
358363

359364
/// This function is called with an SDK specific event object and can return a modified event

dart/test/mocks.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:async';
22

33
import 'package:sentry/sentry.dart';
4+
import 'package:sentry/sentry_private.dart';
45
import 'package:sentry/src/transport/rate_limiter.dart';
56

67
final fakeDsn = 'https://[email protected]/1234567';
@@ -160,3 +161,23 @@ class MockRateLimiter implements RateLimiter {
160161
this.errorCode = errorCode;
161162
}
162163
}
164+
165+
enum MockAttachmentProcessorMode { filter, add }
166+
167+
/// Filtering out all attachments.
168+
class MockAttachmentProcessor implements SentryClientAttachmentProcessor {
169+
MockAttachmentProcessorMode mode;
170+
171+
MockAttachmentProcessor(this.mode);
172+
173+
@override
174+
Future<List<SentryAttachment>> processAttachments(
175+
List<SentryAttachment> attachments, SentryEvent event) async {
176+
switch (mode) {
177+
case MockAttachmentProcessorMode.filter:
178+
return <SentryAttachment>[];
179+
case MockAttachmentProcessorMode.add:
180+
return <SentryAttachment>[SentryAttachment.fromIntList([], "added")];
181+
}
182+
}
183+
}

dart/test/sentry_attachment_test.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,15 @@ void main() {
159159

160160
expect(attachment.addToTransactions, true);
161161
});
162+
163+
test('fromScreenshotData', () async {
164+
final attachment =
165+
SentryAttachment.fromScreenshotData(Uint8List.fromList([0, 0, 0, 0]));
166+
expect(attachment.attachmentType, SentryAttachment.typeAttachmentDefault);
167+
expect(attachment.contentType, 'image/png');
168+
expect(attachment.filename, 'screenshot.png');
169+
expect(attachment.addToTransactions, false);
170+
});
162171
});
163172
}
164173

0 commit comments

Comments
 (0)