diff --git a/backend/pkg/messages/filters.go b/backend/pkg/messages/filters.go index c1a28eb55..5682b2463 100644 --- a/backend/pkg/messages/filters.go +++ b/backend/pkg/messages/filters.go @@ -2,7 +2,11 @@ package messages func IsReplayerType(id int) bool { +<<<<<<< HEAD return 1 != id && 3 != id && 17 != id && 23 != id && 24 != id && 25 != id && 26 != id && 27 != id && 28 != id && 29 != id && 30 != id && 31 != id && 32 != id && 33 != id && 35 != id && 42 != id && 52 != id && 56 != id && 62 != id && 63 != id && 64 != id && 66 != id && 78 != id && 80 != id && 81 != id && 82 != id && 125 != id && 126 != id && 127 != id && 112 != id && 107 != id && 91 != id && 92 != id && 94 != id && 95 != id && 97 != id && 98 != id && 99 != id && 101 != id && 104 != id && 110 != id && 111 != id +======= + return 1 != id && 3 != id && 17 != id && 23 != id && 24 != id && 25 != id && 26 != id && 27 != id && 28 != id && 29 != id && 30 != id && 31 != id && 32 != id && 33 != id && 35 != id && 42 != id && 52 != id && 56 != id && 62 != id && 63 != id && 64 != id && 66 != id && 78 != id && 80 != id && 81 != id && 82 != id && 115 != id && 125 != id && 126 != id && 127 != id && 107 != id && 91 != id && 92 != id && 94 != id && 95 != id && 97 != id && 98 != id && 99 != id && 101 != id && 104 != id && 110 != id && 111 != id +>>>>>>> 3e1b8c39f (change(tracker): add nodes drop message) } func IsIOSType(id int) bool { diff --git a/backend/pkg/messages/messages.go b/backend/pkg/messages/messages.go index bff0daea0..9890c5fff 100644 --- a/backend/pkg/messages/messages.go +++ b/backend/pkg/messages/messages.go @@ -79,6 +79,7 @@ const ( MsgBatchMeta = 80 MsgBatchMetadata = 81 MsgPartitionedMessage = 82 + MsgRemovedNodesCount = 115 MsgIssueEvent = 125 MsgSessionEnd = 126 MsgSessionSearch = 127 @@ -2029,6 +2030,29 @@ func (msg *PartitionedMessage) TypeID() int { return 82 } +type RemovedNodesCount struct { + message + NodesCount uint64 + DOMDropped bool +} + +func (msg *RemovedNodesCount) Encode() []byte { + buf := make([]byte, 21) + buf[0] = 115 + p := 1 + p = WriteUint(msg.NodesCount, buf, p) + p = WriteBoolean(msg.DOMDropped, buf, p) + return buf[:p] +} + +func (msg *RemovedNodesCount) Decode() Message { + return msg +} + +func (msg *RemovedNodesCount) TypeID() int { + return 115 +} + type IssueEvent struct { message MessageID uint64 diff --git a/ee/connectors/msgcodec/messages.py b/ee/connectors/msgcodec/messages.py index 91fb36a63..16763fe59 100644 --- a/ee/connectors/msgcodec/messages.py +++ b/ee/connectors/msgcodec/messages.py @@ -708,6 +708,14 @@ class PartitionedMessage(Message): self.part_total = part_total +class RemovedNodesCount(Message): + __id__ = 115 + + def __init__(self, nodes_count, dom_dropped): + self.nodes_count = nodes_count + self.dom_dropped = dom_dropped + + class IssueEvent(Message): __id__ = 125 diff --git a/ee/connectors/msgcodec/msgcodec.py b/ee/connectors/msgcodec/msgcodec.py index 02b5b5557..40e2ef648 100644 --- a/ee/connectors/msgcodec/msgcodec.py +++ b/ee/connectors/msgcodec/msgcodec.py @@ -630,6 +630,12 @@ class MessageCodec(Codec): part_total=self.read_uint(reader) ) + if message_id == 115: + return RemovedNodesCount( + nodes_count=self.read_uint(reader), + dom_dropped=self.read_boolean(reader) + ) + if message_id == 125: return IssueEvent( message_id=self.read_uint(reader), diff --git a/mobs/messages.rb b/mobs/messages.rb index 99e917778..88ae76f20 100644 --- a/mobs/messages.rb +++ b/mobs/messages.rb @@ -448,6 +448,31 @@ end # 90-111 reserved iOS + +message 112, 'InputChange', :replayer => false do + uint 'ID' + string 'Value' + boolean 'ValueMasked' + string 'Label' + int 'HesitationTime' + int 'InputDuration' +end + +message 113, 'SelectionChange' do + uint 'SelectionStart' + uint 'SelectionEnd' + string 'Selection' +end + +message 114, 'MouseThrashing' do + uint 'Timestamp' +end + +message 115, 'RemovedNodesCount', :replayer => false do + uint 'NodesCount' + boolean 'DOMDropped' +end + ## Backend-only message 125, 'IssueEvent', :replayer => false, :tracker => false do uint 'MessageID' @@ -468,22 +493,3 @@ message 127, 'SessionSearch', :tracker => false, :replayer => false do end # since tracker 4.1.10 - -message 112, 'InputChange', :replayer => false do - uint 'ID' - string 'Value' - boolean 'ValueMasked' - string 'Label' - int 'HesitationTime' - int 'InputDuration' -end - -message 113, 'SelectionChange' do - uint 'SelectionStart' - uint 'SelectionEnd' - string 'Selection' -end - -message 114, 'MouseThrashing' do - uint 'Timestamp' -end \ No newline at end of file diff --git a/tracker/tracker/src/main/app/nodes.ts b/tracker/tracker/src/main/app/nodes.ts index 387679380..b94823cce 100644 --- a/tracker/tracker/src/main/app/nodes.ts +++ b/tracker/tracker/src/main/app/nodes.ts @@ -26,6 +26,10 @@ export default class Nodes { listeners.push([type, listener, useCapture]) } + getNodesCount() { + return this.nodes.length + } + registerNode(node: Node): [/*id:*/ number, /*isNew:*/ boolean] { let id: number = (node as any)[this.node_id] const isNew = id === undefined diff --git a/tracker/tracker/src/main/app/observer/observer.ts b/tracker/tracker/src/main/app/observer/observer.ts index 9e93dde2d..5972e9850 100644 --- a/tracker/tracker/src/main/app/observer/observer.ts +++ b/tracker/tracker/src/main/app/observer/observer.ts @@ -8,6 +8,7 @@ import { CreateElementNode, MoveNode, RemoveNode, + RemovedNodesCount, } from '../messages.gen.js' import App from '../index.js' import { @@ -216,6 +217,8 @@ export default abstract class Observer { } private unbindTree(node: Node) { + let removed = 0 + const nodesCount = this.app.nodes.getNodesCount() const id = this.app.nodes.unregisterNode(node) if (id !== undefined && this.recents.get(id) === RecentsType.Removed) { // Sending RemoveNode only for parent to maintain @@ -235,9 +238,10 @@ export default abstract class Observer { false, ) while (walker.nextNode()) { + removed += 1 this.app.nodes.unregisterNode(walker.currentNode) } - // MBTODO: count and send RemovedNodesCount (for the page crash detection in heuristics) + this.app.send(RemovedNodesCount(removed, removed / nodesCount > 0.5)) } }