From 8716b2ae2a1d9144ae7cdaf67fcf20c85785a89d Mon Sep 17 00:00:00 2001 From: Florencia Acosta Date: Thu, 25 Jul 2024 17:29:43 -0300 Subject: [PATCH] feat(instrumentation-react-native-navigation) addinv 'view' as prefix for attributes + cleaning up tests --- package-lock.json | 155 +++++++++--------- .../README.md | 7 +- .../src/utils/spanCreator.ts | 13 +- .../test/NativeNavigationTracker.test.tsx | 68 +++++--- .../test/NavigationTracker.test.tsx | 55 ++++--- .../test/hooks/useProvider.ts | 5 +- 6 files changed, 165 insertions(+), 138 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac841335b8..a550e5f5c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -283,7 +283,7 @@ }, "metapackages/auto-configuration-propagators": { "name": "@opentelemetry/auto-configuration-propagators", - "version": "0.2.0", + "version": "0.1.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.25.1", @@ -320,14 +320,14 @@ "@opentelemetry/instrumentation": "^0.52.0", "@opentelemetry/instrumentation-amqplib": "^0.41.0", "@opentelemetry/instrumentation-aws-lambda": "^0.43.0", - "@opentelemetry/instrumentation-aws-sdk": "^0.43.1", + "@opentelemetry/instrumentation-aws-sdk": "^0.43.0", "@opentelemetry/instrumentation-bunyan": "^0.40.0", "@opentelemetry/instrumentation-cassandra-driver": "^0.40.0", "@opentelemetry/instrumentation-connect": "^0.38.0", "@opentelemetry/instrumentation-cucumber": "^0.8.0", "@opentelemetry/instrumentation-dataloader": "^0.11.0", "@opentelemetry/instrumentation-dns": "^0.38.0", - "@opentelemetry/instrumentation-express": "^0.41.1", + "@opentelemetry/instrumentation-express": "^0.41.0", "@opentelemetry/instrumentation-fastify": "^0.38.0", "@opentelemetry/instrumentation-fs": "^0.14.0", "@opentelemetry/instrumentation-generic-pool": "^0.38.0", @@ -337,7 +337,7 @@ "@opentelemetry/instrumentation-http": "^0.52.0", "@opentelemetry/instrumentation-ioredis": "^0.42.0", "@opentelemetry/instrumentation-kafkajs": "^0.2.0", - "@opentelemetry/instrumentation-knex": "^0.39.0", + "@opentelemetry/instrumentation-knex": "^0.38.0", "@opentelemetry/instrumentation-koa": "^0.42.0", "@opentelemetry/instrumentation-lru-memoizer": "^0.39.0", "@opentelemetry/instrumentation-memcached": "^0.38.0", @@ -14913,9 +14913,9 @@ } }, "node_modules/@testing-library/dom": { - "version": "10.3.2", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.3.2.tgz", - "integrity": "sha512-0bxIdP9mmPiOJ6wHLj8bdJRq+51oddObeCGdEf6PNEhYd93ZYAN+lPRnEOVFtheVwDM7+p+tza3LAQgp0PTudg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "dev": true, "peer": true, "dependencies": { @@ -19359,9 +19359,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001642", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz", - "integrity": "sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==", + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", "dev": true, "funding": [ { @@ -20977,9 +20977,9 @@ } }, "node_modules/dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", + "version": "1.11.12", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz", + "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==", "dev": true, "peer": true }, @@ -21515,9 +21515,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.829", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.829.tgz", - "integrity": "sha512-5qp1N2POAfW0u1qGAxXEtz6P7bO1m6gpZr5hdf5ve6lxpLM7MpiM4jIPz7xcrNlClQMafbyUDDWjlIQZ1Mw0Rw==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.2.tgz", + "integrity": "sha512-kc4r3U3V3WLaaZqThjYz/Y6z8tJe+7K0bbjUVo3i+LWIypVdMx5nXCkwRe6SWbY6ILqLdc1rKcKmr3HoH7wjSQ==", "dev": true }, "node_modules/emoji-regex": { @@ -23609,9 +23609,9 @@ "peer": true }, "node_modules/flow-parser": { - "version": "0.240.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.240.0.tgz", - "integrity": "sha512-p9xnhi64bGDZF+QhZ9D3Iqh8ILS0K+6KHnted0kyo0WHXcPvCrTvVfLFLdTU4OhmN3e4E9w1ikXiZjwro60nkw==", + "version": "0.241.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.241.0.tgz", + "integrity": "sha512-82yKXpz7iWknWFsognZUf5a6mBQLnVrYoYSU9Nbu7FTOpKlu3v9ehpiI9mYXuaIO3J0ojX1b83M/InXvld9HUw==", "dev": true, "peer": true, "engines": { @@ -24899,9 +24899,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "dependencies": { "agent-base": "^7.0.2", "debug": "4" @@ -26951,9 +26951,9 @@ } }, "node_modules/jsdom": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz", - "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==", + "version": "24.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz", + "integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==", "dev": true, "dependencies": { "cssstyle": "^4.0.1", @@ -26962,11 +26962,11 @@ "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.4", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.10", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.4", @@ -26975,7 +26975,7 @@ "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.17.0", + "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "engines": { @@ -35849,16 +35849,16 @@ } }, "node_modules/react-dom": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0.tgz", - "integrity": "sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "peer": true, "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.21.0" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^18.0.0" + "react": "^18.3.1" } }, "node_modules/react-is": { @@ -37231,9 +37231,9 @@ } }, "node_modules/scheduler": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", - "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "peer": true, "dependencies": { "loose-envify": "^1.1.0" @@ -42882,8 +42882,7 @@ "dev": true }, "plugins/node/instrumentation-react-native-navigation": { - "name": "@opentelemetry/instrumentation-react-native-navigation", - "version": "0.39.0", + "version": "0.1.0", "hasInstallScript": true, "license": "Apache-2.0", "devDependencies": { @@ -42917,7 +42916,7 @@ }, "peerDependencies": { "@opentelemetry/api": "^1.3.0", - "react-dom": "18.0.0" + "react-dom": ">=18.0.0" } }, "plugins/node/instrumentation-react-native-navigation/node_modules/@babel/core": { @@ -44090,7 +44089,7 @@ }, "plugins/node/opentelemetry-instrumentation-aws-sdk": { "name": "@opentelemetry/instrumentation-aws-sdk", - "version": "0.43.1", + "version": "0.43.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.8.0", @@ -44285,7 +44284,7 @@ }, "plugins/node/opentelemetry-instrumentation-express": { "name": "@opentelemetry/instrumentation-express", - "version": "0.41.1", + "version": "0.41.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "^1.8.0", @@ -44536,7 +44535,7 @@ }, "plugins/node/opentelemetry-instrumentation-knex": { "name": "@opentelemetry/instrumentation-knex", - "version": "0.39.0", + "version": "0.38.0", "license": "Apache-2.0", "dependencies": { "@opentelemetry/instrumentation": "^0.52.0", @@ -56509,14 +56508,14 @@ "@opentelemetry/instrumentation": "^0.52.0", "@opentelemetry/instrumentation-amqplib": "^0.41.0", "@opentelemetry/instrumentation-aws-lambda": "^0.43.0", - "@opentelemetry/instrumentation-aws-sdk": "^0.43.1", + "@opentelemetry/instrumentation-aws-sdk": "^0.43.0", "@opentelemetry/instrumentation-bunyan": "^0.40.0", "@opentelemetry/instrumentation-cassandra-driver": "^0.40.0", "@opentelemetry/instrumentation-connect": "^0.38.0", "@opentelemetry/instrumentation-cucumber": "^0.8.0", "@opentelemetry/instrumentation-dataloader": "^0.11.0", "@opentelemetry/instrumentation-dns": "^0.38.0", - "@opentelemetry/instrumentation-express": "^0.41.1", + "@opentelemetry/instrumentation-express": "^0.41.0", "@opentelemetry/instrumentation-fastify": "^0.38.0", "@opentelemetry/instrumentation-fs": "^0.14.0", "@opentelemetry/instrumentation-generic-pool": "^0.38.0", @@ -56526,7 +56525,7 @@ "@opentelemetry/instrumentation-http": "^0.52.0", "@opentelemetry/instrumentation-ioredis": "^0.42.0", "@opentelemetry/instrumentation-kafkajs": "^0.2.0", - "@opentelemetry/instrumentation-knex": "^0.39.0", + "@opentelemetry/instrumentation-knex": "^0.38.0", "@opentelemetry/instrumentation-koa": "^0.42.0", "@opentelemetry/instrumentation-lru-memoizer": "^0.39.0", "@opentelemetry/instrumentation-memcached": "^0.38.0", @@ -64800,9 +64799,9 @@ "dev": true }, "@testing-library/dom": { - "version": "10.3.2", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.3.2.tgz", - "integrity": "sha512-0bxIdP9mmPiOJ6wHLj8bdJRq+51oddObeCGdEf6PNEhYd93ZYAN+lPRnEOVFtheVwDM7+p+tza3LAQgp0PTudg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz", + "integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==", "dev": true, "peer": true, "requires": { @@ -68598,9 +68597,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001642", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001642.tgz", - "integrity": "sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==", + "version": "1.0.30001643", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz", + "integrity": "sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==", "dev": true }, "capital-case": { @@ -69875,9 +69874,9 @@ "dev": true }, "dayjs": { - "version": "1.11.11", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", - "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", + "version": "1.11.12", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz", + "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==", "dev": true, "peer": true }, @@ -70286,9 +70285,9 @@ } }, "electron-to-chromium": { - "version": "1.4.829", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.829.tgz", - "integrity": "sha512-5qp1N2POAfW0u1qGAxXEtz6P7bO1m6gpZr5hdf5ve6lxpLM7MpiM4jIPz7xcrNlClQMafbyUDDWjlIQZ1Mw0Rw==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.2.tgz", + "integrity": "sha512-kc4r3U3V3WLaaZqThjYz/Y6z8tJe+7K0bbjUVo3i+LWIypVdMx5nXCkwRe6SWbY6ILqLdc1rKcKmr3HoH7wjSQ==", "dev": true }, "emoji-regex": { @@ -71928,9 +71927,9 @@ "peer": true }, "flow-parser": { - "version": "0.240.0", - "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.240.0.tgz", - "integrity": "sha512-p9xnhi64bGDZF+QhZ9D3Iqh8ILS0K+6KHnted0kyo0WHXcPvCrTvVfLFLdTU4OhmN3e4E9w1ikXiZjwro60nkw==", + "version": "0.241.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.241.0.tgz", + "integrity": "sha512-82yKXpz7iWknWFsognZUf5a6mBQLnVrYoYSU9Nbu7FTOpKlu3v9ehpiI9mYXuaIO3J0ojX1b83M/InXvld9HUw==", "dev": true, "peer": true }, @@ -72911,9 +72910,9 @@ } }, "https-proxy-agent": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", - "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", "requires": { "agent-base": "^7.0.2", "debug": "4" @@ -74442,9 +74441,9 @@ } }, "jsdom": { - "version": "24.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz", - "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==", + "version": "24.1.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.1.tgz", + "integrity": "sha512-5O1wWV99Jhq4DV7rCLIoZ/UIhyQeDR7wHVyZAHAshbrvZsLs+Xzz7gtwnlJTJDjleiTKh54F4dXrX70vJQTyJQ==", "dev": true, "requires": { "cssstyle": "^4.0.1", @@ -74453,11 +74452,11 @@ "form-data": "^4.0.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.4", + "https-proxy-agent": "^7.0.5", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.10", + "nwsapi": "^2.2.12", "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.0", + "rrweb-cssom": "^0.7.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^4.1.4", @@ -74466,7 +74465,7 @@ "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^14.0.0", - "ws": "^8.17.0", + "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, "dependencies": { @@ -81473,13 +81472,13 @@ } }, "react-dom": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0.tgz", - "integrity": "sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "peer": true, "requires": { "loose-envify": "^1.1.0", - "scheduler": "^0.21.0" + "scheduler": "^0.23.2" } }, "react-is": { @@ -82532,9 +82531,9 @@ } }, "scheduler": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", - "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "peer": true, "requires": { "loose-envify": "^1.1.0" diff --git a/plugins/node/instrumentation-react-native-navigation/README.md b/plugins/node/instrumentation-react-native-navigation/README.md index a5274d7b0d..a079c20c20 100644 --- a/plugins/node/instrumentation-react-native-navigation/README.md +++ b/plugins/node/instrumentation-react-native-navigation/README.md @@ -141,8 +141,9 @@ For instance, when the application starts and the user navigates to a new sectio timestamp: 1718975153696000, duration: 252.375, attributes: { - launch: true, - 'state.end': 'active', + 'view.launch': true, + 'view.state.end': 'active', + 'view.name': 'Home', 'static.attribute.key': 'static.attribute.value', 'custom.attribute.key': 'custom.attribute.value' }, @@ -152,7 +153,7 @@ For instance, when the application starts and the user navigates to a new sectio } ``` -If you dig into the attributes, `launch` refers to the moment the app is launched. It will be `true` only the first time the app mounts. Changing the status between background/foreground won't modify this attribute. For this case the `state.end` is used, and it can contain two possible values: `active` and `background`. +If you dig into the attributes, `view.launch` refers to the moment the app is launched. It will be `true` only the first time the app mounts. Changing the status between background/foreground won't modify this attribute. For this case the `view.state.end` is used, and it can contain two possible values: `active` and `background`. Both components ( and ) are built on top of third-party libraries and function according to the respective APIs exposed by those libraries. diff --git a/plugins/node/instrumentation-react-native-navigation/src/utils/spanCreator.ts b/plugins/node/instrumentation-react-native-navigation/src/utils/spanCreator.ts index 46c7916feb..867dff506d 100644 --- a/plugins/node/instrumentation-react-native-navigation/src/utils/spanCreator.ts +++ b/plugins/node/instrumentation-react-native-navigation/src/utils/spanCreator.ts @@ -18,12 +18,13 @@ import { MutableRefObject } from 'react'; import { TracerRef } from './hooks/useTracerRef'; import { SpanRef } from './hooks/useSpanRef'; -import { Attributes, trace, context } from '@opentelemetry/api'; +import { Attributes } from '@opentelemetry/api'; const ATTRIBUTES = { - initialView: 'launch', - finalView: 'unmount', - appState: 'state.end', + initialView: 'view.launch', + finalView: 'view.unmount', + viewName: 'view.name', + appState: 'view.state.end', }; const spanStart = ( @@ -41,10 +42,10 @@ const spanStart = ( // Starting the span span.current = tracer.current.startSpan(currentRouteName); - trace.setSpan(context.active(), span.current); - // it should create the first span knowing there is not a previous view span.current.setAttribute(ATTRIBUTES.initialView, !!isLaunch); + // it should set the view name in case it's useful have this as attr + span.current.setAttribute(ATTRIBUTES.viewName, currentRouteName); if (customAttributes) { span.current.setAttributes(customAttributes); diff --git a/plugins/node/instrumentation-react-native-navigation/test/NativeNavigationTracker.test.tsx b/plugins/node/instrumentation-react-native-navigation/test/NativeNavigationTracker.test.tsx index c212c4d40b..09e4046fdc 100644 --- a/plugins/node/instrumentation-react-native-navigation/test/NativeNavigationTracker.test.tsx +++ b/plugins/node/instrumentation-react-native-navigation/test/NativeNavigationTracker.test.tsx @@ -25,9 +25,9 @@ import * as rnn from './helpers/react-native-navigation'; import { NavigationTrackerConfig } from '../src/types/navigation'; const AppWithProvider: FC<{ - shouldPassProvider?: boolean; + shouldPassProvider: boolean; config?: NavigationTrackerConfig; -}> = ({ shouldPassProvider = true, config }) => { +}> = ({ shouldPassProvider, config }) => { const { Navigation } = rnn; const provider = useProvider(); const ref = useRef(Navigation.events()); @@ -92,22 +92,23 @@ describe('NativeNavigationTracker.tsx', function () { const mockDidAppearListenerCall = mockDidAppearListener.getCall(0).args[0]; - mockDidAppearListenerCall({ componentName: 'initial-test-view' }); + mockDidAppearListenerCall({ componentName: 'homeView' }); sandbox.assert.calledWith(mockDidDisappearListener, sandbox.match.func); const mockDidDisappearListenerCall = mockDidDisappearListener.getCall(0).args[0]; - mockDidDisappearListenerCall({ componentName: 'initial-test-view' }); + mockDidDisappearListenerCall({ componentName: 'homeView' }); sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: 'initial-test-view', + name: 'homeView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: true, [ATTRIBUTES.appState]: 'active', + [ATTRIBUTES.viewName]: 'homeView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -115,17 +116,18 @@ describe('NativeNavigationTracker.tsx', function () { sandbox.match({ depth: sandbox.match.number }) ); - mockDidAppearListenerCall({ componentName: 'second-test-view' }); - mockDidDisappearListenerCall({ componentName: 'second-test-view' }); + mockDidAppearListenerCall({ componentName: 'detailsView' }); + mockDidDisappearListenerCall({ componentName: 'detailsView' }); sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: 'second-test-view', + name: 'detailsView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: false, [ATTRIBUTES.appState]: 'active', + [ATTRIBUTES.viewName]: 'detailsView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -137,7 +139,7 @@ describe('NativeNavigationTracker.tsx', function () { }); it('should render a component that implements passing a provider', function () { - const screen = render(); + const screen = render(); // should not call the global `getTracer` function since it should get the provider from props sandbox.assert.notCalled(mockGlobalTracer); @@ -145,22 +147,23 @@ describe('NativeNavigationTracker.tsx', function () { sandbox.assert.calledWith(mockDidAppearListener, sandbox.match.func); const mockDidAppearListenerCall = mockDidAppearListener.getCall(1).args[0]; - mockDidAppearListenerCall({ componentName: 'initial-test-view' }); + mockDidAppearListenerCall({ componentName: 'homeView' }); sandbox.assert.calledWith(mockDidDisappearListener, sandbox.match.func); const mockDidDisappearListenerCall = mockDidDisappearListener.getCall(1).args[0]; - mockDidDisappearListenerCall({ componentName: 'initial-test-view' }); + mockDidDisappearListenerCall({ componentName: 'homeView' }); sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: 'initial-test-view', + name: 'homeView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: true, [ATTRIBUTES.appState]: 'active', + [ATTRIBUTES.viewName]: 'homeView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -168,17 +171,18 @@ describe('NativeNavigationTracker.tsx', function () { sandbox.match({ depth: sandbox.match.number }) ); - mockDidAppearListenerCall({ componentName: 'second-test-view' }); - mockDidDisappearListenerCall({ componentName: 'second-test-view' }); + mockDidAppearListenerCall({ componentName: 'detailsView' }); + mockDidDisappearListenerCall({ componentName: 'detailsView' }); sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: 'second-test-view', + name: 'detailsView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: false, [ATTRIBUTES.appState]: 'active', + [ATTRIBUTES.viewName]: 'detailsView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -198,18 +202,21 @@ describe('NativeNavigationTracker.tsx', function () { const handleAppStateChange = mockAddEventListener.getCall(0).args[1]; - mockDidAppearListenerCall({ componentName: 'initial-view-after-launch' }); - + // app launches + mockDidAppearListenerCall({ componentName: 'homeView' }); + // app goes to background handleAppStateChange('background'); + // at this point it should grab the first span adding 'background' as app state sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: 'initial-view-after-launch', + name: 'homeView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: true, [ATTRIBUTES.appState]: 'background', + [ATTRIBUTES.viewName]: 'homeView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -217,22 +224,26 @@ describe('NativeNavigationTracker.tsx', function () { sandbox.match({ depth: sandbox.match.number }) ); + // back to foreground handleAppStateChange('active'); - + // user navigates to another view so the previous one disappears. it should end the previous span mockDidDisappearListenerCall({ - componentName: 'initial-view-after-launch', + componentName: 'homeView', }); - mockDidAppearListenerCall({ componentName: 'next-view' }); + // user gets the next view after navigate + mockDidAppearListenerCall({ componentName: 'detailsView' }); + // at this point a new span should be created with the same name but saying it's in 'active' state (foreground) sandbox.assert.calledWith( mockConsoleDir, sinon.match({ - name: 'initial-view-after-launch', + name: 'homeView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: false, [ATTRIBUTES.appState]: 'active', + [ATTRIBUTES.viewName]: 'homeView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -240,16 +251,19 @@ describe('NativeNavigationTracker.tsx', function () { sandbox.match({ depth: sandbox.match.number }) ); + // app goes to background handleAppStateChange('background'); + // and for that reason it should create a new span with the same name but in 'background' state sandbox.assert.calledWith( mockConsoleDir, sinon.match({ - name: 'next-view', + name: 'detailsView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: false, [ATTRIBUTES.appState]: 'background', + [ATTRIBUTES.viewName]: 'detailsView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -264,6 +278,7 @@ describe('NativeNavigationTracker.tsx', function () { it('should create spans with custom attributes', function () { const screen = render( = ({ shouldPassProvider = true, config }) => { +}> = ({ shouldPassProvider, config }) => { const { useNavigationContainerRef } = rnn; const ref = useNavigationContainerRef(); const provider = useProvider(); @@ -100,21 +100,22 @@ describe('NavigationTracker.tsx', function () { sandbox.assert.calledWith(mockAddListener, 'state', sandbox.match.func); const mockNavigationListenerCall = mockAddListener.getCall(0).args[1]; - mockGetCurrentRoute.returns({ name: '1-first-view-test' }); + mockGetCurrentRoute.returns({ name: 'homeView' }); mockNavigationListenerCall(); - mockGetCurrentRoute.returns({ name: '1-second-view-test' }); + mockGetCurrentRoute.returns({ name: 'detailsView' }); mockNavigationListenerCall(); // after render a view and then navigate to a different one the spanEnd should be called and it should register a complete span sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: '1-first-view-test', + name: 'homeView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: true, [ATTRIBUTES.appState]: 'active', + [ATTRIBUTES.viewName]: 'homeView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -122,21 +123,22 @@ describe('NavigationTracker.tsx', function () { sandbox.match({ depth: sandbox.match.number }) ); - mockGetCurrentRoute.returns({ name: '1-second-view-test' }); + mockGetCurrentRoute.returns({ name: 'detailsView' }); mockNavigationListenerCall(); - mockGetCurrentRoute.returns({ name: '1-third-view-test' }); + mockGetCurrentRoute.returns({ name: 'extraView' }); mockNavigationListenerCall(); // again after render a view and then navigate to a different one (the third) the spanEnd should be called and it should register a complete span sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: '1-second-view-test', + name: 'detailsView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: false, [ATTRIBUTES.appState]: 'active', + [ATTRIBUTES.viewName]: 'detailsView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -148,7 +150,7 @@ describe('NavigationTracker.tsx', function () { }); it('should render a component that implements passing a provider', function () { - const screen = render(); + const screen = render(); // should not call the global `getTracer` function since it should get the provider from props sandbox.assert.notCalled(mockGlobalTracer); @@ -156,21 +158,22 @@ describe('NavigationTracker.tsx', function () { sandbox.assert.calledWith(mockAddListener, 'state', sandbox.match.func); const mockNavigationListenerCall = mockAddListener.getCall(1).args[1]; - mockGetCurrentRoute.returns({ name: '2-first-view-test' }); + mockGetCurrentRoute.returns({ name: 'homeView' }); mockNavigationListenerCall(); - mockGetCurrentRoute.returns({ name: '2-second-view-test' }); + mockGetCurrentRoute.returns({ name: 'detailsView' }); mockNavigationListenerCall(); // after render a view and then navigate to a different one the spanEnd should be called and it should register a complete span sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: '2-first-view-test', + name: 'homeView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: true, [ATTRIBUTES.appState]: 'active', + [ATTRIBUTES.viewName]: 'homeView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -178,21 +181,22 @@ describe('NavigationTracker.tsx', function () { sandbox.match({ depth: sandbox.match.number }) ); - mockGetCurrentRoute.returns({ name: '2-second-view-test' }); + mockGetCurrentRoute.returns({ name: 'detailsView' }); mockNavigationListenerCall(); - mockGetCurrentRoute.returns({ name: '1-third-view-test' }); + mockGetCurrentRoute.returns({ name: 'extraView' }); mockNavigationListenerCall(); // again after render a view and then navigate to a different one (the third) the spanEnd should be called and it should register a complete span sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: '2-second-view-test', + name: 'detailsView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: false, [ATTRIBUTES.appState]: 'active', + [ATTRIBUTES.viewName]: 'detailsView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -211,7 +215,7 @@ describe('NavigationTracker.tsx', function () { const handleAppStateChange = mockAddEventListener.getCall(0).args[1]; // app launches, navigation listener is called - mockGetCurrentRoute.returns({ name: '3-initial-view-after-launch' }); + mockGetCurrentRoute.returns({ name: 'homeView' }); // - start the first span mockNavigationListenerCall(); @@ -222,11 +226,12 @@ describe('NavigationTracker.tsx', function () { sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: '3-initial-view-after-launch', + name: 'homeView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: true, [ATTRIBUTES.appState]: 'background', + [ATTRIBUTES.viewName]: 'homeView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -240,18 +245,19 @@ describe('NavigationTracker.tsx', function () { // - start the second span (same view) // app navigates to a different view - mockGetCurrentRoute.returns({ name: '3-next-view' }); + mockGetCurrentRoute.returns({ name: 'detailsView' }); mockNavigationListenerCall(); // - end the second span sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: '3-initial-view-after-launch', + name: 'homeView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: false, [ATTRIBUTES.appState]: 'active', + [ATTRIBUTES.viewName]: 'homeView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -266,11 +272,12 @@ describe('NavigationTracker.tsx', function () { sandbox.assert.calledWith( mockConsoleDir, sandbox.match({ - name: '3-next-view', + name: 'detailsView', traceId: sandbox.match.string, attributes: { [ATTRIBUTES.initialView]: false, [ATTRIBUTES.appState]: 'background', + [ATTRIBUTES.viewName]: 'detailsView', }, timestamp: sandbox.match.number, duration: sandbox.match.number, @@ -286,6 +293,7 @@ describe('NavigationTracker.tsx', function () { it('should create spans with custom attributes', function () { const screen = render(